我正在尝试设置 structlog 并设置日志级别。我的代码如下所示:
import structlog
import logging
filepath=open("out.log",'a')
logging.basicConfig(
level=logging.INFO
)
structlog.configure(
processors=[structlog.stdlib.filter_by_level],
wrapper_class=structlog.BoundLogger,
context_class=dict,
logger_factory=structlog.PrintLoggerFactory(filepath),
)
logger = structlog.getLogger()
logger.info('test')
Run Code Online (Sandbox Code Playgroud)
这失败了:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.8/site-packages/structlog/_base.py", line 189, in _proxy_to_logger
args, kw = self._process_event(method_name, event, event_kw)
File "/usr/local/lib/python3.8/site-packages/structlog/_base.py", line 149, in _process_event
event_dict = proc(self._logger, method_name, event_dict)
File "/usr/local/lib/python3.8/site-packages/structlog/stdlib.py", line 381, in filter_by_level
if logger.isEnabledFor(_NAME_TO_LEVEL[name]):
AttributeError: 'PrintLogger' object has no attribute 'isEnabledFor'
Run Code Online (Sandbox Code Playgroud)
好吧,当然。我不应该将 PrintLogger 与 stdlib 处理器一起使用。但我想按日志级别进行过滤(因为这就是日志记录通常的工作方式,嗯?)那么我该怎么做呢?我想我需要使用其他记录器工厂,但是哪一个呢?当然 structlog.stdlib.LoggerFactory 可以工作,但它不会重定向到文件。
所以我说:好吧,我将创建自己的过滤器:
def …Run Code Online (Sandbox Code Playgroud) 使用 python 标准日志模块,可以使用以下方法添加原始日志调用的行号: %(lineno)s.
这如何使用 structlog 来完成?
我正在使用 FastAPI 和 Structlog,想要测试日志格式并将其从纯文本/字符串转换为 JSON 格式,以便日志聚合器平台具有更好的可读性和处理能力。面临某些日志输出以 JSON 形式提供但以纯字符串形式存在的情况。
电流输出
INFO: 127.0.0.1:62154 - "GET /api/preface HTTP/1.1" 200 OK
INFO: 127.0.0.1:62154 - "GET /loader.json HTTP/1.1" 200 OK
INFO: 127.0.0.1:62155 - "GET /hello_world HTTP/1.1" 200 OK
{"key":"test_key","message":"Push to NFS Success","event":"Testing Fast API..","logger":"test_my_api","filename":"main.py","func_name":"Hello_World","process":23760,"module":"docker","thread":23140,"pathname":"D:\\my_work\\fast_api\\main.py","process_name":"SpawnProcess-1","level":"info","time-iso":"2023-06-30T15:25:03.113400Z"}
Run Code Online (Sandbox Code Playgroud)
预期输出:
{
"level": "INFO",
"IP": "127.0 .0 .1: 62154",
"method": "GET",
"endpoint": "/loader.json",
"protocol": "HTTP / 1.1",
"status_code": 200,
"status": "OK"
}
{
"level": "INFO",
"IP": "127.0 .0 .1: 62155",
"method": "GET",
"endpoint": "/api/preface",
"protocol": "HTTP / 1.1",
"status_code": 200,
"status": …Run Code Online (Sandbox Code Playgroud) 我觉得这应该非常简单,但我不知道如何在使用 structlog 时指定日志文件的路径。该文档指出您可以将传统日志记录与 structlog 一起使用,因此我尝试了以下方法:
logger = structlog.getLogger(__name__)
logging.basicConfig(filename=logfile_path, level=logging.ERROR)
logger.error("TEST")
Run Code Online (Sandbox Code Playgroud)
日志文件已创建,但当然“TEST”不会出现在其中。只是一片空白。
Structlog 似乎在创建日志消息时使用__repr__,这导致date对象datetime看起来'datetime.datetime(2018, 9, 20, 10, 1, 52, 414750)'更'2018-09-20 10:01:52.414750'可取。
我本以为会有一个现成的处理器来处理这个问题,但我找不到。
我正在尝试将日志的额外字段添加为键值,同时继续使用标准日志记录库和 structlog ProcessorFormatter。
这是一个例子:
如果我们使用 JsonFormatter,额外的字段将作为键值添加到日志中。
使用 python-json-logger:
formatter = jsonlogger.JsonFormatter()
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logging.basicConfig(
level=logging.DEBUG,
handlers=[handler]
)
logger = logging.getLogger('testnameloger1')
logger.debug('testmsg2', extra={'extra2': 2})
Run Code Online (Sandbox Code Playgroud)
安慰:
{"message": "testmsg2", "extra2": 2}
Run Code Online (Sandbox Code Playgroud)
在日志记录中使用基于结构日志的格式化程序进行渲染:
shared_processors = [
structlog.stdlib.add_logger_name,
structlog.stdlib.add_log_level,
structlog.processors.TimeStamper(fmt='iso'),
]
formatter = structlog.stdlib.ProcessorFormatter(
processor=structlog.processors.JSONRenderer(),
foreign_pre_chain=shared_processors,
)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logging.basicConfig(
level=logging.DEBUG,
handlers=[handler]
)
logger = logging.getLogger('testnameloger1')
logger.debug('testmsg1', extra={'extra1': 1})
Run Code Online (Sandbox Code Playgroud)
安慰:
{"event": "testmsg1", "logger": "testnameloger1", "level": "debug", "timestamp": "2020-06-16T13:33:50.881221Z"}
Run Code Online (Sandbox Code Playgroud)
如何在日志输出中添加额外字段?
我想要的日志格式如下:
{"event": "testmsg1", "extra1": 1, "logger": "testnameloger1", "level": "debug", "timestamp": "2020-06-16T13:33:50.881221Z"}
Run Code Online (Sandbox Code Playgroud)
感谢您的见解
我已经为我的 Django 项目安装了django-structlog 1.4.1。我已按照该链接中描述的所有步骤进行操作。
在我的settings.py文件中:
import structlog
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django_structlog.middlewares.RequestMiddleware',
]
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"json_formatter": {
"()": structlog.stdlib.ProcessorFormatter,
"processor": structlog.processors.JSONRenderer(),
},
"plain_console": {
"()": structlog.stdlib.ProcessorFormatter,
"processor": structlog.dev.ConsoleRenderer(),
},
"key_value": {
"()": structlog.stdlib.ProcessorFormatter,
"processor": structlog.processors.KeyValueRenderer(key_order=['timestamp', 'level', 'event', 'logger']),
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "plain_console",
},
"json_file": {
"class": "logging.handlers.WatchedFileHandler",
"filename": "log/json.log",
"formatter": "json_formatter",
},
"flat_line_file": {
"class": "logging.handlers.WatchedFileHandler",
"filename": …Run Code Online (Sandbox Code Playgroud) 我使用 structlog 进行日志记录,并希望以 json 格式打印异常/堆栈跟踪。
目前它没有格式化并且是字符串格式,可读性不是很好
{
"message": "Error info with an exc",
"timestamp": "2022-03-31T13:32:33.928188+00:00",
"logger": "__main__",
"level": "error",
"exception": "Traceback (most recent call last):\n File \"../../main.py\", line 21, in <module>\n assert 'foo' == 'bar'\nAssertionError"
}
Run Code Online (Sandbox Code Playgroud)
想要 json 格式的异常,例如
{
"message": "Error info with an exc",
"timestamp": "2022-03-31T13:32:33.928188+00:00",
"logger": "__main__",
"level": "error",
"exception": {
"File": "../.../main.py",
"line": 21,
"function": "<module>",
"errorStatement": "assert 'foo' == 'bar'",
"errorType":"AssertionError",
}
}
Run Code Online (Sandbox Code Playgroud)
这只是一个小例子,我也使用回溯库并传递在大字符串块中打印的 stackTrace
我们是否有任何可用的库可以进行 stacktrace json 格式化。或者我们必须编写一个自定义函数吗?
我阅读了structlog的文档:Configuration
目标是将每个文件的日志记录样板减少到:
Run Code Online (Sandbox Code Playgroud)from structlog import get_logger logger = get_logger()
有没有办法将此减少到一个导入线(没有;)?