Python中如何处理日志问题?

一个应用启动多个服务,如何使多个服务的日志输出到一个日志文件中?怎样配置,使用 logging 模块能实现吗?


Python中如何处理日志问题?
8 回复

Python日志处理的核心是使用内置的 logging 模块。

别自己造轮子,logging 模块提供了完整的解决方案。下面是一个直接能用的基础配置:

import logging

# 1. 创建logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)  # 设置最低记录级别

# 2. 创建控制台处理器
ch = logging.StreamHandler()
ch.setLevel(logging.WARNING)  # 控制台只显示WARNING及以上

# 3. 创建文件处理器
fh = logging.FileHandler('app.log', encoding='utf-8')
fh.setLevel(logging.DEBUG)  # 文件记录所有DEBUG及以上

# 4. 设置格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)

# 5. 添加处理器
logger.addHandler(ch)
logger.addHandler(fh)

# 使用示例
logger.debug('调试信息')      # 只写入文件
logger.info('普通信息')       # 只写入文件  
logger.warning('警告信息')    # 同时输出到控制台和文件
logger.error('错误信息')      # 同时输出到控制台和文件

关键点:

  • getLogger(__name__) 用模块名创建logger,便于追踪
  • 分级别控制:DEBUG < INFO < WARNING < ERROR < CRITICAL
  • 处理器决定输出到哪里,每个可以单独设置级别
  • 格式器统一日志样式

进阶可以直接用字典配置:

import logging.config

config = {
    'version': 1,
    'handlers': {
        'file': {
            'class': 'logging.FileHandler',
            'filename': 'app.log',
            'formatter': 'detailed'
        }
    },
    'formatters': {
        'detailed': {
            'format': '%(asctime)s %(levelname)s: %(message)s'
        }
    },
    'root': {
        'handlers': ['file'],
        'level': 'INFO'
    }
}

logging.config.dictConfig(config)

总结:用 logging 模块,按需配置不同级别的处理器。

用外部日志吧,比如 syslog

楼上说的都对,logging 模块的还提供了一个例子: https://docs.python.org/2/howto/logging-cookbook.html#network-logging 很清楚。
我们这边类似的情况,多个服务写日志,各写各的文件,然后用 logstash 收集到一起集中存储处理,也很方便的

可以 追加写的方式写入指定文件即可

追加写是原子性的

限 Linux 下
openstack 对多进程写日志没任何特殊处理

为此我专门查过 你可以参考

http://www.lolizeppelin.com/2017/08/05/linux-append-write/

我 blog 手机浏览器显示有问题

python 的 logging 模块是线程安全的,写是追加模式可以当成是原子操作在多进程模式下也没问题。
有问题的是在多进程切割日志,多进程下会有问题。
参考下下面的,扩展了 logging 使 logging 进程安全。
https://pypi.python.org/pypi/ConcurrentLogHandler/0.9.1

我是用 celery 做的,专门起一个 log 的 celery 进程来写日志

回到顶部