Before learning the use of the Logger module, you can customize a logger implementation to both file and screen output. However, when using the Software Catalog development specification to organize the code, it is necessary to make the code a block of code, and a series of problems are encountered.
The first is an example of a custom logger:
import logging# first create a Loggerlogger = logging.getlogger (__name__) # The name of the logger is defined, and the name previously called directly with logging is root, and the log format is obtained with% (name) s. The name can also be customized such as "TEST" logger.setlevel (logging. DEBUG) # below this level will be ignored, after which you can also set the output level # create handler and output level ch = logging. Streamhandler () # Output to screen handlerch.setlevel (logging.info) # output level and ignore level above are different, You can look at the effect fh = logging. Filehandler (' Access.log ', encoding= ' utf-8 ') # output to file handler, define character encoding fh.setlevel (logging. WARNING) # Create a log format, you can create a different format ch_formatter = logging for each handler. Formatter ('% (name) s % (asctime) s {% (levelname) s}:% (message) s ', datefmt= '%y-%m-%d %h:%m:%s ') # Key Parameters datefmt custom date format fh_formatter = logging. Formatter ('% (asctime) s % (module) s-% (Lineno) d [% (levelname) s]:% (message) s ', datefmt= '%y/%m/%d %h: %m:%s ') # associate the above log format with the handler Ch.setformatter (Ch_formatter) fh.setformatter (fh_formatter) # Add handler to logGerlogger.addhandler (CH) logger.addhandler (FH) # above is done, look at the output of the log logger.debug (' logger test Debug ') logger.info (' Logger test info ') logger.warning (' logger test warning ') logger.error (' Logger test error ') logger.critical (' logger test critical ')
The
is then made into a module, and the code needs to be written into the function. And because it is written into a function, it is possible to pass in parameters. Here, the name of the log is passed in as a parameter, and several log levels can be passed in if needed.
# writes the following to the log.py file, which can then be invoked as a module in another program Import loggingdef log_mod (name): Logger = logging.getlogger (name) logger.setlevel (logging. DEBUG) ch = logging. Streamhandler () ch.setlevel (logging.info) fh = logging . Filehandler (' Access.log ', encoding= ' Utf-8 ') fh.setlevel (logging. WARNING) ch_formatter = logging. Formatter ('% (module) s-% (Lineno) d % (levelname) s:% (message) s ') fh_formatter = logging. Formatter ('% (asctime) s % (name) s % (levelname) s:% (message) s ', datefmt= '%y/%m/%d %h:%m:%s ') ch.setformatter (Ch_formatter) fh.setformatter (fh_formatter) logger.addhandler (CH) logger.addhandler (FH) # We need to return logger to r.Eturn logger
Then, in another file, call the Log_mod method in the Log module:
Import log# The following statement will print 1 rows of log log.log_mod ("Test") log.log_mod ("test") with each execution 1 times. info ("Test 2") Log.log_mod (" Test "). Info (" Test 3 ") input (" Look at each name in a different case ") # The following is not problematic because of the different names Log.log_mod (" Test1 "). Info (" in Test1 A ") Log.log_mod (" Test2 "). Info (" in Test2 a ") Log.log_mod (" Test3 "). Info (" in Test3 a ")
As a result, one row will be printed more than once per call. The reason should be to call the function multiple times, generating multiple methods. So just make sure to call only 1 functions to avoid this problem.
Import loglog1 = Log.log_mod ("Test1") # only called Once Log.log () Log1.info ("in Log1 A") log1.info ("in Log1 B") log1.info ("in Log1 C") log2 = Log.log_mod ("test2") # If it is another log name, then call again, the name will be different Log2.info ("in log2 A") log2.info (' in log2 B ') log2.info ("in Log2 C ")
But it's not over yet, and the problem is happening again. This is what happens in the function:
Import Logdef log_test1 (): Log1 = Log.log_mod ("Test") # called only once Log.log () Log1.info ("in Log1 A") log1.info ("in log 1 B ") Log1.info (" in Log1 C ") log_test2 () def log_test2 (): log2 = Log.log_mod (" Test ") # Here the log name is the same as above, equal to 1 times Log2.info ("in log2 A") log2.info (' in log2 B ') log2.info ("in log2 C") Log_test1 ()
Log_test2 again called once Log.log_mod caused the log to print more than once. Here if the LOG2 assignment statement commented out, and then change the following log2 to Log1 is also not good, will error.
But this can:
Import Logdef log_test1 (): Log1 = Log.log_mod ("Test") # called only once Log.log () Log1.info ("in Log1 A") log1.info ("in log 1 B ") Log1.info (" in Log1 C ") Log_test2 (LOG1) def log_test2 (log2): Log2.info (' in log2 A ') log2.info (" in log2 B ") Log2.info ("in log2 C") Log_test1 ()
Although good, but so every time the call function will have to pass this parameter continues, very troublesome. And it is not conducive to future changes.
This problem has to be solved from the source, modify the log module:
Import loggingdef log_mod (name): logger = logging.getlogger (name) logger.setlevel (logging. DEBUG) ch = logging. Streamhandler () ch.setlevel (logging.info) fh = logging . Filehandler (' Access.log ', encoding= ' Utf-8 ') fh.setlevel (logging. WARNING) ch_formatter = logging. Formatter ('% (module) s-% (Lineno) d % (levelname) s:% (message) s ') fh_formatter = logging. Formatter ('% (asctime) s % (name) s % (levelname) s:% (message) s ', datefmt= '%y/%m/%d %h:%m:%s ') ch.setformatter (Ch_formatter) fh.setformatter (fh_formatter) logger.addhandler (CH) logger.addhandler (FH) # Here you need to return the logger to return logger ' ' is an additional assignment statement, and calling the log module simplyTo invoke the following 1 or more variables is OK no need to call the above function, each required log name first defines the good one variable in addition, the following definition of the variable part, I was directly written in the log module should also be able to write to the configuration (settings or call conf) module, do not know which is better. "' Log1 = log_mod (" Test1 ") log2 = log_mod (" Test2 ") log3 = log_mod (" Test3 ")
Then we directly call the variables defined in the module:
From log import Log1,log2,log3def log_test1 (): Log1.info ("in Log1 A") log1.info (' in Log1 B ') log1.info ("in Log1 C ") Log_test2 () def log_test2 (): Log2.info (" in log2 A ") log2.info (' in log2 B ') log2.info (" in log2 C ") log_tes T3 () def log_test3 (): Log3.info ("in Log3 A") log3.info (' in Log3 B ') log3.info ("in Log3 C") Log_test1 ()
There is no problem with the output, the problem is finally solved.
The invocation of the logger module in Python