qpython3使用手册 pdf_日志操作手册

import logging

import logging.config

import logging.handlers

from multiprocessing import Process, Queue, Event, current_process

import os

import random

import time

class MyHandler:

"""

A simple handler for logging events. It runs in the listener process and

dispatches events to loggers based on the name in the received record,

which then get dispatched, by the logging system, to the handlers

configured for those loggers.

"""

def handle(self, record):

logger = logging.getLogger(record.name)

# The process name is transformed just to show that it's the listener

# doing the logging to files and console

record.processName = '%s(for%s)' % (current_process().name, record.processName)

logger.handle(record)

def listener_process(q, stop_event, config):

"""

This could be done in the main process, but is just done in a separate

process for illustrative purposes.

This initialises logging according to the specified configuration,

starts the listener and waits for the main process to signal completion

via the event. The listener is then stopped, and the process exits.

"""

logging.config.dictConfig(config)

listener = logging.handlers.QueueListener(q, MyHandler())

listener.start()

if os.name == 'posix':

# On POSIX, the setup logger will have been configured in the

# parent process, but should have been disabled following the

# dictConfig call.

# On Windows, since fork isn't used, the setup logger won't

# exist in the child, so it would be created and the message

# would appear - hence the "if posix" clause.

logger = logging.getLogger('setup')

logger.critical('Should not appear, because of disabled logger ...')

stop_event.wait()

listener.stop()

def worker_process(config):

"""

A number of these are spawned for the purpose of illustration. In

practice, they could be a heterogeneous bunch of processes rather than

ones which are identical to each other.

This initialises logging according to the specified configuration,

and logs a hundred messages with random levels to randomly selected

loggers.

A small sleep is added to allow other processes a chance to run. This

is not strictly needed, but it mixes the output from the different

processes a bit more than if it's left out.

"""

logging.config.dictConfig(config)

levels = [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR,

logging.CRITICAL]

loggers = ['foo', 'foo.bar', 'foo.bar.baz',

'spam', 'spam.ham', 'spam.ham.eggs']

if os.name == 'posix':

# On POSIX, the setup logger will have been configured in the

# parent process, but should have been disabled following the

# dictConfig call.

# On Windows, since fork isn't used, the setup logger won't

# exist in the child, so it would be created and the message

# would appear - hence the "if posix" clause.

logger = logging.getLogger('setup')

logger.critical('Should not appear, because of disabled logger ...')

for i in range(100):

lvl = random.choice(levels)

logger = logging.getLogger(random.choice(loggers))

logger.log(lvl, 'Message no.%d', i)

time.sleep(0.01)

def main():

q = Queue()

# The main process gets a simple configuration which prints to the console.

config_initial = {

'version': 1,

'formatters': {

'detailed': {

'class': 'logging.Formatter',

'format': '%(asctime)s%(name)-15s%(levelname)-8s%(processName)-10s%(message)s'

}

},

'handlers': {

'console': {

'class': 'logging.StreamHandler',

'level': 'INFO',

},

},

'root': {

'level': 'DEBUG',

'handlers': ['console']

},

}

# The worker process configuration is just a QueueHandler attached to the

# root logger, which allows all messages to be sent to the queue.

# We disable existing loggers to disable the "setup" logger used in the

# parent process. This is needed on POSIX because the logger will

# be there in the child following a fork().

config_worker = {

'version': 1,

'disable_existing_loggers': True,

'handlers': {

'queue': {

'class': 'logging.handlers.QueueHandler',

'queue': q,

},

},

'root': {

'level': 'DEBUG',

'handlers': ['queue']

},

}

# The listener process configuration shows that the full flexibility of

# logging configuration is available to dispatch events to handlers however

# you want.

# We disable existing loggers to disable the "setup" logger used in the

# parent process. This is needed on POSIX because the logger will

# be there in the child following a fork().

config_listener = {

'version': 1,

'disable_existing_loggers': True,

'formatters': {

'detailed': {

'class': 'logging.Formatter',

'format': '%(asctime)s%(name)-15s%(levelname)-8s%(processName)-10s%(message)s'

},

'simple': {

'class': 'logging.Formatter',

'format': '%(name)-15s%(levelname)-8s%(processName)-10s%(message)s'

}

},

'handlers': {

'console': {

'class': 'logging.StreamHandler',

'level': 'INFO',

'formatter': 'simple',

},

'file': {

'class': 'logging.FileHandler',

'filename': 'mplog.log',

'mode': 'w',

'formatter': 'detailed',

},

'foofile': {

'class': 'logging.FileHandler',

'filename': 'mplog-foo.log',

'mode': 'w',

'formatter': 'detailed',

},

'errors': {

'class': 'logging.FileHandler',

'filename': 'mplog-errors.log',

'mode': 'w',

'level': 'ERROR',

'formatter': 'detailed',

},

},

'loggers': {

'foo': {

'handlers': ['foofile']

}

},

'root': {

'level': 'DEBUG',

'handlers': ['console', 'file', 'errors']

},

}

# Log some initial events, just to show that logging in the parent works

# normally.

logging.config.dictConfig(config_initial)

logger = logging.getLogger('setup')

logger.info('About to create workers ...')

workers = []

for i in range(5):

wp = Process(target=worker_process, name='worker%d' % (i + 1),

args=(config_worker,))

workers.append(wp)

wp.start()

logger.info('Started worker:%s', wp.name)

logger.info('About to create listener ...')

stop_event = Event()

lp = Process(target=listener_process, name='listener',

args=(q, stop_event, config_listener))

lp.start()

logger.info('Started listener')

# We now hang around for the workers to finish their work.

for wp in workers:

wp.join()

# Workers all done, listening can now stop.

# Logging in the parent still works normally.

logger.info('Telling listener to stop ...')

stop_event.set()

lp.join()

logger.info('All done.')

if __name__ == '__main__':

main()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值