momo's Blog.

Python logging 配置为JSON格式

字数统计: 458阅读时长: 2 min
2021/06/25 Share

前言

将日志json化输出

基本信息

模块format显示消息的内置格式

如果需要更改消息显示格式, 需要指定format

1
2
3
4
5
import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')

将输出

1
2
3
DEBUG:This message should appear on the console
INFO:So should this
WARNING:And this, too

可参考: LogRecord属性

配置JSON输出

安装 python-json-logger

配置JSON输出,我们需要安装第三方的包

1
pip install python-json-logger

Pypi
https://pypi.python.org/pypi/python-json-logger

创建配置文件

logging.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[loggers]
keys=root,jsonmodule

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=simpleFormatter,json

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_jsonmodule]
level=DEBUG
handlers=fileHandler
qualname=jsonmodule

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=handlers.TimedRotatingFileHandler
level=INFO
formatter=json
args=("./app.log", 'd', 1, 15, 'utf-8')

[formatter_json]
class=pythonjsonlogger.jsonlogger.JsonFormatter
format=%(asctime)s %(threadName)s %(thread)d %(levelname)s %(lineno)d %(module)s %(funcName)s %(message)s

[formatter_simpleFormatter]
format=%(asctime)s %(funcName)s %(filename)s [line: %(lineno)d] %(levelname)s:%(message)s

默认前台输出,以及后台写文件. 日志文件已天分割, 并且保留15天.

使用

1
2
3
4
5
6
import logging.config

logging.config.fileConfig('logging.conf')
logger = logging.getLogger('jsonmodule')

logger.error('dawdwad')

输出

1
2
3
4
5
前台: 
2021-06-25 16:54:32,185 <module> logger.py [line: 7] ERROR:dawdwad

日志:
{"asctime": "2021-06-25 16:54:32,185", "threadName": "MainThread", "thread": 18348, "levelname": "ERROR", "lineno": 7, "module": "logger", "funcName": "<module>", "message": "dawdwad"}

配置默认自定义字段

You can also use the add_fields method to add to or generally normalize the set of default set of fields, it is called for every log event. For example, to unify default fields with those provided by structlog you could do something like this:

1
2
3
4
5
6
7
8
9
10
11
class CustomJsonFormatter(jsonlogger.JsonFormatter):
def add_fields(self, log_record, record, message_dict):
super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict)
if not log_record.get('timestamp'):
# this doesn't use record.created, so it is slightly off
now = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ')
log_record['timestamp'] = now
if log_record.get('level'):
log_record['level'] = log_record['level'].upper()
else:
log_record['level'] = record.levelname

更改配置文件

1
2
3
[formatter_json]
class=log.formatter.CustomJsonFormatter
format=%(threadName)s %(thread)d %(lineno)d %(module)s %(funcName)s %(message)s

参考

CATALOG
  1. 1. 前言
  2. 2. 基本信息
    1. 2.1. 模块format显示消息的内置格式
  3. 3. 配置JSON输出
    1. 3.1. 安装 python-json-logger
    2. 3.2. 创建配置文件
      1. 3.2.1. logging.conf
      2. 3.2.2. 使用
  4. 4. 配置默认自定义字段
    1. 4.1. 更改配置文件
  5. 5. 参考