python输出json格式log,方便LogStash收集

系统 1457 0

为了配合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
              
            
          

更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论