python 多进程 logging:ConcurrentLogHandler

python 多进程 logging:ConcurrentLogHandler

python的logging模块RotatingFileHandler仅仅是线程安全的,如果多进程多线程使用,推荐 ConcurrentLogHandler. 安装之:

# Using ConcurrentLogHandler:

# wget https://pypi.python.org/packages/fd/e5/0dc4f256bcc6484d454006b02f33263b20f762a433741b29d53875e0d763/ConcurrentLogHandler-0.9.1.tar.gz#md5=9609ecc4c269ac43f0837d89f12554c3
# cd ConcurrentLogHandler-0.9.1
# python2.7 setup.py install

Linux下建一个目录,下面的文件都放到这个目录中:

1) logging-config.ini

[loggers]
keys=root,simpleExample

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0

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

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

2) logging-config.yaml

version: 1

formatters:
    simple:
        format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'

handlers:
    console:
        class: logging.StreamHandler
        level: DEBUG
        formatter: simple
        stream: ext://sys.stdout

loggers:
    simpleExample:
        level: DEBUG
        handlers: [console]
        propagate: no

root:
    level: DEBUG
    handlers: [console]

3) testlogging.py

#!/usr/bin/python2.7
#-*- coding: UTF-8 -*-
#
# Using ConcurrentLogHandler:
#   wget https://pypi.python.org/packages/fd/e5/0dc4f256bcc6484d454006b02f33263b20f762a433741b29d53875e0d763/ConcurrentLogHandler-0.9.1.tar.gz#md5=9609ecc4c269ac43f0837d89f12554c3
#   cd ConcurrentLogHandler-0.9.1
#   python2.7 setup.py install
###########################################################
import logging, logging.config
import cloghandler

import yaml

###########################################################
# create logger
# 使用代码创建logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)

# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# add formatter to ch
ch.setFormatter(formatter)

# add ch to logger
logger.addHandler(ch)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

###########################################################
# basicConfig
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')

###########################################################
# using yaml config file
f = open("logging-config.yaml")
dictcfg = yaml.load(f)
f.close()

logging.config.dictConfig(dictcfg)

#logging.config.fileConfig("logging.config")
log = logging.getLogger("root")
log.info("==YAML== Here is a very exciting log message")

###########################################################
# using ini config file
logging.config.fileConfig("logging-config.ini")
log = logging.getLogger("simpleExample")
log.info("==INI== Here is a very exciting log message")

###########################################################
# using inline code config
logging.config.dictConfig({
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'verbose': {
            'format': "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
            'datefmt': "%Y-%m-%d %H:%M:%S",
        },
        'simple': {
            'format': '%(levelname)s %(message)s',
        },
    },
    'handlers': {
        'null': {
            'level': 'DEBUG',
            'class': 'logging.NullHandler',
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
        'file': {
            'level': 'DEBUG',
            'class': 'cloghandler.ConcurrentRotatingFileHandler',
            'maxBytes': 1024 * 1024 * 10,   # 当达到10MB时分割日志
            'backupCount': 10,              # 最多保留10份文件
            'delay': True,                  # If delay is true, file opening is deferred until the first call to emit
            'filename': 'sample-site.log',
            'formatter': 'verbose',
        },
        'file2': {
            'level': 'DEBUG',
            'class': 'cloghandler.ConcurrentRotatingFileHandler',
            'maxBytes': 1024 * 1024 * 10,   # 当达到10MB时分割日志
            'backupCount': 10,              # 最多保留10份文件
            'delay': True,                  # If delay is true, file opening is deferred until the first call to emit
            'filename': 'sample-site2.log',
            'formatter': 'verbose',
        },
    },
    'loggers': {
        '': {
            'handlers': ['file'],
            'level': 'INFO',
        },
        'root': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': 0,
        },
        'root2': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': 1,
        },
    },
})

logger = logging.getLogger("root")
logger.info("==== Here is a very exciting log message")

logger = logging.getLogger("root2")
logger.info("==== Here is a very exciting log message2")

至于喜欢使用哪种配置(ini, yaml还是代码)看自己喜欢了。我建议是yaml。

上一篇:PMP--可能会涉及到的计算题


下一篇:VS2010生成安装包