GVKun编程网logo

Python logger 全局使用,单例模式(python logger handler)

2

最近很多小伙伴都在问Pythonlogger全局使用,单例模式和pythonloggerhandler这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展0x04Pythonlogge

最近很多小伙伴都在问Python logger 全局使用,单例模式python logger handler这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展0x04 Python logger 支持多进程日志按大小分割、Golang 版的 PSR-3 Logger 规范,支持自定义 Logger、Java Logger(java.util.logging.logger)不替代变量、logger.debug,logger.info,logger.warn,logger.error,logger.fatal的区别等相关知识,下面开始了哦!

本文目录一览:

Python logger 全局使用,单例模式(python logger handler)

Python logger 全局使用,单例模式(python logger handler)

import logging
from logging import handlers
 
class PyLogger(object):
    level_relations = {
        'debug':logging.DEBUG,
        'info':logging.INFO,
        'warning':logging.WARNING,
        'error':logging.ERROR,
        'crit':logging.CRITICAL
    }   # Log level relationship mapping
    
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        '''

        Parameters
        ----------
        Comment : Singleton mode
        if you want to change or add new logfile, just input new filename
        
        For example:
            
            example start:
            
            log = PyLogger('all_test456.log',level='debug')
            log.logger.debug('debug')
            log.logger.info('info')
            log.logger.warning('警告')
            log.logger.error('报错')
            log.logger.critical('严重')
            log.logger.info(log)
            PyLogger('error.log', level='error').logger.error('error') # PyLogger object at 0x00000222F177EF48>
            
            log_new = PyLogger('all_test456789.log',level='debug')
            log_new.logger.debug('debug')
            log_new.logger.info('info')
            log_new.logger.warning('警告')
            log_new.logger.error('报错')
            log_new.logger.critical('严重')
            log_new.logger.info(log_new)
            PyLogger('error.log', level='error').logger.error('error') # PyLogger object at 0x00000222F177EF48>
        
            example end:
        
        cls : TYPE
            DESCRIPTION.
        *args : TYPE
            DESCRIPTION.
        **kwargs : TYPE
            DESCRIPTION.

        Returns
        -------
        TYPE
            DESCRIPTION.

        '''
        if cls._instance is None:
            cls._instance = object.__new__(cls)
        return  cls._instance
 
    def __init__(self, filename,level='info',when='D',backCount=3,fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
        self.logger = logging.getLogger(filename)
        format_str = logging.Formatter(fmt) #S et log format
        self.logger.setLevel(self.level_relations.get(level)) # Set log level
        if not self.logger.handlers:
            sh = logging.StreamHandler() # Output to the screen
            sh.setFormatter(format_str) # Set the format displayed on the screen
            
            # Write to file #The processor that automatically generates the file at the specified interval
            th = handlers.TimedRotatingFileHandler(filename=filename,when=when,backupCount=backCount,encoding='utf-8')
            
            # Instantiate TimedRotatingFileHandler
            # interval is the time interval, backupCount is the number of backup files, if it exceeds this number, it will be automatically deleted, when is the time unit of the interval, the units are as follows:
            # S seconds
            # M points
            # H hours,
            # D day,
            # W Every week (interval==0 means Monday)
            # midnight Every morning
            th.setFormatter(format_str) # Set the format written in the file
            self.logger.addHandler(sh) # Add object to logger
            self.logger.addHandler(th)

            
if __name__ == '__main__':
    log = PyLogger('all_test456.log',level='debug')
    log.logger.debug('debug')
    log.logger.info('info')
    log.logger.warning('警告')
    log.logger.error('报错')
    log.logger.critical('严重')
    log.logger.info(log)
    PyLogger('error.log', level='error').logger.error('error') # PyLogger object at 0x00000222F177EF48>
    
    log_new = PyLogger('all_test456789.log',level='debug')
    log_new.logger.debug('debug1')
    log_new.logger.info('info1')
    log_new.logger.warning('警告1')
    log_new.logger.error('报错1')
    log_new.logger.critical('严重1')
    log_new.logger.info(log_new)
    PyLogger('error.log', level='error').logger.error('error') # PyLogger object at 0x00000222F177EF48>

0x04 Python logger 支持多进程日志按大小分割

0x04 Python logger 支持多进程日志按大小分割

支持多进程日志按大小分割

[toc]

由于python内置模块logging.handlers.RotatingFileHandler是不支持多进程下日志分割的,存在进程间竞争同一文件。在网上找到了支持多进程的日志分割方案。 参考 中文博客 参考 英文mrfh

多进程日志大小分割handler配置实例

  1. 安装mrfh模块 pip install mrfh
  2. 由于mrfh用到了fcntl模块,只有linux才有所以在win下是不可用的
  3. 下面是一个日志配置的实例,在file_size_rotate_hd中就用到了mrfh提供的handler。
 LOGGER_CONFIG_DICT = {
        ''version'': 1,
        ''disable_existing_loggers'': False,
        ''formatters'': {
            ''detailed_fmt'': {
                ''class'': ''logging.Formatter'',
                ''format'': ''%(asctime)s %(created)s %(levelname)-6s %(name)-15s %(processName)s:%(threadName)s %(message)s''
                #  human-readable  timestamp levelname logger_name  processname threadname  message
            },
            ''simple_fmt'': {
                ''class'': ''logging.Formatter'',
                ''format'': ''%(asctime)s %(levelname)-8s %(name)-15s %(message)s''
                #  human-readable  levelname logger_name message
            },
            ''portal_fmt'': {
                ''class'': ''logging.Formatter'',
                # ''datefmt'': ''%Y-%m-%d %H:%M:%S,uuu'',  # 实际默认格式就是这个
                ''format'': ''%(asctime)s %(levelname)-8s %(name)-15s  %(processName)-10s %(message)s''
            },
            ''system_fmt'': {
                ''class'': ''logging.Formatter'',
                ''format'': ''%(asctime)s %(name)-15s %(levelname)-8s %(processName)-10s %(message)s''
            },
        },
        ''handlers'': {
            ''file_size_rotate_hd'': {
                #''class'': ''logging.handlers.RotatingFileHandler'',
                ''class'': ''mrfh.MultiprocessRotatingFileHandler'',  # 这里就是用到mrfh了。
                ''filename'': ''./logs/portal.log'',
                ''mode'': ''a'',
                ''maxBytes'': 1024 * 1024 * 500,
                ''backupCount'': 50,
                ''formatter'': ''portal_fmt''
            },
            ''errors_hd'': {
                ''class'': ''logging.FileHandler'',
                ''filename'': ''./logs/errors.log'',
                ''formatter'': ''detailed_fmt'',
                ''level'': ''ERROR''  # 只会错误40及以上的日志
            },
            ''system_hd'': {
                ''class'': ''logging.FileHandler'',
                ''filename'': ''./logs/system.log'',
                ''formatter'': ''simple_fmt''
            }
        },
        ''loggers'': {
            ''selfservices'': {
                ''level'': ''INFO'',
                ''propagate'': False,
                ''handlers'': [''file_size_rotate_hd'', ''errors_hd'']
                # ''handlers'': [''time_rotate_file_hd'', ''file_size_rotate_hd'', ''errors_hd'']
            },
        },
        ''root'': {
            ''level'': ''DEBUG'',
            ''handlers'': [''system_hd'', ''errors_hd'']
        },
    }

Golang 版的 PSR-3 Logger 规范,支持自定义 Logger

Golang 版的 PSR-3 Logger 规范,支持自定义 Logger

开源地址

  • https://github.com/go-packagist/logger
  • https://flc.io/go-packagist-logger/
Go VersionGoDoccodecovGo Report CardtestsMIT license
说明: 设计参考 PHP PSR-3 规范,做了一些调整后实现。

安装

go get github.com/go-packagist/logger

教程

package main

import (
    "fmt"
    "github.com/go-packagist/logger"
    "time"
)

type CustomLogger struct {
    logger.Loggerable
}

var _ logger.Logger = (*CustomLogger)(nil)

func NewCustomLogger() *CustomLogger {
    c := &CustomLogger{
        Loggerable: func(level logger.Level, s string) {
            fmt.Println(fmt.Sprintf("%s %s: %s", time.Now().Format(time.DateTime), level.UpperString(), s))
        },
    }

    return c
}

func main() {
    c := NewCustomLogger()

    c.Emergencyf("Emergencyf: %s", "test")
    c.Alertf("Alertf: %s", "test")
    c.Criticalf("Criticalf: %s", "test")
    c.Errorf("Errorf: %s", "test")
    c.Warningf("Warningf: %s", "test")
    c.Noticef("Noticef: %s", "test")
    c.Infof("Infof: %s", "test")
    c.Debugf("Debugf: %s", "test")

    c.Emergency("Emergency: test")
    c.Alert("Alert: test")
    c.Critical("Critical: test")
    c.Error("Error: test")
    c.Warning("Warning: test")
    c.Notice("Notice: test")
    c.Info("Info: test")
    c.Debug("Debug: test")

    c.Log(logger.Emergency, "Log: Emergency: test")

    // Output:
    // 2023-03-28 23:18:13 EMERGENCY: Emergencyf: test
    // 2023-03-28 23:18:13 ALERT: Alertf: test
    // 2023-03-28 23:18:13 CRITICAL: Criticalf: test
    // 2023-03-28 23:18:13 ERROR: Errorf: test
    // 2023-03-28 23:18:13 WARNING: Warningf: test
    // 2023-03-28 23:18:13 NOTICE: Noticef: test
    // 2023-03-28 23:18:13 INFO: Infof: test
    // 2023-03-28 23:18:13 DEBUG: Debugf: test
    // 2023-03-28 23:18:13 EMERGENCY: Emergency: test
    // 2023-03-28 23:18:13 ALERT: Alert: test
    // 2023-03-28 23:18:13 CRITICAL: Critical: test
    // 2023-03-28 23:18:13 ERROR: Error: test
    // 2023-03-28 23:18:13 WARNING: Warning: test
    // 2023-03-28 23:18:13 NOTICE: Notice: test
    // 2023-03-28 23:18:13 INFO: Info: test
    // 2023-03-28 23:18:13 DEBUG: Debug: test
    // 2023-03-28 23:18:13 EMERGENCY: Log: Emergency: test
}

内置 Logger

  • logger.NewNullLogger() - 啥也不干
  • logger.NewPrintLogger() - 打印到控制台

参考资料

  • PSR-3: Logger Interface:https://www.php-fig.org/psr/psr-3/
  • PSR Log:https://github.com/php-fig/log
  • Go Redis: https://github.com/redis/go-redis/ (参考了一些设计思路)

Java Logger(java.util.logging.logger)不替代变量

Java Logger(java.util.logging.logger)不替代变量

所以我发现在味精中使用Sep 16,2020 4:10:22 PM pages.pageUtils.CustomExpectedConditions$1 apply INFO: Actual: 2 Sep 16,2020 4:10:22 PM pages.pageUtils.CustomExpectedConditions$1 apply INFO: jQuerys active: {0} 导致了问题。即使在使用'时,我也遇到了同样的问题。尽管删除它可以解决问题,但我想知道是否可以通过任何方式在日​​志中使用\'

logger.debug,logger.info,logger.warn,logger.error,logger.fatal的区别

logger.debug,logger.info,logger.warn,logger.error,logger.fatal的区别

logger.debug,logger.info,logger.warn,logger.error,logger.fatal的区别

logger.debug,logger.info,logger.warn,logger.error,logger.fatal的作用都是把错误信息写到文本日志里

不同的是它们表示的日志级别不同:
日志级别由高到底是:fatal,error,warn,info,debug,低级别的会输出高级别的信息,高级别的不会输出低级别的

信息,如等级设为Error的话,warn,info,debug的信息不会输出

修改日志输出的级别要在log4j文件中进行配置
项目正式发布后,一般会把日志级别设置为fatal或者error
 

今天关于Python logger 全局使用,单例模式python logger handler的讲解已经结束,谢谢您的阅读,如果想了解更多关于0x04 Python logger 支持多进程日志按大小分割、Golang 版的 PSR-3 Logger 规范,支持自定义 Logger、Java Logger(java.util.logging.logger)不替代变量、logger.debug,logger.info,logger.warn,logger.error,logger.fatal的区别的相关知识,请在本站搜索。

本文标签: