Python的标准logging模块
Python 2.3 introduced thelogging module to the Python standard library. logging provides a standard interface for outputting information from a running application. The classic example of a logging mechanism is writing data to a text file, which is a plain old log file. While the log file is likely the most common form of logging, the logging module provides the ability to send information to file-like objects, TCP and UDP sockets, email servers, the Unix syslog, the NT event log, memory buffers, and HTTP servers in addition to "real" files.
从Python2.3起,Python的标准库加入了logging模块.logging模块给运行中的应用提供了一个标准的信息输出接口.logging机制的一个典型实现就是把数据写到一个简单的log文件(txt文件),而这个log文件的格式可以由logging模块来定义.logging模块支持把message输出到类文件对象,TCP和UDPsockets,email服务器,Unix的syslog系统,NT系列的enent log系统,缓存,HTTP服务器,当然还包括”真正的”文件.
The logging library takes a modular approach and offers the several categories of components: loggers, handlers, filters, and formatters. Loggers expose the interface that application code directly uses. Handlers send the log records to the appropriate destination. Filters provide a finer grained facility for determining which log records to send on to a handler. Formatters specify the layout of the resultant log record.
Logging库采用模块的访问方式,它提供了以下组件:loggers,handlers,filters和formatters.Loggers直接生成一个应用对象.Handlers把log记录发到相应的目的地.Filters选择需要send到handler的message.Formatters定义了log记录的输出格式.
Loggers
Logger objects have a threefold job. First, they expose several methods to application code so that applications can log messages at runtime. Second, logger objects determine which log messages to act upon based upon severity (the default filtering facility) or filter objects. Third, logger objects pass along relevant log messages to all interested log handlers.
Logger对象扮演了三重角色.首先,它提供多种机制给应用程序使其能够在运行时记录log message.其次,Logger对象根据log信息的不同等级(filter 的默认方式)来选择如何输出og信息.最后,logger对象将处理后log信息传送给相关的loghandlers.
The most widely used methods on logger objects fall into two categories: configuration and message sending.
Logger对象中中最常使用的两种方法:configuration和message sending.
The configuration methods are:
用于Configuration的方法:
setLevel() specifies the lowest-severity log message a logger will handle, where debug is the lowest built-in severity level and critical is the highest built-in severity. For example, if the severity level is info, the logger will handle only info, warning, error, and critical messages and will ignore debug messages.
addFilter() and removeFilter() add and remove filter objects from the logger object. This article does not address filters.
setLevel()方法用来定义一个logger对象中message的严重级别(比如说中/高/底三种,我定义为中,那么只有严重程度为中或者高的log才会被处理).debug级别是内置的最低级别,critical是最高级别.举例来说,如果严重级别设为info级,logger仅仅处理info,warning,error和critical级的log,而debug级别的则会被忽略掉.addFilter() 和 removeFilter() 用来添加/移除logger对象中的filter对象。
With the logger object configured, the following methods create log messages:
根据logger对象的设置,以下的方法都可以用来生成log信息:
debug(), info(), warning(), error(), and critical() all create log records with a message of log_message and a level that corresponds to their respective method names. log_message is actually a format string, which may contain the standard string substitution syntax of %s, %d, %f, and so on. *args is a list of objects that correspond with the substitution fields in log_message. With regard to **kwargs, the logging methods care only about a keyword of exc_info and use it to determine whether to log exception information.
debug(),info(),warning(),error()和critical()将log_message参数所带的message和与之相对应的严重程度生成log信息.log_message实际上是一个格式字符串,它可以包含诸如%s,%d,%f此类的替换符号.*args是实际要替换log_message中%s,%d,%f参数的列表.关于**kwargs参数,logging只关注exc_info,用来选择是否输出 log exception information。
exception() creates a log message similar to error(). The difference is that exception() dumps a stack trace along with it. Call this method only from an exception handler.
exception()跟error()很相似.不同之处是exception()存储了stack 的trace信息.exception()只能通过exception handler调用.
log() takes a log level as an explicit argument. This is a little more verbose for logging messages than using the log level convenience methods listed above, but this is how to log at custom log levels.
Log()以一个详尽的参数来设置level,相比上面所列举的方法有能为详细的log信息,这属于自定义log信息的范畴了.
logging.getLogger([name]) returns a reference to a logger instance with a name of name if a name is provided, or root if not. The names are period-separated (.) hierarchical structures. Multiple calls to logging.getLogger() with the same name will return a reference to the same logger object. Loggers that are further down in the hierarchical list are children of loggers higher up in the list. For example, given a logger with a name of foo, loggers with names of foo.bar, foo.bar.baz, and foo.bam are all children of foo. Child loggers propagate messages up to their parent loggers. Because of this, it is unnecessary to define and configure all the loggers an application uses. It is sufficient to configure a top-level logger and create child loggers as needed.
Logging.getLogger([name])方法返回一个logger实例的引用,如果name参数给出,则用这个参数的值作为名字,如果没有则用root做默认值.名字是以点号分割的命名方式命名的(a.b.c).对同一个名字的多个调用logging.getLogger()方法会返回同一个logger对象.这种命名方式里面,后面的loggers是前面logger的子.比如说,有一个名字是foo的logger,那么诸如foo.bar,foo.bar.baz和foo.bam这样的logger都是foo这个logger的子,子loggers自动继承父loggers的log信息,正因为此,没有必要把一个应用的所有logger都配置一边,只要把顶层的logger配置好了,然后子logger根据需要继承就行了.
Handlers
Handler objects are responsible for dispatching the appropriate log messages (based on the log messages' severity) to the handler's specified destination. Logger objects can add zero or more handler objects to themselves with an addHandler() method. As an example scenario, an application may want to send all log messages to a log file, all log messages of error or higher to stdout, and all messages of critical to an email address. This scenario requires three individual handlers where each hander is responsible for sending messages of a specific severity to a specific location.
Handler对象负责分配合适的log信息(基于log信息的严重程度)到handler指定的目的地.Logger对象可以用addHandler()方法添加零个或多个handler对象到它自身.一个常见的场景是,一个应用可能希望把所有的log信息都发送到一个log文件中去,所有的error级别以上的log信息都发送到stdout,所有critical的log信息通过email发送.这个场景里要求三个不同handler处理,每个handler负责把特定的log信息发送到特定的地方.
The standard library includes the following handlers:
标准库里面包括以下的handlers:
This article uses only StreamHandler and FileHandler in its examples.
本文里面只用到了StreamHandler和FileHandler
There are very few methods in a handler for application developers to concern themselves with. The only handler methods that seem relevant for application developers who are using the built-in handler objects (that is, not creating custom handlers) are the following configuration methods:
Handler里面提供给应用开发者的只有很少的几个方法可用.对使用内置的handler(就是说不是自定义的handlers)的开发者可用的配置方法如下:
The setLevel() method, just as in logger objects, specifies the lowest severity that will be dispatched to the appropriate destination. Why are there two setLevel() methods? The level set in the logger determines which severity of messages it will pass to its handlers. The level set in each handler determines which messages that handler will send on. setFormatter() selects a Formatter object for this handler to use. addFilter() and removeFilter() respectively configure and deconfigure filter objects on handlers.
setLevel()方法跟logger对象里面的setLevel()一样,也是用于设定一个最低分发log信息的级别.为什么有两个setLevel()呢?logger的严重等级用于决定那个级别的log信息可以分发到它的handlers.handler里面的level设置用于控制那些个log信息是handler需要转寄的.setFormatter()方法选定一个格式化对象给它自己用.addFilter()和removeFilter()分别用于为handler增加一个filter和删除一个filter.
Application code should not directly instantiate and use handlers. Instead, the logging.Handler class is a base class that defines the interface that all Handlers should have and establishes some default behavior that child classes can use (or override).
应用里面Handler不应该被直接实例化.相反,应该用logging.Handler类作所有Handlers的基类,在它里面定义所有自Handler用到的接口并且创建一些默认的方法让子类来用(或者继承).