Recent tasks often involve log records, and have been deliberately logging to learn how to record them again. Like Java, Python's logging is a tedious thing, writing a lot of things before writing a record. The procedure for typical logging is this:
- Create Logger
- Create Handler
- Define Formatter
- Add formatter to Handler
- Add handler to Logger
The code is almost the same as the sauce (this is copied according to other pages, reference notes):
1ImportLogging23#1. Create a Logger4 Logger = Logging.getlogger (‘MyLogger‘)5Logger.setlevel (logging. DEBUG)67#2. Create a handler to write to the log file8 fh = logging. Filehandler (‘Test.log‘)9Fh.setlevel (logging. DEBUG)1011#Create another handler for output to the consoleCH =Logging. Streamhandler ()13Ch.setlevel (logging. DEBUG)1415#3. Define the output format of the handler (formatter)16 formatter = logging. Formatter ( ' % (asctime) s-% (name) s-% (levelname) s-% ( Message) S ' ) 17 18 # 4, add handler Formatter19 fh.setformatter (formatter) 20 ch.setformatter (formatter) 21 22 # 5, add logger handler 23 Span style= "COLOR: #000000" >logger.addhandler (FH) 24 logger.addhandler (CH)
Before you can formally start logging. The same is true of the Java.util.Logging class in Java, where the code is a bit more complicated. Golang's log is relatively simple, but there is no format, the system records a time, the content format completely their own hand-drawn. Third-party log library is not touched, like Java Log4j,golang Log4go and Seelog, and so on, do not know whether it will be simpler to use. I can't remember this all the time because I don't quite understand why logger and handler write like this. Until this task appeared in my view is quite "strange" bug, only in-depth understanding of a bit.
My task is this, to do a log cutting tool, by day to split the log open, that is, 0 points a day to generate a new log, the old log renamed. Also, delete the log for more than 3 months to ensure that the disk space is not filled with log. The program requires that you can cut different logs in multiple directories, and the specific path is configured in JSON.
The Timedrotatingfilehandler method in the Logging.handlers class is used to obtain a handler. The approximate wording is:
1 logger = Logging.getlogger ()#Get Logger2 handler = Logging.handlers.TimedRotatingFileHandler (logfile, "s", 1, 0) # cut log 3 handler.suffix = ' %y%m%d" post-cut log settings suffix 4 Logger.addhandler (handler) # add logger on Handler5 logger.fatal ( Datetime.datetime.now (). Strftime ( ' %y-%m-%d# is written in the new journal
I'm not setting level and formatter here. Because it is only split, it has no effect on the new log. Timedrotatingfilehandler the method of the function see the note, or look at the Python source code, this function is written in Python, you can find the definition. Here I am using a new log file generated per second, then dispatched with crontab at 0 o ' Day, then using a for loop to process each log file in the JSON.
But strangely, each time the program is run, the first cut log generates a split file, and the next one generates two new logs. The solution is not to be baffled. After checking the code that may be set in the program time is too short, generate a file per second, it is possible that a second processing can not finish, generated two. Although there is no scientific basis for this argument, the third parameter in Timedrotatingfilehandler is changed to 60, which generates a file every 60 seconds. Complete, quietly waiting for crontab to time.
Bite! Time to. Check the results quickly. A good news and a bad news. The good news is that this time each log is only cut to generate a new file, without generating two. The bad news is that the number of days that are added to each file is the ghost of the day. I cut 4 logs, the resulting new log is written in one or two, three or four lines of the day date.
At the moment my heart is almost broken. I began to wonder why. It is clear that the four-line date is called 4 times logger.fatal (' Datetime.datetime.now (). Strftime ('%y-%m-%d ')) this function. In other words, I wrote a sentence in this log every time for the for loop. But clearly each for is to handle a log, the next time for should be processing the next log, why would you process the log again? It occurred to me that Logger.addhandler (handler) would run every cycle, that is, logger was the same logger, adding 4 handler. By the 4th cycle, there are 4 handler in this logger, and it will add content to 4 different logs. Uh.
If this is the case, then the above procedure is changed, the first sentence and the last sentence in the loop outside, the loop only with the middle of the three sentences. OK, this time. Looking back at the log record of the steps, also understand what logger and handler is a ghost:logger can be seen as a log, for each log recorded, he needs a set of rules, such as the format of the record (formatter), Rank (level) and so on, this rule is handler. By using Logger.addhandler (handler) to add multiple rules, you can have one logger record multiple logs. As for the Logging.getlogger () method to obtain the root logger and inheritance relationship, you can see the note of the page, here I just probably understand what the meaning, has not been specifically used. It may be used in the future in the framework, and it will be used to record more complex logs.
What the hell is logger and handler in Python?