python logging 模块使用例子

支持文件、屏幕打印、电子邮件、TCP、UDP、syslog本地、syslog远程、windows事件、http server方式记录日志:

#!/usr/bin/python
import os
import sys
import logging
import logging.config
from logging import handlers

DEBUG = True

SYSLOG_HANDLER_HOST = 'localhost'

LOG_PATH = '../server.log'

MAIL_HANDLER_HOST = 'smtp.qq.com'
MAIL_HANDLER_FROMADDR = 'user@qq.com'
MAIL_HANDLER_TOADDRS = ['user1@qq.com','user2@gmail.com']
MAIL_HANDLER_SUBJECT = 'Logging from python app'
MAIL_HANDLER_CREDENTIALS = ('user@qq.com','password')

TCPSOCKET_HANDLER_HOST = 'localhost'
TCPSOCKET_HANDLER_PORT = 9022

UDPSOCKET_HANDLER_HOST = 'localhost'
UDPSOCKET_HANDLER_PORT = 9021

NTEVENT_HANDLER_APPNAME = 'Python Application'
NTEVENT_HANDLER_LOGTYPE = 'Application'

HTTP_HANDLER_HOST = 'localhost:8000'
HTTP_HANDLER_URL = '/logging'
HTTP_HANDLER_METHOD = 'GET'


LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
       'detail': {
            'format': '%(name)s %(levelname)s %(asctime)s %(module)s %(process)d %(thread)d [%(pathname)s:%(lineno)d] %(message)s'
        },
        'verbose': {
            'format': '%(name)s %(levelname)s %(asctime)s [%(pathname)s:%(lineno)d] %(message)s'
        },
        'simple': {
            'format': '%(name)s %(levelname)s %(message)s'
        },
    },
    'handlers': {
       'console':{
            'level':'NOTSET',
            'class':'logging.StreamHandler',
            'stream':sys.stderr,
            'formatter': 'verbose' #'simple'
        },
        'file':{
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(os.getcwd(), LOG_PATH),
            'formatter': 'verbose',
            'maxBytes': 1024*1024*20,  # 20MB
            'backupCount': 5,
        },
        'syslog.remote':{
            'level':'DEBUG',
            'class':'logging.handlers.SysLogHandler',
            'address':(SYSLOG_HANDLER_HOST,handlers.SYSLOG_UDP_PORT), # log to syslog or rsyslog server
            'formatter': 'verbose',
        },
        'mail.handler':{
            'level':'DEBUG',
            'class':'logging.handlers.SMTPHandler', # log to mailbox
            'mailhost':MAIL_HANDLER_HOST,
            'fromaddr':MAIL_HANDLER_FROMADDR,
            'toaddrs':MAIL_HANDLER_TOADDRS,
            'subject':MAIL_HANDLER_SUBJECT,
            'credentials':MAIL_HANDLER_CREDENTIALS,
            'formatter': 'detail',
        },
        'socket.tcp.handler':{
            'level':'DEBUG',
            'class':'logging.handlers.SocketHandler', # log to tcp socket
            'host':TCPSOCKET_HANDLER_HOST,
            'port':TCPSOCKET_HANDLER_PORT,
            'formatter': 'verbose',
        },
        'socket.udp.handler':{
            'level':'DEBUG',
            'class':'logging.handlers.DatagramHandler', # log to udp socket
            'host':UDPSOCKET_HANDLER_HOST,
            'port':UDPSOCKET_HANDLER_PORT,
            'formatter': 'verbose',
        },
        'http.handler':{
            'level':'DEBUG',
            'class':'logging.handlers.HTTPHandler', # log to http server
            'host':HTTP_HANDLER_HOST,
            'url':HTTP_HANDLER_URL,
            'method':HTTP_HANDLER_METHOD,
            'formatter': 'verbose',
        }
    },
    'loggers': {
        'CommonLogger': {
            'handlers': ['console', 'file'] if DEBUG else ['file'],
            'level': 'DEBUG' if DEBUG else 'DEBUG', #'INFO'
            'propagate': False,
            # very important in multithread environment, means disable propagation from current logger to the *root* logger.
        },
    }
}

syslog_local = {
            'level':'DEBUG',
            'class':'logging.handlers.SysLogHandler',
            'address':'/dev/log', # log to local syslog file
            'formatter': 'verbose',
        }

ntevent_handler = {
            'level':'DEBUG',
            'class':'logging.handlers.NTEventLogHandler', # log to windows event log
            'appname':NTEVENT_HANDLER_APPNAME,
            'logtype':NTEVENT_HANDLER_LOGTYPE,
            'formatter': 'verbose',
        }

common_logger = {
            'handlers': ['console', 'file'] if DEBUG else ['file'],
            'level': 'DEBUG' if DEBUG else 'DEBUG', #'INFO'
            'propagate': False,
            # very important in multithread environment, means disable propagation from current logger to the *root* logger.
        }


if sys.platform == 'linux2':
    LOGGING['handlers']['syslog.local'] = syslog_local
if sys.platform == 'win32':
    LOGGING['handlers']['ntevent.handler'] = ntevent_handler

def getlogger(logger_name=None):
    if isinstance(logger_name,str) or isinstance(logger_name,unicode):
        LOGGING['loggers'][logger_name] = common_logger
        logging.config.dictConfig(LOGGING)
        logger = logging.getLogger(logger_name)
    else:
        logging.config.dictConfig(LOGGING)
        logger = logging.getLogger("CommonLogger")
        
    return logger

另附上一个接收tcp方式日志的服务器:

import cPickle
import logging
import logging.handlers
import SocketServer
import struct


class LogRecordStreamHandler(SocketServer.StreamRequestHandler):
    """Handler for a streaming logging request.

    This basically logs the record using whatever logging policy is
    configured locally.
    """

    def handle(self):
        """
        Handle multiple requests - each expected to be a 4-byte length,
        followed by the LogRecord in pickle format. Logs the record
        according to whatever policy is configured locally.
        """
        while 1:
            chunk = self.connection.recv(4)
            if len(chunk) < 4:
                break
            slen = struct.unpack(">L", chunk)[0]
            chunk = self.connection.recv(slen)
            while len(chunk) < slen:
                chunk = chunk + self.connection.recv(slen - len(chunk))
            obj = self.unPickle(chunk)
            record = logging.makeLogRecord(obj)
            self.handleLogRecord(record)

    def unPickle(self, data):
        return cPickle.loads(data)

    def handleLogRecord(self, record):
        # if a name is specified, we use the named logger rather than the one
        # implied by the record.
        if self.server.logname is not None:
            name = self.server.logname
        else:
            name = record.name
        logger = logging.getLogger(name)
        # N.B. EVERY record gets logged. This is because Logger.handle
        # is normally called AFTER logger-level filtering. If you want
        # to do filtering, do it at the client end to save wasting
        # cycles and network bandwidth!
        logger.handle(record)

class LogRecordSocketReceiver(SocketServer.ThreadingTCPServer):
    """simple TCP socket-based logging receiver suitable for testing.
    """

    allow_reuse_address = 1

    def __init__(self, host='localhost',
                 port=9022,
                 handler=LogRecordStreamHandler):
        SocketServer.ThreadingTCPServer.__init__(self, (host, port), handler)
        self.abort = 0
        self.timeout = 1
        self.logname = None

    def serve_until_stopped(self):
        import select
        abort = 0
        while not abort:
            rd, wr, ex = select.select([self.socket.fileno()],
                                       [], [],
                                       self.timeout)
            if rd:
                self.handle_request()
            abort = self.abort

def main():
    logging.basicConfig(
        format="%(levelname)s %(name)s %(asctime)s [%(pathname)s:%(lineno)d] %(message)s")
    tcpserver = LogRecordSocketReceiver()
    print "About to start TCP server..."
    tcpserver.serve_until_stopped()

if __name__ == "__main__":
    main()

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券