• python的日志模块:logging;django的日志系统;django日志输出时间修改


     Django的log,主要是复用Python标准库中的logging模块,在settings.py中进行配置 

    源代码

    1、__init__.py包含以下类:

    StreamHandler
    Formatter
    %(name)s            Name of the logger (logging channel)
        %(levelno)s         Numeric logging level for the message (DEBUG, INFO,
                            WARNING, ERROR, CRITICAL)
        %(levelname)s       Text logging level for the message ("DEBUG", "INFO",
                            "WARNING", "ERROR", "CRITICAL")
        %(pathname)s        Full pathname of the source file where the logging
                            call was issued (if available)
        %(filename)s        Filename portion of pathname
        %(module)s          Module (name portion of filename)
        %(lineno)d          Source line number where the logging call was issued
                            (if available)
        %(funcName)s        Function name
        %(created)f         Time when the LogRecord was created (time.time()
                            return value)
        %(asctime)s         Textual time when the LogRecord was created
        %(msecs)d           Millisecond portion of the creation time
        %(relativeCreated)d Time in milliseconds when the LogRecord was created,
                            relative to the time the logging module was loaded
                            (typically at application startup time)
        %(thread)d          Thread ID (if available)
        %(threadName)s      Thread name (if available)
        %(process)d         Process ID (if available)
        %(message)s         The result of record.getMessage(), computed just as
                            the record is emitted
    FileHandler
    日志级别:
    CRITICAL = 50
    FATAL = CRITICAL
    ERROR = 40
    WARNING = 30
    WARN = WARNING
    INFO = 20
    DEBUG = 10
    NOTSET = 0

    2、config.py

    3、handlers.py包含以下class

    TimedRotatingFileHandler:可以根据时间自动生成新的日志文件
    HTTPHandler:
    RotatingFileHandler:可以根据日志大小自动生成新的日志文件

    日志处理类:

    class        功能
    StreamHandler    输出到Stream。通常用来打印到标准输出。
    FileHandler    打印到文件。
    NullHandler    不格式化也不打印。主要是为了避免No handlers could be found for logger XXX的设计。
    WatchedFileHandler    自动重开log文件,配合别的会自动切分的log文件使用。
    RotatingFileHandler    自动按大小切分的log文件。
    TimedRotatingFileHandler    按时间自动切分的log文件。
    SocketHandler    向Socket打log,基于TCP协议。
    DatagramHandler    向Socket打log,基于UDP协议。
    SysLogHandler    在Unix-like系统打印到remote或local的Unix syslog。
    NTEventLogHandler    在Windows系统打印到微软的event log。
    SMTPHandler    通过email发送log。
    MemoryHandler    打印到内存buffer。
    HTTPHandler    通过HTTP协议向服务器发送log。
    QueueHandler    打log到Queue中,适合多进程(multiprocessing)场景。

     

    分层传递日志

    a.b.c.d会把日志传到a.b.c;a.b.c会把日志传到a.b;a.b会把日志传到a

    写到相应层级日志的方法是,在需要记录日志的文件地方,使用如下函数,里面根据需要填写相应的层级:logger = logging.getLogger('a.b.c')

    Django日志示例:

    配置:

    
    
    # https://docs.djangoproject.com/zh-hans/2.1/topics/logging/
    LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
    'verbose': {
    # 后缀d表示数据格式是整数,s表示数据格式是字符串
    'format': '[%(levelname)s] [%(asctime)s] [%(module)s] %(filename)s:%(lineno)d %(funcName)s '
    '%(processName)s:[%(process)d] %(threadName)s:[%(thread)d] %(message)s'
    # 'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
    # 'style': '{',
    },
    'simple': {
    'format': '[%(levelname)s] [%(asctime)s] %(message)s',
    # 'format': '[%(asctime)s] %(message)s',
    # 后缀d表示数据格式是整数,s表示数据格式是字符串
    # 'format': '[%(levelname)s] [%(asctime)s] [%(module)s] %(filename)s:%(lineno)d %(funcName)s '
    # '%(processName)s:[%(process)d] %(threadName)s:[%(thread)d] %(message)s',
    # 'style': '{',
    },
    'standard': {
    # 'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s',
    'format': '{asctime} [{levelname:6}] {name:30}: {message}',
    # 设置上面格式样式;{lineno:3}是行号,至少显示3个字符,少则补空格
    # 这里style选择{,是指{asctime}这种形式。
    # 如果选择%,则是%(asctime)s这种形式。
    # 还有一种选择,是$,是$asctime或${asctime}这种形式。
    'style': '{',
    # 设置时间格式
    'datefmt': '%Y-%m-%d %H:%M:%S',
    },
    'operation': {
    'format': '%(message)s'
    }
    },
    # 'filters': {
    # # 'special': {
    # # '()': 'erebus.logging.SpecialFilter',
    # # 'foo': 'bar',
    # # },
    # 'require_debug_true': {
    # '()': 'django.utils.log.RequireDebugTrue',
    # },
    # },

    # Handler是决定如何处理logger中每一条消息的引擎。它描述特定的日志行为,比如把消息输出到屏幕、文件或网络socket。
    # 和 logger 一样,handler 也有日志级别的概念。如果一条日志记录的级别不匹配或者低于 handler 的日志级别,
    # 对应的消息会被 handler 忽略。
    'handlers': {
    'default': {
    'level': 'DEBUG',
    'class': 'logging.handlers.RotatingFileHandler',
    'filename': 'logs/default.log',
    # 'maxBytes': 1024*1024*5, # 5 MB
    'maxBytes': 1024*5, # 5 KB
    'backupCount': 5,
    'formatter': 'standard',
    },
    'output_to_file': {
    'level': 'INFO', # 忽略debug信息
    'class': 'logging.FileHandler',
    'filename': '{}/{}.log'.format(BASE_LOG_DIR, conf.get('log', 'name')),
    'formatter': 'simple' if DEBUG else 'verbose',
    'encoding': 'utf8',
    },
    'console_log': {
    'level': 'DEBUG', # 所有的日志都会被输出到console
    # 'filters': ['require_debug_true'],
    'class': 'logging.StreamHandler',
    'formatter': 'simple'
    },
    'operation': {
    'level': 'INFO',
    'class': 'logging.FileHandler',
    'filename': '{}/{}.log'.format(BASE_LOG_DIR, 'operation'),
    'formatter': 'operation',
    'encoding': 'utf8'
    }
    # 'mail_admins': {
    # 'level': 'ERROR',
    # 'class': 'django.utils.log.AdminEmailHandler',
    # # 'filters': ['special']
    # }
    },
    'loggers': {
    # 可以通过使用空字符串:''来设置'catch all' logger
    # 在以下设置中,将所有日志事件保存到logs/default.log,但配置为'propagate': False日志事件除外,
    # 这些日志事件将保存到相应的日志文件中,比如本文的logs/erebus.log。
    '': {
    'handlers': ['default'],
    'level': 'DEBUG',
    'propagate': True
    },
    # 名字随意起,用时,使用logger = logging.getLogger(conf.get('log', 'name'))获取,传到相应的loggers里就可以
    conf.get('log', 'name'): {
    'handlers': ['output_to_file', 'console_log'],
    # 当 logger 处理一条消息时,会将自己的日志级别和这条消息的日志级别做对比。
    # 如果消息的日志级别匹配或者高于 logger 的日志级别,它就会被进一步处理。
    # 否则这条消息就会被忽略掉。当 logger 确定了一条消息需要处理之后,会把它传给 Handler。

    # 'level': 'INFO', # debug日志会被忽略
    'level': 'DEBUG', # 所有的日志都会被处理
    'propagate': False, # 值为False,表示日志不会传到上个层级,自然也不会传到default.log里
    },
    # 使用logger = logging.getLogger('django.request'), logger.info('info'),
    # 可以把日志输出到'handlers': ['output_to_file', 'console_log'],
    # 这里的名字不能随便取,命名为django、django.request才会捕获django的日志
    conf.get('log', 'name')+'.request': {
    'handlers': ['output_to_file', 'console_log'],
    'level': 'DEBUG',
    # 会把日志向django.request的上层django传播
    'propagate': True,
    },
    # 'erebus.custom': {
    # 'handlers': ['console', 'mail_admins'],
    # 'level': 'INFO',
    # # 'filters': ['special']
    # },
    'operation': {
    'handlers': ['operation'],
    'level': 'INFO',
    # 'propagate': True,
    }
    }
    }
     

    使用日志

    logger = logging.getLogger('django')
    def hello(request):
    content = {'hello': 'hello world'}
    # return HttpResponse("hello world")
    logger.error('test')
    logger.error('访问hello界面:error')
    logger.debug('访问hello界面:debug')
    logger.info('访问hello界面:info')
    logger.warning('访问hello界面:warning')
    logger.critical('访问hello界面:critical')
    logger.log(40, '测试')
    logger.exception('ceshi')
    return render(request, 'hello.html', content)

    时间格式:

    Directive    Meaning Notes
    %a    Locale’s abbreviated weekday name.
    %A    Locale’s full weekday name.
    %b    Locale’s abbreviated month name.
    %B    Locale’s full month name.
    %c    Locale’s appropriate date and time representation.
    %d    Day of the month as a decimal number [01,31].
    %H    Hour (24-hour clock) as a decimal number [00,23].
    %I    Hour (12-hour clock) as a decimal number [01,12].
    %j    Day of the year as a decimal number [001,366].
    %m    Month as a decimal number [01,12].
    %M    Minute as a decimal number [00,59].
    %p    Locale’s equivalent of either AM or PM. (1)
    %S    Second as a decimal number [00,61]. (2)
    %U    Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3)
    %w    Weekday as a decimal number [0(Sunday),6].
    %W    Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3)
    %x    Locale’s appropriate date representation.
    %X    Locale’s appropriate time representation.
    %y    Year without century as a decimal number [00,99].
    %Y    Year with century as a decimal number.
    %z    Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].
    %Z    Time zone name (no characters if no time zone exists).
    %%    A literal '%' character.

    Django内置的loggers:

    Django provides several built-in loggers.

    djangodjango.request、django.serverdjango.templatedjango.db.backends、django.security.*、django.security.csrf、django.db.backends.schema

    日志输出时区问题

    当设置日志时区为utc时,中国时区的日志输出会相差8个小时

    # 使用utc时间,前端根据时区自动显示当地时间
    USE_TZ = True
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True

    这是需要修改日志模块,在settings配置里添加:

    def beijing(sec, what):
        beijing_time = datetime.datetime.now() + datetime.timedelta(hours=8)
        return beijing_time.timetuple()
    
    
    logging.Formatter.converter = beijing

    参考:

    1、https://codeday.me/bug/20170630/32009.html

    2、http://note.qidong.name/2018/11/django-logging/

    3、https://docs.djangoproject.com/zh-hans/2.1/topics/logging/#django-request

    4、https://blog.csdn.net/u010099080/article/details/85944741

  • 相关阅读:
    O052、Create Volume 操作 (Part III)
    O051、Create Volume 操作 (Part II)
    O050、Create Volume 操作 (Part I)
    O049、准备 LVM Volume Provider
    O048、掌握 cinder-scheduler 调度逻辑
    O047、 Cinder 组件详解
    O046、掌握Cinder 的设计思想
    O045、理解 Cinder 架构
    O044、一张图秒懂 Nova 16种操作
    O043、计算节点宕机了怎么办
  • 原文地址:https://www.cnblogs.com/shengulong/p/10294017.html
Copyright © 2020-2023  润新知