第一:脚本--函数配置
简单的脚本,可以直接采用函数配置
import logging
logging.basicConfig(level=logging.INFO,filename='G:/web/test.log',format="%(levelname)s:%(message)s",filemode='w')
logger = logging.getLogger('weather')
stream_handler = logging.StreamHandler()
logger.addHandler(stream_handler)
logger.info('rain')
以上logging.basicConfig()语句,相当于默认添加了一个保存日志的handler,并设置地址,格式,读写方式。
logger记录器此时,只有一个相当于Filewriter 的handler,不能控制台输出,需要额外添加一个用于输出至
控制台的handler,且该handler的level继承了basicConfig的level。
------------------------------------------------------------------------------------------------------------------
插入题外话,python中的读写模式:
模式 | 可做操作 | 若文件不存在 | 是否覆盖 |
r | 只能读 | 报错 | - |
r+ | 可读可写 | 报错 | 是 |
w | 只能写 | 创建 | 是 |
w+ | 可读可写 | 创建 | 是 |
a | 只能写 | 创建 | 否,追加写 |
a+ | 可读可写 | 创建 | 否,追加写 |
------------------------------------------------------------------------------------------------------------------
第二:多模块--封装配置信息
很少这样操作。
import logging
import logging.handlers
import os
log_dir = os.path.join(os.curdir, 'logs')
if os.path.exists(log_dir) and os.path.isdir(log_dir):
pass
else:
os.mkdir(log_dir)
consle_handle = logging.StreamHandler()#当作全局变量,某种程度避免重复写入日志【多次调用?】
class jess_logs(object):
formater = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
file_handler = logging.handlers.RotatingFileHandler(filename='logs/jessproxy.log')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formater)
consle_handle.setLevel(logging.INFO)
consle_handle.setFormatter(formater)
def getlog(self,current='name'):
my_jess_log = logging.getLogger(current)
my_jess_log.addHandler(self.file_handler)
my_jess_log.addHandler(consle_handle)
my_jess_log.setLevel(logging.INFO)
return my_jess_log
配置信息封装成一个类,方便调用
from .... import jess_logs
logger = jess_logs().getlog(current=__name__)
__name__获取调用模块名称。
第三:多模块---配置文件
优点:方便维护
根目录下,配置文件,一般默认名称logging.conf
#coding: utf-8
#logging配置文件
#定义logger模块,root是父类,必须存在,其他的自定义
#logging.getLogger(name) 相当于向loggging模块注册了一种日志打印
#如果name为loggers里面keys的值,则调用对应的配置,如果name没有则调用默认(root)的配置
#name 中用点 . 表示继承关系
#可以有多个,以逗号隔开
#####################################################################################################
[loggers]
keys=root,scheduler,utils,getter#需要日志的模块名作为日志记录器名
#实现logger对应的配置信息
# 必须是 logger_name name为loggers中key的值
#level 日志级别,级别有 DEBUG,INFO,WARNING,ERROR,CRITICAL
#handlers 日志处理器,可以有多个 以逗号隔开
#qualname logger的名称,通过logging.getLogger(name)获取,这里的name便是qualname
# 如果获取的logger 名称不存在,则调用默认(root)logger
#propagate 是否继承符类的配置信息,0:否 1:是
#如果这个属性是True也就是1,那么这个logger的输出会朝着上一级logger传播;会产生两个记录
#所以需要把其他logger的propagate属性设置为False
[logger_root]
level=INFO
handlers=file_write
qualname=root
[logger_scheduler]
level=INFO
handlers=stream
qualname=scheduler
propagate=1
#不向上一级传播
#在这里 如果propagate=1,则表示继承父类(root)的配置信息。
#也就是说 既输出到日志文件(继承父类的配置)又输出到控制台
#propagate = 0 表示仅使用自身的配置,仅输出到日志文件
[logger_utils]
level=INFO
handlers=stream
qualname=utils
propagate=1
[logger_getter]
level=INFO
handlers=stream
qualname=getter
propagate=1
#######################################################################
[handlers]
keys=file_write,stream
#handlers的具体配置实现
#必须是 handler_name name为handlers中key的值
#class为logging包里面的handler处理器
#formatter 日志输入格式
#args handler相关参数
[handler_file_write]
class=FileHandler
formatter=pretty
level=INFO
args=('./logs/jesslog2.log','w' )
# ./是当前目录
# ../是上一级【父级】目录
[handler_stream]
class=StreamHandler
level=INFO
formatter=pretty
args=(sys.stdout,)
##############################################################################
[formatters]
keys=pretty
#日志输出格式化实现
#datefmt 日期格式 对应asctime
[formatter_pretty]
format=%(levelname)s - %(name)s - %(asctime)s - %(module)s.%(funcName)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S
调用配置文件,封装成类
import logging
import logging.handlers
import os
import logging.config
class mylogger(object):
"""
加载日志配置文件,并获得logger
"""
log_instance = None
@staticmethod
def int_logging_conf():
"""
从当前目录获取配置文件
"""
current_path = os.path.join(os.curdir,'logging.conf')
logging.config.fileConfig(current_path)
@staticmethod
def get_logger(name=''):
"""
获得logger
"""
if mylogger.log_instance == None:
mylogger.int_logging_conf()
mylogger.log_instance = logging.getLogger(name)
return mylogger.log_instance
模块调用
from ... import mylogger
logger = mylogger.get_logger('scheduler')
坑:因配置文件含中文字符,提示解码错误,可以用Notepad++这个记事本转码utf-8转成ANSI编码