Logging module:
The logging module in the standard library, which was used to solve the problem of print interruption when learning thread safety earlier, describes the function of the logging module.
logging modules are thread-safe and do not require any special work from customers. It achieves this by using thread locks; There is a lock to serialize the access to the module's shared data, and each handler also creates a lock to serialize access to its underlying I/O.
Logging Level:
level |
value |
CRITICAL |
50 |
ERROR |
40 |
WARNING |
30, default |
INFO |
20 |
DEBUG |
10 |
NOTSET |
0 |
The lower the level of records defined, the more information, the higher the level, and the less information.
Logging formatted string:
Property name |
format |
Description |
Asctime |
%(asctime)s |
Easy-to-read time format: The default is ' 2003-07-08 16:49:45,896 ' (the number after the comma is the millisecond part of the time) |
FileName |
%(filename)s |
The file name portion of the pathname. |
FuncName |
%(funcName)s |
function name in which the log call is located |
levelname |
% (LevelName) s The level name of the |
message ( ' DEBUG ' , < Code class= "docutils literal" > ' INFO ' , ' WARNING ' , ' ERROR ' , ' CRITICAL ' ). |
Levelno |
%(levelno)s |
The log level corresponding to the number format (,,, DEBUG INFO WARNING ERROR , CRITICAL ). |
Lineno |
%(lineno)d |
The source line number that issued the logging call, if available. |
Module |
%(module)s |
The module name in which it is located (e.g. the test6.py module records TEST6) |
Message |
%(message)s |
The information recorded |
Name |
%(name)s |
Name of the logger logger called |
Process |
%(process)d |
Process ID |
ProcessName |
%(processName)s |
Process Name |
Thread |
%(thread)d |
Thread ID |
ThreadName |
%(threadName)s |
Thread Name |
Use the Basicconfig method to configure the logging record format:
format |
Description |
filename |
Specifies that Filehandler is created using the specified file name instead of Streamhandler. |
filemode |
Specifies the mode of the open file, if filename is specified (the default is ' a ' if the file mode is not specified). |
format |
Uses the specified format string for a handler. |
datefmt |
Use the specified date/time format. |
level |
Sets the root logger level to the specified level. |
handlers |
If specified, this should be an iterator to the root logger that has already been created by the handler. any handlers that have not yet set the formatter will be assigned the default formatter created in this function . |
Example:
Import threadingimport Loggingformat = "% (asctime) s% (thread) d% (message) S" Logging.basicconfig (Level=logging.info, Format=format) def add (x, y): logging.warning ("{} {}". FORMAT (Threading.enumerate (), x+y)) T = Threading. Timer (1,add,args= (4,5)) T.start () Run result: 2017-12-17 15:40:34,226 123145367023616 [<_mainthread (Mainthread, stopped 4320629568), <timer (Thread-1, started 123145367023616);] 9
To modify the date format:
DATEFMT = "[%y-%m-%d%h:%m:%s]" FORMAT = "% (asctime) s% (thread) d% (message) S" Logging.basicconfig (Level=logging.info, FORMAT=FORMAT,DATEFMT=DATEFMT)
[2017-12-17 15:45:18]
Output to File:
Logging.basicconfig (level=logging.info,format=format,datefmt=datefmt,filename= ' Class_test.log ')
The file path is not specified and defaults to the current module path.
Import Threadingimport loggingdatefmt = "[%y-%m-%d%h:%m:%s]" FORMAT = "% (asctime) s% (thread) d% (message) S" Logging.basicconfig (level=logging.info,format=format,datefmt=datefmt,filename= ' Class_test.log ') def add (x, y): logging.warning ("{} {}". Format (Threading.enumerate (), x+y)) T = Threading. The Timer (1,add,args= (4,5)) T.start () output appends the Class_test.log file written to the current module path: [2017-12-17 15:50:13] 123145503244288 [<_ Mainthread (Mainthread, stopped 4320629568), <timer (Thread-1, started 123145503244288);] 9
Logger class:
Structure
Returns a logger instance using the factory method.
logging.
getLogger
([Name=none])
Specifies name, which returns a logger instance called name. If the same name is used again, an object is instantiated. Name is not specified, the logger instance is returned, and the name is root, which is root logger.
Logger are hierarchical, using the '. ' dot division, such as ' a ', ' a.b ' or ' a.b.c.d ', ' a ' is the parent of ' a.b ' parent,a.b is the child of a. For Foo, the names Foo.bar, Foo.bar.baz, and Foo.bam are descendants of Foo.
Example:
Import loggingdatefmt = "[%y-%m-%d%h:%m:%s]" FORMAT = "% (asctime) s% (thread) d% (message) S" Logging.basicconfig (level= Logging.info,format=format,datefmt=datefmt,filename= ' class_test.log ') root = Logging.getlogger () print (Root.name, Type (root), root.parent,id (root)) logger = Logging.getlogger (__name__) print (Logger.name, type (logger), ID (logger), ID ((logger.parent))) Logger1 = Logging.getlogger (__name__ + ". Ok") print (Logger1.name, type (LOGGER1), id (logger1), id ((logger1.parent))) Print (Logger1.parent,id (logger1.parent)) Run result: Root <class ' logging. Rootlogger ' > None 4367575248__main__ <class ' logging. Logger ' > 4367575864 4367575248__main__.ok <class ' logging. Logger ' > 4367575920 4367575864<logging. Logger object at 0x10453eb38> 4367575864
The level setting of child children does not affect the level of parent parents:
Import Loggingformat = "% (asctime) s% (thread) d% (message) S" Logging.basicconfig (level=logging. Warning,format=format,datefmt= "[%y-%m-%d%h:%m:%s]") root = Logging.getlogger () print (1,root,id (root)) #RootLogger, Root Loggerroot.info (' my root ') #低于定义的WARNING级别, so Loga = Logging.getlogger (__name__) #Logger继承自RootLoggerprint (2, Loga,id (Loga), ID (loga.parent)) print (3,loga.geteffectivelevel ()) #数值形式的有效级别loga. Warning (' before ') Loga.setlevel ( #设置级别为28print (4,loga.geteffectivelevel ()) Loga.info (' after ') #loga. Warning (' after1 ') operation results: [2017-12-17 16:31:20] 4320629568 Before1 <logging. Rootlogger object at 0x104534f28> 43675359122 <logging. Logger object at 0x1044ef630> 4367250992 43675359123 304 28[2017-12-17 16:31:20] 4320629568 after1
Handler:
Handler control the output destination of the log information, which can be a console, a file.
Level can be set individually
Format can be set individually
You can set the filter
Handler
Streamhandler #不指定使用sys. Strerr
Filehandler #文件
_stderrhandler #标准输出
Nullhandler #什么都不做
The inheritance of level:
Import Loggingformat = "% (asctime) s% (thread) d% (message) S" Logging.basicconfig (Level=logging.info,format=format, Datefmt= "[%y-%m-%d%h:%m:%s]") root = Logging.getlogger () #根Logger级别为INFO 20print (' root: ', Root.geteffectivelevel ()) Log1 = Logging.getlogger (' s ') log1.setlevel (logging. ERROR) #级别为ERROR 40print (' log1: ', Log1.geteffectivelevel ()) log1.error (' log1 error ') log2 = Logging.getlogger (' s.s1 ') # Inherited from Log1 40, unable to use Warninglog2.setlevel (logging. WARNING) #设置为WARNING 30, you can use Warningprint (' log2: ', Log2.geteffectivelevel ()) log2.warning (' log2 WARNING ') to run the result: [ 2017-12-17 16:52:22] 4320629568 log1 errorroot:20log1:40[2017-12-17 16:52:22] 4320629568 log2 warninglog2:30
Logger instance, if level is set, it is compared with the levels of the information, otherwise, inherits the nearest ancestor.
Handler processing:
Import Loggingformat = "% (asctime) s% (thread) d% (message) S" Logging.basicconfig (Level=logging.info,format=format, Datefmt= "[%y-%m-%d%h:%m:%s]") root = Logging.getlogger () print (1,root.geteffectivelevel ()) #RootLogger, root Loggerlog1 = Logging.getlogger (' s ') print (2,log1.geteffectivelevel ()) H1 = logging. Filehandler (' Test.log ') h1.setlevel (logging. WARNING) Log1.addhandler (H1) print (3,log1.geteffectivelevel ()) log2 = Logging.getlogger (' s.s2 ') print (4, Log2.geteffectivelevel ()) H2 = logging. Filehandler (' Test1.log ') h2.setlevel (logging. WARNING) Log1.addhandler (H2) print (3,log1.geteffectivelevel ()) log2.warning (' log2 info---') Run Result: 1 20[2017-12-17 19:02:53] 7956 log2 Info---2 203 204 203 20
Test.log and Test1.log will eventually record a copy of "LOG2 info---"
Similarly, handler can also be set to use logging. Formatter () Set the format and Logging.filter () settings filter:
Import Loggingformat = "% (asctime) s% (thread) d% (message) S" Logging.basicconfig (Level=logging.info,format=format, Datefmt= "[%y-%m-%d%h:%m:%s]") root = Logging.getlogger () print (1,root.geteffectivelevel ()) #RootLogger, root Loggerlog1 = Logging.getlogger (' s ') #模块化用__module__, functional with __name__ as logger name, logger with the same name in memory also has only one print (2,log1.geteffectivelevel ()) H1 = logging. Filehandler (' Test.log ') h1.setlevel (logging. WARNING) FMT1 = logging. Formatter (' [% (asctime) s]% (thread) s% (threadname) s Log1-handler1% (message) s ') H1.setformatter (FMT1) # The formatted string Log1.addhandler (h1) Filter1 = logging of the personalization record is redefined. Filter (' s ') #过滤器 will record S, s.s2 information Log1.addfilter (filter1) print (3,log1.geteffectivelevel ()) log2 = Logging.getlogger (' S.s2 ') print (4,log2.geteffectivelevel ()) H2 = logging. Filehandler (' Test1.log ') h2.setlevel (logging. WARNING) Log1.addhandler (h2) Filter1 = logging. Filter (' S.s2 ') #过滤器不会记录s. S2 messages will only record their messages Log1.addfilter (filter1) print (3,log1.geteffectivelevel ()) log1.warning (' Log1 warning=== ') log2.warning (' log2 warning---') operation result: Test.log: #hanDler1 recorded the information of Log1 and log2 [2017-12-17 19:43:12,654] 5872 mainthread log1-handler1 log1 warning===[2017-12-17 19:43:12,654 ] 5872 mainthread log1-handler1 log2 Warning---test1.log: #handler2只记录了它自己的信息log2 warning---
Slag Map:
Summarize:
1. The level of each logger instance is like an inlet, let the water flow in, if the threshold is too high, the information will not come in
2. If the level is not set, use the parent logger, if the parent logger level is not set, continue to find the parent's parent, finally found root, if the root set to use it, if root is not set, the default value of root is warning
3. Generate some level of information on a logger, first and logger levels, if the message level is lower than Logger's EFFECTIVELEVL, the message is discarded and the message is no longer passed to the parent logger. If the pass (greater than equals) is checked, the message is given to logger all handler processing, each handler need to compare with their level to decide whether to deal with. If there is no handler, or the message has been handler processed, the message continues to be sent to the parent logger processing.
4. When the parent logger gets the message, it repeats the third process until the root logger
[Python Multithreading] Logging module, logger Class (eight)