python logging配置
python中,logging由logger,handler,filter,formater四个部分组成。
logger是提供我们记录日志的方法;
handler是让我们选择日志的输出地方,如:控制台,文件,邮件发送等,一个logger添加多个handler;
filter是给用户提供更加细粒度的控制日志的输出内容;
formater用户格式化输出日志的信息。
python中配置logging有三种方式
第一种:基础配置,logging.basicConfig(filename="config.log",filemode="w",format="%(asctime)s-%(name)s-%(levelname)s-%(message)s",level=logging.INFO)。
第二种:使用配置文件的方式配置logging,使用fileConfig(filename,defaults=None,disable_existing_loggers=Ture )函数来读取配置文件。
第三种:使用一个字典方式来写配置信息,然后使用dictConfig(dict,defaults=None, disable_existing_loggers=Ture )函数来瓦按成logging的配置.
在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有
filename: 用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
filemode: 文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format: 指定handler使用的日志显示格式。
datefmt: 指定日期时间格式。
level: 设置rootlogger(后边会讲解具体概念)的日志级别
stream: 用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。
若同时列出了filename和stream两个参数,则stream参数会被忽略。
format参数中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s 用户输出的消息
日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET
propagete参数 :propagete=0,表示输出日志,但消息不传递;propagate=1是输出日志,同时消息往更高级别的地方传递。root为最高级别。
TimedRotatingFileHandler: 创建固定时间间隔的日志,它被集成在 logging 中,直接调用进行实例化和配置就可以使用
TimedRotatingFileHandler 的构造函数为:TimedRotatingFileHandler( filename [, when [, interval [, backupCount] ] ] )
参数解释:
filename 是输出日志的文件名称前缀,比如说 testServiceLog 这样的就是日志文件名前缀
when 是一个字符串,定义了日志切分的间隔时间单位,这是一个枚举类,可选参数如下:
"S":Second 秒
"M":Minutes 分钟
"H":Hour 小时
"D":Days 天
"W":Week day(0 = Monday)
"midnight":Roll over at midnight
interval 是间隔时间单位的个数,指等待多少个 when 的时间后 Logger 会自动重建新闻继续进行日志记录
这里需要注意的一点是,如果创建的文件和已有文件存在重名的情况,则会对历史的文件进行覆盖操作,所以使用好 suffix 避免文件名称重复
backupCount 是保留日志的文件个数
默认的参数是0,这种设置下是不会自动删除文件的。如果设置为 N(正整数),则会在创建新的日志文件时会检查日志文件个数是否到达 N,达到了的话就会从最先创建的开始删除,从而达到维持日志文件个数为 N 个的目标
logging 配置文件代码实例:
def init_log(service_name): """ 进行 logger 配置 :return: """ # 日志基础路径 log_path = r"D:\RE_service" # 服务 日志路径 service_log_path = os.path.join(log_path, service_name) # info 日志路径 service_info_log_path = os.path.join(service_log_path, 'info', 'info') # error 日志路径 service_error_log_path = os.path.join(service_log_path, 'error', 'error') standard_format = "%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(levelname)s]- %(message)s" # 创建路径 if not os.path.exists(log_path): os.makedirs(log_path, mode=0o777) # 创建logger logger = logging.getLogger('main_logger') logger.setLevel(logging.DEBUG) # 创建handler 用于写入日志文件 info_handler = TimedRotatingFileHandler(service_info_log_path + ".log", when='MIDNIGHT', interval=1, backupCount=60, encoding='utf-8') info_handler.setLevel(logging.DEBUG) info_handler.setFormatter(logging.Formatter(standard_format)) # 设置 切分后日志文件名的时间格式 默认 filename+"." + suffix # filename="mylog" suffix设置,会生成文件名为mylog.2020-02-25.log info_handler.suffix = "%Y-%m-%d.log" # extMatch是编译好正则表达式,用于匹配日志文件名后缀 # 需要注意的是suffix和extMatch一定要匹配的上,如果不匹配,过期日志不会被删除。 info_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}.log$") # 创建handler 用于写入日志文件 # TimedRotatingFileHandler 创建固定时间间隔的日志 error_handler = TimedRotatingFileHandler(service_error_log_path + ".log", when='MIDNIGHT', interval=1, backupCount=60, encoding='utf-8') error_handler.setLevel(logging.ERROR) error_handler.setFormatter(logging.Formatter(standard_format)) error_handler.suffix = "%Y-%m-%d.log" error_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}.log$") # 处理器添加到logger logger.addHandler(info_handler) logger.addHandler(error_handler) return logger
使用实例:
def create_app(): # 创建flask实例 app = Flask(__name__) # 创建日志 logger = init_log("logname") @app.route('/') def hello_world(): logger.info("成功接收消息" + str(center_frequency)) return 'Hello World'