Learn python with socratica [My notes] - part 15- Logging

Lesson 17

Introduction

logging means is recorded, it is a way of generating logs. The program is running, logging module can record everything [needed] record. This is important for developers, is a good program knows where the wrong directly know what happened.

Functions

logging important information to help programmers write to a file or other forms of output, more information is a matter of the operative part of the code and the code. Each has a logging level, it built a total of five levels, including: Debug, Info, Warning, Error, critical. Developers can also create their own new level.

  	import logging
    dir(logging)

	output:
    ['BASIC_FORMAT',
     'BufferingFormatter',
     'CRITICAL',
     'DEBUG',
     'ERROR',
     'FATAL',
     'FileHandler',
     'Filter',
     'Filterer',
     'Formatter',
     'Handler',
     'INFO',
     'LogRecord',
     'Logger',
     'LoggerAdapter',
     'Manager',
     'NOTSET',
     'NullHandler',
     'PercentStyle',
     'PlaceHolder',
     'RootLogger',
     'StrFormatStyle',
     'StreamHandler',
     'StringTemplateStyle',
     'Template',
     'WARN',
     'WARNING',
     '_STYLES',
     '_StderrHandler',
     '__all__',
     '__author__',
     '__builtins__',
     '__cached__',
     '__date__',
     '__doc__',
     '__file__',
     '__loader__',
     '__name__',
     '__package__',
     '__path__',
     '__spec__',
     '__status__',
     '__version__',
     '_acquireLock',
     '_addHandlerRef',
     '_checkLevel',
     '_defaultFormatter',
     '_defaultLastResort',
     '_handlerList',
     '_handlers',
     '_levelToName',
     '_lock',
     '_logRecordFactory',
     '_loggerClass',
     '_nameToLevel',
     '_releaseLock',
     '_removeHandlerRef',
     '_showwarning',
     '_srcfile',
     '_startTime',
     '_warnings_showwarning',
     'addLevelName',
     'atexit',
     'basicConfig',
     'captureWarnings',
     'collections',
     'critical',
     'currentframe',
     'debug',
     'disable',
     'error',
     'exception',
     'fatal',
     'getLevelName',
     'getLogRecordFactory',
     'getLogger',
     'getLoggerClass',
     'handlers',
     'info',
     'io',
     'lastResort',
     'log',
     'logMultiprocessing',
     'logProcesses',
     'logThreads',
     'makeLogRecord',
     'os',
     'raiseExceptions',
     'root',
     'setLogRecordFactory',
     'setLoggerClass',
     'shutdown',
     'sys',
     'threading',
     'time',
     'traceback',
     'warn',
     'warning',
     'warnings',
     'weakref']

logging function is quite complex, this class mainly in the basic log-based, other forms sprout new needs their own experiments.

  	import logging
    help(logging.basicConfig)
	
	output:
    Help on function basicConfig in module logging:
    
    basicConfig(**kwargs)
        Do basic configuration for the logging system.
        
        This function does nothing if the root logger already has handlers
        configured. It is a convenience method intended for use by simple scripts
        to do one-shot configuration of the logging package.
        
        The default behaviour is to create a StreamHandler which writes to
        sys.stderr, set a formatter using the BASIC_FORMAT format string, and
        add the handler to the root logger.
        
        A number of optional keyword arguments may be specified, which can alter
        the default behaviour.
        
        filename  Specifies that a FileHandler be created, using the specified
                  filename, rather than a StreamHandler.
        filemode  Specifies the mode to open the file, if filename is specified
                  (if filemode is unspecified, it defaults to 'a').
        format    Use the specified format string for the handler.
        datefmt   Use the specified date/time format.
        style     If a format string is specified, use this to specify the
                  type of format string (possible values '%', '{', '$', for
                  %-formatting, :meth:`str.format` and :class:`string.Template`
                  - defaults to '%').
        level     Set the root logger level to the specified level.
        stream    Use the specified stream to initialize the StreamHandler. Note
                  that this argument is incompatible with 'filename' - if both
                  are present, 'stream' is ignored.
        handlers  If specified, this should be an iterable of already created
                  handlers, which will be added to the root handler. Any handler
                  in the list which does not have a formatter assigned will be
                  assigned the formatter created in this function.
        
        Note that you could specify a stream created using open(filename, mode)
        rather than passing the filename and mode in. However, it should be
        remembered that StreamHandler does not close its stream (since it may be
        using sys.stdout or sys.stderr), whereas FileHandler closes its stream
        when the handler is closed.
        
        .. versionchanged:: 3.2
           Added the ``style`` parameter.
        
        .. versionchanged:: 3.3
           Added the ``handlers`` parameter. A ``ValueError`` is now thrown for
           incompatible arguments (e.g. ``handlers`` specified together with
           ``filename``/``filemode``, or ``filename``/``filemode`` specified
           together with ``stream``, or ``handlers`` specified together with
           ``stream``.



    import logging
    logging.basicConfig(filename="./log.out")
    logger = logging.getLogger()
    
    logger.info("first")
    print(logger.level)
	
	output:
    30


Here will generate a log file in the current directory, 30 represents what? In the hierarchy of logging in, divided into: NOTSET-0, DEBUG-10, INFO-20, WARNING-30, ERROR-40, CRITICAL-50.30 represents the current log level is basicConfig default WARNING. At this point, we make a change:

	import logging
    logging.basicConfig(filename="./log.out",
                       level = logging.DEBUG)
    logger = logging.getLogger()
    
    logger.info("first")
    print(logger.level)

	output:
    10

Here, in theory, it will print out 10, but the wrong time being no cause. If you open log.out, reads as follows: INFO: root: First .

New Format

According to rewrite the log format to their needs, python module provides a lot of information, for example:

 	import logging
    LOG_FORMAT="%(levelname) %(asctime)s - %(massage)s"
    logging.basicConfig(filename="./log.out",
                       level = logging.DEBUG,
                       format = LOG_FORMAT)
    logger = logging.getLogger()
    
    logger.info("first")

If you open the log, you will find more than a line of new log, the format will be changed to: INFO YMD HMS-MS - First . If you want every time to rewrite the log, you need to add the fileMode :

   import logging
   LOG_FORMAT="%(levelname) %(asctime)s - %(massage)s"
   logging.basicConfig(filename="./log.out",
                      level = logging.DEBUG,
                      format = LOG_FORMAT,
                      filemode = 'w')
   logger = logging.getLogger()
   
   logger.info("second")

At this point the output log only the second line. Here also we need to note that the only message will be above the current level is written to the log:

   import logging
   LOG_FORMAT="%(levelname) %(asctime)s - %(massage)s"
   logging.basicConfig(filename="./log.out",
                      level = logging.DEBUG,
                      format = LOG_FORMAT,
                      filemode = 'w')
   logger = logging.getLogger()
   
   # Test Massages
   logger.debug("This is a harmless debug message.")
   logger.info("Just some useful info.")
   logger.warning("Warning!")
   logger.error("Did you just try to divide by zero?")
   logger.critical("The entire internet is down!")

After running all the massage will appear in the log. But if the level basicConfig into ERROR, then there is after the last two.

Example

How to use the log to better debugging code does:

    import logging
    import math
    
    LOG_FORMAT="%(levelname) %(asctime)s - %(massage)s"
    logging.basicConfig(filename="./mathlog.out",
                       level = logging.DEBUG,
                       format = LOG_FORMAT,
                       filemode = 'w')
    logger = logging.getLogger()
    
    def quadratic_formula(a,b,c):
        """Return the solutions to the equation ax^2 + bx + c = 0."""
        logger.info("quafratic_formula({0},{1},{2})".format(a,b,c))
        
        # compute the discriminant
        logger.debug("# Compute the discriminant")
        disc = b**2 - 4*a*c
        
        # compute the two roots
        logger.debug("# Compute the two roots")
        root1 = (-b + math.sqrt(disc)) / (2*a)
        root2 = (-b - math.sqrt(disc)) / (2*a)
        
        # Return the roots
        logger.debug("# Return the roots")
        return (root1, root2)
    
    roots = quadratic_formula(1,0,-4)
    print(roots)
    
	output:
    (2.0, -2.0)

If you open the log file, a total of four lines:

  • INFO
  • DEBUG- # Compute the discriminant
  • DEBUG- # Compute the two roots
  • DEBUG- # return the roots

Here is an example of error:

   	import logging
    import math
    
    LOG_FORMAT="%(levelname) %(asctime)s - %(massage)s"
    logging.basicConfig(filename="./mathlog.out",
                       level = logging.DEBUG,
                       format = LOG_FORMAT,
                       filemode = 'w')
    logger = logging.getLogger()
    
    def quadratic_formula(a,b,c):
        """Return the solutions to the equation ax^2 + bx + c = 0."""
        logger.info("quafratic_formula({0},{1},{2})".format(a,b,c))
        
        # compute the discriminant
        logger.debug("# Compute the discriminant")
        disc = b**2 - 4*a*c
        
        # compute the two roots
        logger.debug("# Compute the two roots")
        root1 = (-b + math.sqrt(disc)) / (2*a)
        root2 = (-b - math.sqrt(disc)) / (2*a)
        
        # Return the roots
        logger.debug("# Return the roots")
        return (root1, root2)
    
    # error: c=-4 -> c=1
    roots = quadratic_formula(1,0,1)
    print(roots)
	
	output:
    ---------------------------------------------------------------------------
    
    ValueError                                Traceback (most recent call last)
    
    <ipython-input-15-d0549ea89a68> in <module>()
         27 
         28 # error: c=-4 -> c=1
    ---> 29 roots = quadratic_formula(1,0,1)
         30 print(roots)

    <ipython-input-15-d0549ea89a68> in quadratic_formula(a, b, c)
         19     # compute the two roots
         20     logger.debug("# Compute the two roots")
    ---> 21     root1 = (-b + math.sqrt(disc)) / (2*a)
         22     root2 = (-b - math.sqrt(disc)) / (2*a)
         23 

    ValueError: math domain error

Error, so as the root can not be negative, so that the calculation error to math.sqrt. If you open the log file at this time, you can find a total of three lines:

  • INFO
  • DEBUG- # Compute the discriminant
  • DEBUG- # Compute the two roots

The last line is the wrong place, which is the way we usually DEBUG time. Add logging code to better identify the mistake, you can also improve the readability of the code.

Youtube source:
https://www.youtube.com/watch?v=bY6m6_IIN94&list=PLi01XoE8jYohWFPpC17Z-wWhPOSuh8Er-

Guess you like

Origin blog.csdn.net/sinat_34611224/article/details/93009348