micropython logging文档
1.日志级别Level
日志记录级别的数值在下表中给出。日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET
我们设置了输出 level,系统便只会输出 level 数值大于或等于该 level 的的日志结果,例如我们设置了输出日志 level 为 INFO,那么输出级别大于等于 INFO 的日志,如 WARNING、ERROR 等,DEBUG 和 NOSET 级别的不会输出。默认的输出level为INFO。
级别 |
数值 |
---|---|
|
50 |
|
40 |
|
30 |
|
20 |
|
10 |
|
0 |
2.logging.basicConfig函数:
通过logging.basicConfig函数对日志的输出格式及方式做相关配置
def basicConfig(level=INFO, filename=None, stream=None, format=None, style="%"): global _level _level = level if filename: h = FileHandler(filename) else: h = StreamHandler(stream) h.setFormatter(Formatter(format, style=style)) root.handlers.clear() root.addHandler(h)
logging.basicConfig函数各参数:
level: 设置日志级别,默认为logging.WARNING
filename: 指定日志文件名
format: 指定输出的格式和内容 ,
%(asctime)s: 打印日志的时间
%(message)s: 打印日志信息
3.记录器(Logger)
Logger:即 Logger Main Class,是我们进行日志记录时创建的对象
如果没有显式的进行创建,则默认创建一个root logger,并应用默认的日志级别(WARN),处理器Handler(StreamHandler,即将日志信息打印输出在标准输出上),和格式化器Formatter(默认的格式%(message)s)。
创建方法:logger = logging.getLogger()
def getLogger(name=None): if name is None: name = "root" if name in _loggers: return _loggers[name] if name == "root": l = Logger(name) sh = StreamHandler() sh.formatter = Formatter() l.addHandler(sh) else: l = Logger(name) _loggers[name] = l return l
创建Logger实例后,可以使用以下方法进行日志级别设置,增加处理器Handler。
- logger.setLevel(logging.ERROR) # 设置日志级别为ERROR,即只有日志级别大于等于ERROR的日志才会输出
- logger.addHandler(handler_name) # 为Logger实例增加一个处理器
4.处理器(Handler)
处理器将日志记录发送给其他输出终端,他们获取日志记录并用相关函数中处理它们。
比如,一个文件处理器将会获取一条日志记录,并且把它添加到文件中。
本logging 模块提供的 Handler 有:
- StreamHandler:logging.StreamHandler;日志输出到流,可以是 sys.stderr,sys.stdout 。
- FileHandler:logging.FileHandler;日志输出到文件。
StreamHandler创建方法:sh = logging.StreamHandler()
class StreamHandler(Handler): def __init__(self, stream=None): self._stream = stream or sys.stderr self.terminator = "\n" self.formatter = Formatter() def emit(self, record): self._stream.write(self.formatter.format(record) + self.terminator) def flush(self): pass
FileHandler创建方法:fh = logging.FileHandler(filename)
class FileHandler(Handler): def __init__(self, filename, mode="a", encoding=None, delay=False): super().__init__() self.encoding = encoding self.mode = mode self.delay = delay self.terminator = "\n" self.filename = filename self._f = None def emit(self, record): self._f = open(self.filename, self.mode) self._f.write(self.formatter.format(record) + self.terminator) def close(self): if self._f is not None: self._f.close()
创建完fh/sh后,可以给它设置一个格式化器Formatter
class Handler: def __init__(self): self.formatter = Formatter() def setFormatter(self, fmt): self.formatter = fmt
5.格式化器(Formatter)
使用Formatter对象设置日志信息最后的规则、结构和内容
formatter创建方法: formatter = logging.Formatter(fmt="%(asctime)s:%(massage)s", datefmt=None)
其中,fmt是消息的格式化字符串,datefmt是日期字符串,但本logging模块不支持。如果不指明fmt,将使用'%(message)s'。
class Formatter: converter = utime.localtime def __init__(self, fmt=None, datefmt=None, style="%"): self.fmt = fmt or "%(message)s" self.datefmt = datefmt if style not in ("%", "{"): raise ValueError("Style must be one of: %, {") self.style = style def usesTime(self): if self.style == "%": return "%(asctime)" in self.fmt elif self.style == "{": return "{asctime" in self.fmt def format(self, record): # The message attribute of the record is computed using msg % args. record.message = record.msg % record.args # If the formatting string contains '(asctime)', formatTime() is called to # format the event time. if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) # If there is exception information, it is formatted using formatException() # and appended to the message. The formatted exception information is cached # in attribute exc_text. if record.exc_info is not None: record.exc_text += self.formatException(record.exc_info) record.message += "\n" + record.exc_text # The record’s attribute dictionary is used as the operand to a string # formatting operation. if self.style == "%": return self.fmt % record.__dict__ elif self.style == "{": return self.fmt.format(**record.__dict__) else: raise ValueError( "Style {0} is not supported by logging.".format(self.style) ) def formatTime(self, record, datefmt=None): assert datefmt is None # datefmt is not supported ct = utime.localtime(record.created) return "{0}-{1}-{2} {3}:{4}:{5}".format(*ct) def formatException(self, exc_info): raise NotImplementedError() def formatStack(self, stack_info): raise NotImplementedError()
6.简单使用:
import logging logging.debug('debug message') logging.info('info message') logging.warning('warn message') logging.error('error message') logging.critical('critical message')
输出:
info message
warn message
error message
critical message
7.简单配置:
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s : %(message)s') logging.debug('debug message')
输出:
2019-6-18 16:49:10 : debug message
8.记录日志到文件
import logging logging.basicConfig(level=logging.DEBUG,filename='/flash/logger.log',format='%(asctime)s : %(message)s') logging.debug('debug message should go to the log file') logging.info('info message should go to the log file') logging.warning('warn message should go to the log file') logging.error('error message should go to the log file') logging.critical('critical message should go to the log file')
logger.log文件会写入如下内容:
2019-6-18 17:2:20 : debug message should go to the log file 2019-6-18 17:2:25 : info message should go to the log file 2019-6-18 17:2:29 : warn message should go to the log file 2019-6-18 17:2:34 : error message should go to the log file 2019-6-18 17:2:39 : critical message should go to the log file
9.把日志同时输出到标准输出和日志文件:
import logging logger=logging.getLogger() fh = logging.FileHandler('a.log') formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) logger.setLevel(level = logging.DEBUG) logger.addHandler(fh) logger.debug('debug message') logger.info('info message')
标准输出:
info message
a.log文件中的内容:
2019-6-18 19:11:22 - root - DEBUG - debug message
2019-6-18 19:11:22 - root - INFO - info message