A brief analysis of duplicate output of Python log

Source: Internet
Author: User

[TOC]

Problem Origin:

? After learning the functional programming of Python, the logging is exposed to such a powerful log module. In order to reduce duplication of code, it should be a lot of classmates and I can not wait to write a log function, such as the following:

# 这里为了便于理解,简单的展示了一个输出到屏幕的日志函数def my_log():    = logging.getLogger(‘mysql.log‘)    = logging.StreamHandler()    ch.setLevel(logging.ERROR)    = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)    ch.setFormatter(fmt)    logger.addHandler(ch)    return loggermy_log().error(‘run one‘)my_log().error(‘run two‘)my_log().error(‘run three‘)

The function is written, and it seems to be fine, let's run it!

The results are as follows:

2018-06-21 13:06:37,569-mysql.log-error-run One
2018-06-21 13:06:37,569-mysql.log-error-run
2018-06-21 13:06:37,569-mysql.log-error-run
2018-06-21 13:06:37,569-mysql.log-error-run Three
2018-06-21 13:06:37,569-mysql.log-error-run Three
2018-06-21 13:06:37,569-mysql.log-error-run Three

The log is actually repeated output, and the number is increasing.

Problem resolution
    • In fact, logger = logging.getLogger(‘mysql.log‘) when executing, not each time a new logger is generated, but first check whether there is a logger object called ' Mysql.log ' in memory, the existence is removed, does not exist the new.

    • The instantiated logger object has a property such as ' handlers ' to store the Handler, and the code demonstrates the following:

"' Python
Def my_log ():
Logger = Logging.getlogger (' Mysql.log ')
# Print out the handlers list of logger after each call
Print (logger.handlers)

  ch = logging.StreamHandler()  ch.setLevel(logging.ERROR)  fmt = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)  ch.setFormatter(fmt)  logger.addHandler(ch)  return logger

My_log (). Error (' Run one ')
My_log (). Error (' Run ')
My_log (). Error (' Run three ')
```

Operation Result:

[]
2018-06-21 13:26:14,059-mysql.log-error-run One
[<streamhandler

    1. logger.handlersInitially an empty list, execute ' logger.addhandler (CH) ' To add a ' streamhandler ', output a log
    2. In the second call, logger.handlers there is already a ' streamhandler ', the execution of ' Logger.addhandler (CH) ' will add a ' streamhandler ' again, at this time the logger has two ' Streamhandler ', output two duplicate logs
    3. In the third call, logger.handlers there are already two ' Streamhandler ', the second execution of ' Logger.addhandler (CH) ' will be added again, at this time the logger has three ' streamhandler ', output three duplicate log
Workaround 1. gaiminghuanxing
# 为日志函数添加一个name,每次调用时传入不同的日志名def my_log(name):    = logging.getLogger(name)    = logging.StreamHandler()    ch.setLevel(logging.ERROR)    = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)    ch.setFormatter(fmt)    logger.addHandler(ch)    return loggermy_log(‘log1‘).error(‘run one‘)my_log(‘log2‘).error(‘run two‘)my_log(‘log3‘).error(‘run three‘)

Operation Result:

2018-06-21 13:40:51,685-log1-error-run One
2018-06-21 13:40:51,685-log2-error-run
2018-06-21 13:40:51,685-log3-error-run Three

2. Timely Cleaning (Logger.handlers.clear)
def my_log():    = logging.getLogger()    # 每次被调用后,清空已经存在handler    logger.handlers.clear()    = logging.StreamHandler()    ch.setLevel(logging.ERROR)    = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)    ch.setFormatter(fmt)    logger.addHandler(ch)    return loggermy_log().error(‘run one‘)my_log().error(‘run two‘)my_log().error(‘run three‘)

Ps:removehandler method (Poor compatibility)

# 这种写法下的可以使用removeHandler方法(logger.handlers.clear也可以使用在这种写法的函数内)import loggingdef my_log(msg): logger = logging.getLogger(‘mysql.log‘) ch = logging.StreamHandler() ch.setLevel(logging.ERROR) fmt = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘) ch.setFormatter(fmt) logger.addHandler(ch) logger.error(msg) # 在使用完ch后从移除 logger.removeHandler(ch)my_log(‘run one‘)my_log(‘run two‘)my_log(‘run three‘)
3. Judging before use
ImportLoggingdefMy_log (): Logger=Logging.getlogger (' Mysql.log ')# To determine if logger has added handler, is to return the Logger object directly, otherwise execute handler settings and addhandler (CH)    if  notLogger.handlers:ch=Logging. Streamhandler () Ch.setlevel (logging. ERROR) FMT=Logging. Formatter ('% (asctime) s - % (name) s - % (levelname) s - % (message) s') Ch.setformatter (FMT) logger.addhandler (CH)returnLoggermy_log (). Error (' Run one ') My_log (). Error (' Run ') My_log (). Error (' Run three ')
Summarize

? The first time I encountered a recurring log output problem, I didn't learn anything about object-oriented programming at the time, and didn't really understand the logging module. After learning object-oriented programming, it's a great feeling to go back and think about these problems.

? For example, at first the logging.getLogger actual principle is not very understanding, in the object-oriented programming in the Hasattr, GetAttr, SetAttr and so on a few ways after the epiphany. So gentlemen if you still do not understand the logging module, it is advisable not to dwell on these details, continue to learn.

? After the expansion of knowledge, some of the problems will naturally be solved:)

Reference content:

Luffycity:https://www.luffycity.com/home

The Python standard Library

huilan_same:51858817

Analysis of duplicate output of Python log

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.