scrapy框架中的常用日志配置
- LOG_FILE : 日志输出文件,如果为None,日志信息会打印在控制台;
- LOG_ENABLED : 是否启用日志,默认True;
- LOG_ENCODING : 日志编码,默认utf-8;
- LOG_LEVEL : 日志等级,默认debug;
- LOG_FORMAT : 日志格式;
- LOG_DATEFORMAT : 日志日期格式;
- LOG_STDOUT : 日志标椎输出,默认False,如果是True所有标椎输出都将写入日志中;
- LOG_SHORT_NAMES : 短日志名,默认False,如果是True将不输出组件名。
日志级别
- CRITICAT — 严重错误
- ERROR — 一般错误
- WARNING — 警告信息
- INFO — 一般信息
- DEBUG — 调试信息
级别:
CRITICAT>ERROR>WARNING>INFO>DEBUG
logging模块常用format格式说明
- %(levelno)s: 打印日志级别的数值
- %(levelname)s: 打印日志级别名称
- %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
- %(filename)s: 打印当前执行程序名
- %(funcName)s: 打印日志的当前函数
- %(lineno)d: 打印日志的当前行号
- %(asctime)s: 打印日志的时间
- %(thread)d: 打印线程ID
- %(threadName)s: 打印线程名称
- %(process)d: 打印进程ID
- %(message)s: 打印日志信息
日期格式
- %y 两位数的年份表示(00-99)
- %Y 四位数的年份表示(000-9999)
- %m 月份(01-12)
- %d 月内中的一天(0-31)
- %H 24小时制小时数(0-23)
- %I 12小时制小时数(01-12)
- %M 分钟数(00=59)
- %S 秒(00-59)
- %a 本地简化星期名称
- %A 本地完整星期名称
- %b 本地简化的月份名称
- %B 本地完整的月份名称
- %c 本地相应的日期表示和时间表示
- %j 年内的一天(001-366)
- %p 本地A.M.或P.M.的等价符
- %U 一年中的星期数(00-53)星期天为星期的开始
- %w 星期(0-6),星期天为星期的开始
- %W 一年中的星期数(00-53)星期一为星期的开始
- %x 本地相应的日期表示
- %X 本地相应的时间表示
- %Z 当前时区的名称
- %% %号本身
日志配置的常用形式(代码)
LOG_FILE = "日志文件名"
LOG_LEVEL = "日志级别"
LOG_DATEFORMAT = "%Y-%m-%d %H:%M:%S"
LOG_FORMAT = "%(asctime)s-%(levelname)s-%(filename)s-%(funcName)s-%(message)s-%(lineno)d"
scrapy中爬虫使用日志
- 导包 logging;
import logging
- 在自定义custom_settings中添加日志基本配置;
custom_settings = {
"LOG_FILE": "a.log",
"LOGLEVEL": "INFO"
}
- 因为在scrapy框架中,爬虫文件直接self打点调用log(),将信息添加到日志文件中;
self.log("准备采集导航条",logging.INFO)
- 在日志文件中添加日志错误信息,需要对错误信息进行转换,因为log()只能添加字符串日志信息。
基本代码实现
try:
a = []
print(a[0])
except Exception as e:
self.log(f"{repr(e)},错误在{sys._getframe().f_code.co_filename}的{sys._getframe().f_lineno}行", logging.ERROR)
scrapy 中管道使用文件
- 导包 logging;
import logging
- 配置日志中名字
log = logging.getLogger("a.log")
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190829192839640.png)
- 添加日志文件信息
log.info("日志存储信息")
log.debug("日志存储信息")
log.critical("日志存储信息")
log.error("日志存储信息")
log.warning("日志存储信息")
自定义日志工具类
第一个
import logging
import os
LOG_LEVEL = logging.INFO
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LOG_TYPES = {
'transaction': 'transactions.log',
'access': 'access.log',
}
def log(log_type):
"""
from logger.logger import log
log_obj = log('日志名称')
log_obj.info("普通消息")
log_obj.debug("调试消息")
log_obj.warn("警告消息")
log_obj.error("错误消息")
log_obj.critical("hello world")
"""
log_dir = "%s/log" % (BASE_DIR)
log_file = "%s/%s" % (log_dir, LOG_TYPES.get(log_type, log_type+".log"))
os.makedirs(log_dir, exist_ok=True)
logger = logging.getLogger(log_type)
logger.setLevel(LOG_LEVEL)
ch = logging.StreamHandler()
ch.setLevel(LOG_LEVEL)
fh = logging.FileHandler(log_file, encoding="utf-8")
fh.setLevel(LOG_LEVEL)
"""
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 字符串形式的当前时间。默认格式是 “2018-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息
"""
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
logger.addHandler(ch)
logger.addHandler(fh)
return logger
- 导包
from logger import log
- 调用
log_obj = log('日志文件名')
log_obj.info("普通消息")
log_obj.debug("调试消息")
log_obj.warn("警告消息")
log_obj.error("错误消息")
log_obj.critical("严重错误信息")
第二个
import logging
from logging import StreamHandler, FileHandler, Formatter
from logging.handlers import TimedRotatingFileHandler, RotatingFileHandler
class Logger(object):
filename = "123.log"
log_format = "%(asctime)s|%(levelname)s|%(filename)s|%(funcName)s|%(message)s|%(lineno)d"
is_file = False
is_time = False
@classmethod
def log_init(cls):
log = logging.getLogger(__name__)
handler1 = StreamHandler()
handler2 = FileHandler(cls.filename, encoding="gb2312")
log.setLevel(logging.DEBUG)
handler1.setLevel(logging.DEBUG)
handler2.setLevel(logging.DEBUG)
format = Formatter(cls.log_format)
handler1.setFormatter(format)
handler2.setFormatter(format)
if cls.is_time:
filehandler = logging.handlers.TimedRotatingFileHandler("a" + cls.filename, when='S', interval=1, backupCount=3)
filehandler.suffix = "%Y-%m-%d_%H-%M-%S.log"
filehandler.setFormatter(format)
log.addHandler(filehandler)
if cls.is_file:
handler = logging.handlers.RotatingFileHandler(cls.filename, maxBytes=100, backupCount=5)
handler.setFormatter(format)
log.addHandler(handler)
log.addHandler(handler1)
log.addHandler(handler2)
return log
@classmethod
def debug(cls, message):
log = cls.log_init()
log.debug(message)
@classmethod
def warning(cls, message):
log = cls.log_init()
log.warning(message)
@classmethod
def error(cls, message):
log = cls.log_init()
log.error(message)
@classmethod
def critical(cls, message):
log = cls.log_init()
log.critical(message)
@classmethod
def info(cls, message):
log = cls.log_init()
log.info(message)
- 导包
from logger import Logger
- 调用
Logger.filename = "a.log"
Logger.log_format = ""
Logger.is_file = True
Logger.is_time = True
Logger.info("普通消息")
Logger.debug("调试消息")
Logger.warn("警告消息")
Logger.error("错误消息")
Logger.critical("严重错误信息")