Python输出日志

来源:互联网 发布:网络机顶盒能收多少台 编辑:程序博客网 时间:2024/06/06 09:01

https://docs.python.org/2/howto/logging-cookbook.html

import loggingif __name__ == '__main__':    # https://docs.python.org/2/howto/logging-cookbook.html    logger = logging.getLogger('eval_trec_cnn')    logger.setLevel(logging.INFO)    fh = logging.FileHandler('eval_trec_cnn.log')    fh.setLevel(logging.INFO)    ch = logging.StreamHandler()    ch.setLevel(logging.INFO)    formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')    fh.setFormatter(formatter)    ch.setFormatter(formatter)    logger.addHandler(fh)    logger.info('loading data...')    results = []    for i in range(1,10):        logger.info('try: {} test err: {}'.format(i, test_err))        results.append(test_err)    logger.info('final test err: {} std: {}'.format(np.mean(results),np.std(results)))   
In [7]: help(logging.getLogger)Help on function getLogger in module logging:

getLogger(name=None)

Return a logger with the specified name, creating it if necessary.If no name is specified, return the root logger.

In [14]: ? logging.FileHandler

  • Init signature: logging.FileHandler(self, filename, mode=’a’, encoding=None, delay=0)
  • Docstring: A handler class which writes formatted logging records to disk files.
  • Init docstring: Open the specified file and use it as the stream for logging.
  • File: c:\users\administrator\anaconda2\lib\logging__init__.py
    Type: type

In [15]: ? logging.StreamHandler
- Init signature: logging.StreamHandler(self, stream=None)
- Docstring:
A handler class which writes logging records, appropriately formatted,
to a stream. Note that this class does not close the stream, as
sys.stdout or sys.stderr may be used.
- Init docstring:
Initialize the handler.
If stream is not specified, sys.stderr is used.
- File: c:\users\administrator\anaconda2\lib\logging__init__.py
Type: type


>>> import logging>>> logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

In [6]: help(logging.basicConfig)

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 handlersconfigured. It is a convenience method intended for use by simple scriptsto do one-shot configuration of the logging package.The default behaviour is to create a StreamHandler which writes tosys.stderr, set a formatter using the BASIC_FORMAT format string, andadd the handler to the root logger.A number of optional keyword arguments may be specified, which can alterthe 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.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.Note that you could specify a stream created using open(filename, mode)rather than passing the filename and mode in. However, it should beremembered that StreamHandler does not close its stream (since it may beusing sys.stdout or sys.stderr), whereas FileHandler closes its streamwhen the handler is closed.

Multiple handlers and formatters

Loggers are plain Python objects. The addHandler() method has no minimum or maximum quota for the number of handlers you may add. Sometimes it will be beneficial for an application to log all messages of all severities to a text file while simultaneously logging errors or above to the console. To set this up, simply configure the appropriate handlers. The logging calls in the application code will remain unchanged. Here is a slight modification to the previous simple module-based configuration example:

import logginglogger = logging.getLogger('simple_example')logger.setLevel(logging.DEBUG)# create file handler which logs even debug messagesfh = logging.FileHandler('spam.log')fh.setLevel(logging.DEBUG)# create console handler with a higher log levelch = logging.StreamHandler()ch.setLevel(logging.ERROR)# create formatter and add it to the handlersformatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')ch.setFormatter(formatter)fh.setFormatter(formatter)# add the handlers to loggerlogger.addHandler(ch)logger.addHandler(fh)# 'application' codelogger.debug('debug message')logger.info('info message')logger.warn('warn message')logger.error('error message')logger.critical('critical message')

Notice that the ‘application’ code does not care about multiple handlers. All that changed was the addition and configuration of a new handler named fh.

The ability to create new handlers with higher- or lower-severity filters can be very helpful when writing and testing an application. Instead of using many print statements for debugging, use logger.debug: Unlike the print statements, which you will have to delete or comment out later, the logger.debug statements can remain intact in the source code and remain dormant until you need them again. At that time, the only change that needs to happen is to modify the severity level of the logger and/or handler to debug.

Logging to multiple destinations

Let’s say you want to log to console and file with different message formats and in differing circumstances. Say you want to log messages with levels of DEBUG and higher to file, and those messages at level INFO and higher to the console. Let’s also assume that the file should contain timestamps, but the console messages should not. Here’s how you can achieve this:

import logging# set up logging to file - see previous section for more detailslogging.basicConfig(level=logging.DEBUG,                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',                    datefmt='%m-%d %H:%M',                    filename='/temp/myapp.log',                    filemode='w')# define a Handler which writes INFO messages or higher to the sys.stderrconsole = logging.StreamHandler()console.setLevel(logging.INFO)# set a format which is simpler for console useformatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')# tell the handler to use this formatconsole.setFormatter(formatter)# add the handler to the root loggerlogging.getLogger('').addHandler(console)# Now, we can log to the root logger, or any other logger. First the root...logging.info('Jackdaws love my big sphinx of quartz.')# Now, define a couple of other loggers which might represent areas in your# application:logger1 = logging.getLogger('myapp.area1')logger2 = logging.getLogger('myapp.area2')logger1.debug('Quick zephyrs blow, vexing daft Jim.')logger1.info('How quickly daft jumping zebras vex.')logger2.warning('Jail zesty vixen who grabbed pay from quack.')logger2.error('The five boxing wizards jump quickly.')

When you run this, on the console you will see

root        : INFO     Jackdaws love my big sphinx of quartz.myapp.area1 : INFO     How quickly daft jumping zebras vex.myapp.area2 : WARNING  Jail zesty vixen who grabbed pay from quack.myapp.area2 : ERROR    The five boxing wizards jump quickly.

and in the file you will see something like

10-22 22:19 root         INFO     Jackdaws love my big sphinx of quartz.10-22 22:19 myapp.area1  DEBUG    Quick zephyrs blow, vexing daft Jim.10-22 22:19 myapp.area1  INFO     How quickly daft jumping zebras vex.10-22 22:19 myapp.area2  WARNING  Jail zesty vixen who grabbed pay from quack.10-22 22:19 myapp.area2  ERROR    The five boxing wizards jump quickly.

As you can see, the DEBUG message only shows up in the file. The other messages are sent to both destinations.

This example uses console and file handlers, but you can use any number and combination of handlers you choose.

0 0
原创粉丝点击