为了配合LogStash日志收集服务,需要将线上服务的日志输出改为json格式。python日志标准库中并没有json格式的formatter,网上虽然已经有一些json相关的formatter,但不是很满意,就自己开发了一个并放到了github和pypi,目前仅支持 Python3 ,能够很方便的解决 自定义名映射属性 问题,也支持新增 自定义属性 。
欢迎到我的github点星星、提问题:
https://github.com/MyColorfulDays/jsonformatter
先睹为快
核心配置
LogRecord属性介绍可参考Python官网地址:
https://docs.python.org/3/library/logging.html#logrecord-attributes
# 自定义属性
# key代表LogRecord新增/替换的属性名称
# value必须`callable`类型,且不支持参数
CUSTOM_ATTRS
=
{
"session_id"
:
lambda
:
str
(
random
.
random
(
)
)
[
2
:
10
]
}
# 输出格式配置
# 支持json字符串,OrderedDict,dict(由于Python3.7之前dict是无序的,所以3.7之前的版本推荐使用OrderedDict或json字符串)
# key的值可任意
# value必须是LogRecord的属性或新增的自定义属性
# value也可以是“%(attribute)s/d/f”,它将被转为字符串格式输出,不再保持LogRecord属性的原类型
# value如果包含多个LogRecord的属性,必须为“%(attribute)s/d/f”格式拼接
# message若不属于`str, int, float, bool, type(None)`,会自动被转为字符串(防止输出日志时报错:xxx type is not JSON serializable.)
STRING_FORMAT
=
'''{
"@timestamp": "asctime",
"Module": "module",
"Lineno": "lineno",
"Str Lineno": "%(lineno)d",
"Level": "levelname",
"Session Id": "session_id",
"Multi Attrs": "%(module)s - %(lineno)d: %(funcName)s ",
"Message": "message"
}'''
输出结果
$ python test_jsonformatter.py
{
"@timestamp"
:
"2019-07-12 16:43:36,889"
,
"Module"
:
"test_jsonformatter"
,
"Lineno"
:
46,
"Str Lineno"
:
"46"
,
"Level"
:
"INFO"
,
"Session Id"
:
"51916201"
,
"Multi Attrs"
:
"test_jsonformatter - 46: test_logger "
,
"Message"
:
1
}
{
"@timestamp"
:
"2019-07-12 16:43:36,889"
,
"Module"
:
"test_jsonformatter"
,
"Lineno"
:
47,
"Str Lineno"
:
"47"
,
"Level"
:
"INFO"
,
"Session Id"
:
"10761601"
,
"Multi Attrs"
:
"test_jsonformatter - 47: test_logger "
,
"Message"
:
"{}"
}
{
"@timestamp"
:
"2019-07-12 16:43:36,889"
,
"Module"
:
"test_jsonformatter"
,
"Lineno"
:
48,
"Str Lineno"
:
"48"
,
"Level"
:
"INFO"
,
"Session Id"
:
"42298281"
,
"Multi Attrs"
:
"test_jsonformatter - 48: test_logger "
,
"Message"
:
"测试参数: arg1"
}
完整代码
test_jsonformatter.py
import
logging
import
random
from
jsonformatter
import
JsonFormatter
# 自定义属性
# key代表LogRecord新增/替换的属性名称
# value必须`callable`类型,且不支持参数
CUSTOM_ATTRS
=
{
"session_id"
:
lambda
:
str
(
random
.
random
(
)
)
[
2
:
10
]
}
# 输出格式配置
# 支持json字符串,OrderedDict,dict(由于Python3.7之前dict是无序的,所以3.7之前的版本推荐使用OrderedDict或json字符串)
# key的值可任意
# value必须是LogRecord的属性或新增的自定义属性
# value也可以是“%(attribute)s/d/f”,它将被转为字符串格式输出,不再保持LogRecord属性的原类型
# value如果包含多个LogRecord的属性,必须为“%(attribute)s/d/f”格式拼接
# message属性若不属于`str, int, float, bool, type(None)`,会自动被转为字符串(防止输出日志是报错:xxx type is not JSON serializable.)
STRING_FORMAT
=
'''{
"@timestamp": "asctime",
"Module": "module",
"Lineno": "lineno",
"Str Lineno": "%(lineno)d",
"Level": "levelname",
"Session Id": "session_id",
"Multi Attrs": "%(module)s - %(lineno)d: %(funcName)s ",
"Message": "message"
}'''
def
config_logger
(
)
:
logger
=
logging
.
getLogger
(
)
logger
.
setLevel
(
logging
.
INFO
)
# JsonFormatter支持`json.dumps`的所有可选参数
formatter
=
JsonFormatter
(
STRING_FORMAT
,
record_custom_attrs
=
CUSTOM_ATTRS
,
indent
=
4
,
ensure_ascii
=
False
)
sh
=
logging
.
StreamHandler
(
)
sh
.
setFormatter
(
formatter
)
sh
.
setLevel
(
logging
.
INFO
)
logger
.
addHandler
(
sh
)
def
test_logger
(
)
:
logger
=
logging
.
getLogger
(
)
logger
.
info
(
1
)
logger
.
info
(
{
}
)
logger
.
info
(
"测试参数: %s"
,
'arg1'
)
if
__name__
==
'__main__'
:
config_logger
(
)
test_logger
(
)
日志的配置也支持通过配置文件方式设置,可以到我的github查看。
安装
pip安装:
$ pip
install
jsonformatter
克隆github源码手工安装:
$
git
clone https://github.com/MyColorfulDays/jsonformatter.git
$
cd
jsonformatter
$ python setup.py
install