gpt4 book ai didi

logging - 扭曲。如何为每个请求在日志中写入唯一的前缀

转载 作者:行者123 更新时间:2023-12-02 19:46:20 28 4
gpt4 key购买 nike

我扭曲了服务器。它与插件一起运行。我想根据请求为每个条目编写唯一的前缀。

这意味着当user1发出请求时,它将生成一个唯一的字符串,该字符串将以日志记录为前缀(仅用于此请求)。当user2发出请求时,它将是日志记录的另一个唯一前缀。

我认为应该是日志观察程序logger,但是如何在用户请求之间对记录进行分组?

最佳答案

这个问题有几个部分。

首先,简单的部分-如何为日志事件自定义前缀?当然,有几种方法可以解决此问题。您可以做非常非常简单的事情:

from twisted.python.log import msg

def myLog(message):
msg("my prefix" + message)


也就是说,只需在日志消息上加上所需的前缀即可。不过,这可能并不是您真正想要的,因为它会粉碎您的日志消息并将前缀文本与日志消息混合在一起,而这种方式很难逆转(请注意,某些已记录的消息可能来自其他系统,并且没有任何前缀-但您怎么知道?)。

因此,您可以在日志事件中使用另一个键,而不是使用前缀:

from twisted.python.log import msg

def myLog(message):
msg(message, system="my prefix")


这将导致发出的日志事件看起来像(不太准确,不够接近),类似于:

{"message": message, "system": "my prefix"}


而且“系统”键恰好是一个特殊的键。 Twisted中的默认文件日志观察器可以识别它,并且其内容最终会写到该文件中的日志消息中:

2013-07-23 06:25:35-0400 [my prefix] message


但是,您可能不希望为基于用户的信息选择“系统”键。毕竟,系统可能与HTTP服务器有关。用户不是系统。

您可以通过 msg传递任何其他关键字参数:

from twisted.python.log import msg

def myLog(message):
msg(message, userIdentifier="alice")


userIdentifier将被Twisted附带的文件日志观察者忽略,但是您可以编写自己的观察者来注意它。例如:

from twisted.python.log import FileLogObserver, textFromEventDict, addObserver

class MyObserver(FileLogObserver):
def emit(self, event):
text = textFromEventDict(event)
if text and event.get("userIdentifier"):
adjusted = event.copy()
adjusted["message"] = "(%s) %s" % (event["userIdentifier"], text)
FileLogObserver.emit(self, adjusted)

addObserver(MyObserver(...).emit)


这使您可以使观察者注意到您的特殊日志事件,并在将其发送到常规文件写入逻辑之前修改其文本。我刚刚在这里做了一些简单的文本格式设置,但是您可以做得更好,例如将每个用户的事件写到他们自己的专用日志文件中,或者使用更易于解析的结构化日志格式。

我希望到目前为止,这一切都是有用的,但实际上并不能帮助您在特定的日志事件中正确获取正确的用户标识符。到目前为止,每个用户都是“驴友”。

首先,让我们看看如何使用户多样化。一种方法是将 userIdentifier设置为参数:

from twisted.python.log import msg

def myLog(message, userIdentifier):
msg(message, userIdentifier=userIdentifier)


当然, myLog现在看起来有点傻。您可以致电 msg。也许您想要比这更自动的东西。您可以将用户标识符包装在可调用对象中,这样就不必继续传递它:

from functools import partial

from twisted.python.log import msg

aliceLog = partial(msg, userIdentifier="alice")


现在,您只需执行 aliceLog("login")即可记录爱丽丝的事件。您可能不想在顶层定义此名称,因为您尚不知道用户名,并且可能会有多个用户。幸运的是,您可以随时轻松地制作这些内容。

让我们暂时将其放在一边,考虑如何识别用户。

有很多方法,所以我只是假设 request.getUser()是合适的。用您实际上想使用的任何其他机制替换它。

现在,您需要跟踪此信息。一种简单的方法是将其作为参数传递给想要记录与用户相关的事件的任何代码。我希望这实际上不是负担,因为任何想要记录与用户相关的事件的代码可能都已经需要知道它为谁服务。

这进入了Twisted Web的一个稍微毛茸茸的区域。遍历系统(即getChild)非常灵活,根据您使用它的方式,将信息传递给最终使用者的方式可能有很大的不同。

一种方法是使用透明的IResource包装器。这里的想法是,您在层次结构中插入一个不占用任何段的IResource,仅检查请求并创建一些有用的状态,例如用户标识符。例如,

from twisted.web.resource import IResource
from twisted.python.components import proxyForInterface

class GiveChildrenUserInfo(proxyForInterface(IResource)):
def getChild(self, request, segment):
child = self.original.getChild(request, segment)
child.setUser(request.getUser())
return GiveChildrenUserInfo(child)

rootResource = GiveChildrenUserInfo(actualRootResource)
...


请注意两件事。首先,我发明了一个 setUser方法,您所有的资源现在都必须实现。用户从请求中获取资源后,将在每个资源上调用它。现在,这些资源可以使用该用户信息-例如,调用 msg(message, userIdentifier=user)或使用 partial定义这样的日志帮助程序,如上所示。

我仍然没有在这里涉及到很多与日志记录有关的基础知识,但是我希望这足以使您入门并演示一些可能的方向。

关于logging - 扭曲。如何为每个请求在日志中写入唯一的前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17785273/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com