瑞瑞哥的博客

配置oslo_log的日志格式

配置oslo_log的日志格式

最近写了个小程序,给自己弄天气预报。由于要用到日志的调用链,就打算用oslo_log。结果默认配置下打开日志一看,日志大概是这样:

1
2
3
4
5
6
7
2017-11-18 02:09:34.284 29063 DEBUG myifttt.common.log.log [-] test execute_routine /root/code/test/myifttt/plugins/weather.py:107
2017-11-18 02:17:25.812 29125 DEBUG myifttt.common.log.log [-] test execute_routine /root/code/test/myifttt/plugins/weather.py:107
2017-11-18 02:18:08.302 29158 DEBUG myifttt.common.log.log [-] test execute_routine /root/code/test/myifttt/plugins/weather.py:107
2017-11-18 02:18:52.311 29194 DEBUG myifttt.common.log.log [-] test execute_routine /root/code/test/myifttt/plugins/weather.py:107
2017-11-18 02:34:11.626 29575 INFO /root/code/test/myifttt/plugins [-] processing task [id: 1]
2017-11-18 02:34:11.629 29575 INFO /root/code/test/myifttt/plugins [-] task [id: 1, user: 瑞瑞] should not run
2017-11-18 02:45:44.752 29634 INFO /root/code/test/myifttt/plugins [-] processing task [id: 1]

我觉得默认的日志,有以下问题:

  • 没有协程ID:Python中协程很常见,尤其是我这种定时任务的框架。没有TID特别难以定位问题
  • DEBUG日志正文不在最后:上文中的test才是日志正文,想不到把? 是不是特别别扭?我还是喜欢正文在最后的样子
  • INFO日志不打印代码行号:这简直不能忍
  • 反正怎么看怎么别扭

于是给出自己的设置项:

1
2
3
4
5
6
debug = True
log_file = myifttt.log
log_dir = /var/log/myifttt/
logging_context_format_string = %(asctime)s.%(msecs)03d [PID: %(process)d] %(processName)s [TID: %(thread)d] %(threadName)s %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(funcName)s %(pathname)s:%(lineno)d %(message)s
logging_default_format_string = %(asctime)s.%(msecs)03d [PID: %(process)d] %(processName)s [TID: %(thread)d] %(threadName)s %(levelname)s %(name)s [-] %(funcName)s %(pathname)s:%(lineno)d %(message)s
logging_debug_format_suffix = %(instance)s

其中:

  • logging_context_format_string这个是带上request-id时候,日志的格式
  • logging_default_format_string这个是普通日志的格式
  • logging_debug_format_suffix 这个是DEBUG日志时候,在一行后面额外增加的内容。这里要重点说一下,我什么时候都不想让一行的最后加点什么,换句话说,一行的末端,我只想要日志正文。所以这个字段我填写了一个%(instance)s,这个值是openstack相关虚拟机的ID,所以说肯定是空,这样就达到了DEBUG志末端也是正文的效果了。

另外,贴上oslo_log如何跟oslo_config配套使用:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import logging as ori_logging

from oslo_config import cfg
from oslo_log import log as logging

LOG = logging.getLogger(__name__)
CONF = cfg.ConfigOpts()
DOMAIN = "demo"

# 注册扩展配置项
extend_opts = [
cfg.BoolOpt('enable_console_log',
help='open it to print to screen')
]

# extend group
extend_group = cfg.OptGroup(
name='EXTEND',
title='EXT options'
)

CONF.register_group(extend_group)
CONF.register_opts(extend_opts, extend_group)


logging.register_options(CONF)
CONF(default_config_files=[
"/root/code/test/myifttt/conf/common/log/log.conf", ])
logging.setup(CONF, DOMAIN)


# 初始化其他功能
console = None
if CONF.EXTEND.enable_console_log:
console = ori_logging.StreamHandler()
console.setLevel(ori_logging.DEBUG)
formatter = ori_logging.Formatter(
'%(asctime)s %(filename)s [line:%(lineno)d] [%(funcName)s] %(levelname)s %(message)s')
console.setFormatter(formatter)
LOG.handlers.append(console)


# 根据扩展配置项应用自定义功能
def getLogger(name):
"""[summary]

[description]

Arguments:
name {[type]} -- [description]

Returns:
[type] -- [description]
"""
named_logger = logging.getLogger(name)
if console:
named_logger.handlers.append(console)
return named_logger