Log entry learning

  • 2020-10-31 21:48:55
  • OfStack

Python Logging It turned out to be much more complicated than I expected, and the learning route was comparable to git. However, alternatives is not enough, so we must pay more attention to it and learn from it earnestly and earnestly.

The purpose of learning Logging:

Simple scripts are ok, print is enough.

But it gets a little more complicated, even with 34 files and two or three hundred lines of code, debugging gets a little more complicated.

In addition, if the script is running in the background for a long time, the investigation of running information is more complicated.

At first, I was still looking for all kinds of information crontab Log view, or python Run view in the background, or python stdout And so on, all looking in the wrong direction.

The real solution lies in the right logging.

Once I've done that, I don't need to look for the console output of python or the log of crontab, I just need to look at the file log.

The following is the record of logging's learning.

Simplest log output (no file record)


import logging
 
logging.error(" Something went wrong ")
logging.info(" The print information ")
logging.warning(" Warning message ")

First of all, forget logging.info ()! Forget the logging. basicConfig ()!

The various online articles about python logging are so inconsiderate to the novice that logging, such a complex thing, tries to appear simple and USES all kinds of simple things as illusions.

In fact, the log that we really want to use is definitely not directly used logging.info() and logging.basicConfig() Well, this is the official launch of this module to confuse people - it seems to let you 1 key to get started, quickly see the results, but with the actual really does not match!

So in order to be easy to explain later, I must warn you: Forget them both!

Remember, only one is going to be used logging. What, just logging.getLogger() This 1 time.

Understand the workflow of logging

I don't want to do flowchart 1 stuff, which is even more confusing.

To put it simply:

logging Modules are automatically customized to your logger object 全局化 The,

That is, if you define logger once in your module, say, log, it can be read by any other file running in the same module.

For example, if you have a custom logger in the main file main.py, what kind of output file, output format, etc., can you set crontab0 Will refer to some other file or module, such as sub.py So in sub.py you don't have to set anything, just one sentence logger = logging.getLogger('之前在main.py定义的日志名') You get the previous 1 - slice custom Settings.

Of course, in the called file (called a submodule first), the logging.getLogger('日志名') , it is better to add 1 after the log name .子名称 main.sub, for example. The output will show that the log is from this file. Of course, the previous parent logger must have a name of 1 to, and it will be recognized!

Then, sublogs can have sublogs, or even a submodule can have one sublog for each function, such as main.sub.func1. logging will be based on. Identify the relationship between superior and subordinate.

Thus, in effect, this is the mechanism for class class inheritance. You inherit from the parent name, and then you can rewrite your own new Settings, etc.

Once you understand these concepts, let's talk about code. It's actually a lot easier to understand.

Set the method for logger

Look, says the article more comprehensive and clear, under a lot of reference to the contents of it: Python 101: An Intro to logging

1 generally want to customize 1 logger, such as what format to display when it outputs information, which file to output to, whether to output to screen 1 class, there are three ways to achieve the setting:

Set directly in the python code Use the external ES135en.ini file configuration Use the dict dictionary configuration for python

The syntax of ini is not easy to read, and it is not easy to set variables dynamically, so just write it directly in python code.

Common Settings statement

Note that 1 must define logger at the main entry so that all other submodules can inherit it.


#  main.py
import logging
import otherMod2  #  The submodule that will be called later 

def main():
  """
   This file is the main entry to the program 
  """

  define_logger()

  log = logging.getLogger('exampleApp')

  #  Output information test 
  logger.info("Program started")
  result = otherMod2.add(7, 8)   #  This is a method from another module 
  logger.info("Done!")

def define_logger():
  logger = logging.getLogger("exampleApp")
  logger.setLevel(logging.INFO)

  #  Set the output format 
  formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 
  #  Set up the log file processor 
  fh = logging.FileHandler("new_snake.log")
  fh.setFormatter(formatter)  #  Add format for this processor 

  #  Set the screen stdout Output processor 
  sh = logging.StreamHandler(stream=None)
  sh.setFormatter(formatter)
 
  #  Add the processor to logger on 
  logger.addHandler(fh)
  logger.addHandler(sh)
 
if __name__ == "__main__":
  main()

Here are the call methods in the submodule (very simple) :


# otherMod2.py
import logging
 
module_logger = logging.getLogger("exampleApp.otherMod2")

def add(x, y):
  #  Here, 1 other `getLogger` It's inherited from the parent logger the 
  logger = logging.getLogger("exampleApp.otherMod2.add")

  #  Output test 
  logger.info("added %s and %s to get %s" % (x, y, x+y))
  return x+y

Notice that in the main file, you can define logger anywhere, either in main() or in any individual function or class, it doesn't matter. You just need to define it before you call the submodule. Once defined, the log name is written down and submodules can be easily inherited.


Related articles: