Using the Python script log feature

Source: Internet
Author: User
Suppose you want to develop an automated scripting tool, the engineering structure is as follows, CommonThis one packageis the implementation of the framework function, ScriptsThe catalog is a test case script that we write (please ignore other unrelated directories).

Our requirements for the logging feature are as follows:

1 in order to facilitate the view of the log, each script corresponds to a log file, the log file is named after the name of the script

2nd log path and the journal capacity saved per script can be set, such as set to 5MB, then the oldest log is automatically overwritten

3rd log function to be easy to use, reduce the coupling with the framework business functions

  

Now, let's analyze each of these requirements individually.

  1 To implement a log file for each script , you need to generate a log file in the log module, based on the name of the use case script, the key question here is how to get the name of the use case script in the log module.

A common way to get filenames is os.getcwd() to sys.argv[0], __file__, look at the various effects:

First write the following code in a file (suppose test.py ):

  

Then in another file (assumed script1.py ) import test , then call the func method:

  

Run script1.py , the result is:

  

Visible is the os.getcwd() directory that executes the script, the sys.argv[0] absolute path name of the execution script, and the __file__ absolute pathname of the file where the code is executed.

Now it's clear that we should use it sys.argv[0] to get the name of the execution script, because getting an absolute path requires a bit of processing:sys.argv[0].split('/')[-1].split('.')[0]

  2nd Log capacity Problem , to achieve more than capacity to automatically overwrite the oldest logs, logging in the RotatingFileHandler class can be set to the size of the log file, as well as the number of backups.

So where does the log path and capacity configuration fit? Let the user directly modify RotatingFileHandler the parameters obviously not good, it is best not to let the user modify the framework file, the user simply call the interface to write their own script.

The scenario used here is to write the configuration information to a file that the XML file is more appropriate to use as a configuration file, the user modifies the XML file to make the configuration, and the log module reads the parameters from the XML file.

Here for the convenience of putting the XML file Common below, named config.xml , the content is:

<?xml version= "1.0" encoding= "Utf-8"?><config>  <!--log save path--  <logpath>e:\ Pythonlog</logpath>  <!--the log file size for each script, in megabytes---  <logsize>8</logsize>  <!-- Number of log files saved per script-  <lognum>3</lognum></config>

To read the contents of an XML file, it lxml is very simple to use the library, followed by the code.

  

  3rd log function to be easy to use , reduce the coupling with the framework business functions, it is best to encapsulate the logging function, only provide logging interface.

Log interface in the form of a class method can meet the above requirements, the user only need to call through the class logging interface, anywhere call, easy to use, and no need to define class instances, and framework business is not coupled.

With the above analysis, we will implement the log module.

Because the log function is also part of the Framework Foundation, we put the log module in Common this package , Common under the new log.py file, the code is as follows:

# coding:utf-8from lxml import etreeimport logging.handlersimport loggingimport osimport sys# provides logging function class logger: # Read X First The configuration data in the ML file # because CONFIG. xml is placed in the same directory as the current file, so __file__ to get the directory of the file and then stitching it into an absolute path # Here we use the lxml library to parse the XML root = Etree.parse (os.p Ath.join (Os.path.dirname (__file__), ' config. * '). Getroot () # Read the log file save path LogPath = Root.find (' LogPath '). Text # Read log file Capacity, converted to bytes logsize = 1024*1024*int (Root.find (' logsize '). Text) # read log file save number lognum = Int (root.find (' Lognum '). Text) # log file Name: The absolute path of the log file is obtained by the names of the use case script, combined with the log save path logname = Os.path.join (LogPath, Sys.argv[0].split ('/') [ -1].split ('. ') [0]) # Initialize Logger log = Logging.getlogger () # Log format, you can set FMT = logging as needed. Formatter (' [% (asctime) s][% (filename) s][line:% (Lineno) d][% (levelname) s]% (message) s ', '%y-%m-%d%h:%m:%s ') # Log output to file , here used to get the above log name, size, save number Handle1 = Logging.handlers.RotatingFileHandler (logname, Maxbytes=logsize, backupcount= Lognum) Handle1.setformatter (FMT) # Output to the screen at the same time for easy implementation observation Handle2 = logging. Streamhandler (stream=sys.stdout) HAndle2.setformatter (FMT) Log.addhandler (handle1) Log.addhandler (handle2) # Set the log basic, here is set to info, indicating that only the info level and above will print Log.setlevel (logging.info) # Log interface, the user only need to call the interface here, here only the information, WARNING, error three levels of log, you can define more interfaces as needed @classmethod def INFO ( CLS, msg): Cls.log.info (msg) return @classmethod def warning (CLS, msg): Cls.log.warning (msg) return @classm Ethod def error (CLS, msg): Cls.log.error (msg) return

To test it, write the script1 script2 following code separately in the script and:

From Common.log import *logger.info ("This is Info") logger.warning (' This was warning ') Logger.error (' This is the error ')

Run two scripts separately, console output is:

  

The resulting log file:

  

File contents:

  

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.