python3 配置logging日志类的操作

配置类config_file:

from configparser import ConfigParser

class config_file:

  def __init__(self,conf_filePath,encoding="utf-8"):
    #打开配置文件,实例化ConfigParser类,并以默认utf-8的编码格式读取文件
    self.cf = ConfigParser()
    self.cf.read(conf_filePath,encoding)

  def get_Int_Value(self,section,option):
    #获取整数
    return self.cf.getint(section,option)

  def get_boolValue(self,section,option):
    #获取布尔值
    return self.cf.getboolean(section,option)

  def get_strValue(self,section,option):
    # 获取字符串类型的值
    return self.cf.get(section,option)

  def get_floatValue(self,section,option):
    # 获取浮点数值
    return self.cf.getfloat(section,option)

  def get_sections(self):
    # 获取所有的section
    return self.cf.sections()

  def get_options(self,section):
    # 获取所有的option
    return self.cf.options(section)

日志类:

from configparser import ConfigParser
import logging
from config_file import config_file
class Log_Test(config_file):#继承config_file

  def logging(self):
    logger = logging.getLogger(self.get_strValue('log','logger_name')) #从配置文件读取logger名
    logger.setLevel(self.get_strValue('log', 'logger_level')) # 设置logger收集器的收集log级别
    format_logger = logging.Formatter(self.get_strValue('log','logger_format'))
    if(self.get_boolValue('log','logger_out')):
      handle = logging.StreamHandler() # 指定输出到console控制台
      handle.setLevel(self.get_strValue('log', 'logger_level')) # 读取日志等级并设定logging的级别
      handle.setFormatter(format_logger) # 指定日志格式
    else:
      handle = logging.FileHandler(self.get_strValue('log','logger_filepath'), encoding='utf-8')
      handle.setLevel(self.get_strValue('log', 'logger_level')) # 读取日志等级并设定logging的级别
      handle.setFormatter(format_logger) # 指定日志格式
    logger.addHandler(handle)
    return logger

日志配置文件logging.cfg:

[log]
#日志收集器
logger_name=TEST
#日志级别 级别需要大写 DEBUG-->INFO-->WARNING-->ERROR-->CRITICAL/FATAL
logger_level=DEBUG
#日志输出格式  注意转义
logger_format=%%(asctime)s-%%(filename)s-%%(levelname)s-日志信息:%%(message)s
#日志是否输出到控制台  True  or  False
logger_out=False
#日志输出指定文件地址
logger_filepath=logging_Test.log

将读取配置文件类进行封装,日志类继承配置类。

补充知识:Python2/Python3自定义日志类教程

一、说明

1.1 背景说明

Python的logging功能是比较丰富的支持不同层次的日志输出,但或是我们想在日志前输出时间、或是我们想要将日志输入到文件,我们还是想要自定义日志类。

之前自己也尝试写过但感觉文档太乱看不懂怎么写,今天有人拿个半成品来问为什么代码报错,在其基础上改造了一下。

1.2 logging级别说明

logging日志级别及对应值如下,默认情况下直接运行只有INFO及以上级别才会输出(本质上是大于等于20才会输出),调试模式运行DEBUG日志才会输出。

可以通过自定义输出日志级别,指定直接运行输出什么级别的日志;不过调试模式打印的日志应该是不可以修改的。


Level


Numeric value


CRITICAL


50


ERROR


40


WARNING


30


INFO


20


DEBUG


10


NOTSET


0

二、实现代码

2.1 Python2实现代码

# -*- coding: utf-8 -*-
import os
import datetime
import logging

class LogConfig:
  def __init__(self,log_type="console"):
    # 指定日志输出到控制台时的初始化
    if log_type == "console":
      logging.basicConfig(level=logging.INFO,
                format='%(asctime)s %(levelname)s %(message)s',
                datefmt='%Y-%m-%d %H:%M:%S',
                )
    # 指定日志输出到文件的初始化
    elif log_type == "file":
      # 创建存放日志的目录
      if not os.path.exists('./log'):
        os.mkdir('./log')

      # 操作系统本身不允许文件名包含:等特殊字符,所以这里也不要用,不然赋给filename时会报错
      nowTime = datetime.datetime.now().strftime('%Y-%m-%d')
      file_name = './log/%s.log' % nowTime

      # python2.7也有logging.basicConfig(),但只直接用logging.basicConfig(),写中文时会报错
      # 所以为风格统一,我们这里不使用logging.basicConfig(),全通过set设置
      root_logger = logging.getLogger()
      root_logger.setLevel(logging.INFO)
      handler = logging.FileHandler(filename=file_name, encoding='utf-8', mode='a')
      formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
      handler.setFormatter(formatter)
      root_logger.addHandler(handler)

  def getLogger(self):
    logger = logging.getLogger()
    return logger

if __name__ == "__main__":
  # log_type = "console"
  log_type = "file"
  logger = LogConfig(log_type).getLogger()
  logger.debug('print by debug')
  logger.info('print by info')
  logger.warning('print by warning')

2.2 Python3实现代码

python3.3 之后logging.basicConfig()中提供了handlers参数,我们可借助handlers参数来指定编码。

python3.3之前的python3版本写法得和python2一样。另外python3.9之后logging.basicConfig()会直接提供encoding参数,到时可以更方便。

import os
import datetime
import logging

class LogConfig:
  def __init__(self,log_type="console"):
    # 指定日志输出到控制台时的初始化
    if log_type == "console":
      logging.basicConfig(level=logging.INFO,
                format='%(asctime)s %(levelname)s %(message)s',
                datefmt='%Y-%m-%d %H:%M:%S',
                )
    # 指定日志输出到文件的初始化
    elif log_type == "file":
      # 创建存放日志的目录
      if not os.path.exists('./log'):
        os.mkdir('./log')

      # 操作系统本身不允许文件名包含:等特殊字符,所以这里也不要用,不然赋给filename时会报错
      nowTime = datetime.datetime.now().strftime('%Y-%m-%d')

      file_name = './log/%s.log' % nowTime
      file_handler = logging.FileHandler(filename=file_name,encoding='utf-8', mode='a')
      # level----指定打印的日志等级;默认为WARNING;可为NOTSET、DEBUG、INFO、WARNING、ERROR、CRITICAL
      # format----指定整条日志的格式;这里设置为“时间-等级-日志内容”
      # datefmt----format中时间的格式;
      # filename----日志输出到的文件;默认打印到控制台
      # filemode----日志文件读写形式;默认为“a”;配合filename使用,如果不用filename该参数也可不用
      # 本来输出到文件使用filename和filemode两个参数就可以了,不需要handlers
      # 但是logging将日志输出到文件时中文会乱码,而logging.basicConfig又没有提供指定编码的参数(python3.9之后才提供有直接的encoding参数)
      # 要指定编码只能使用handlers。另外handlers还是python3.3 之后才提供的参数,在此之前的版本请参考python2的写法
      logging.basicConfig(level=logging.INFO,
                format='%(asctime)s %(levelname)s %(message)s',
                datefmt='%Y-%m-%d %H:%M:%S',
                # filename=file_name,
                # filemode='a',
                handlers=[file_handler],
                )

  def getLogger(self):
    logger = logging.getLogger()
    return logger

if __name__ == "__main__":
  # log_type = "console"
  log_type = "file"
  logger = LogConfig(log_type).getLogger()
  logger.debug('print by debug')
  logger.info('print by info')
  logger.warning('print by warning')

三、日志截图

四、更科学的日志定义方式(20200310更新)

通过近段时间的使用发现原先的方法就自己用用没问题,但与别人产生调用及上生产时就会存在几个问题:

第一个问题是,直接通过logging.basicConfig()进行配置,会同时影响被调用库的日志设置。

第二个问题是,原现的文件日志形式只能输出到一个给定的文件,不能实现不同的日志类型输出到不同的日志文件。

第三个问题是,原现的文件日志形式使用"w"模式则上次日志会被清除,使用"a"模式则日志又会无限增长需要注意清理。

前两个问题通过getLogger时给定一个名称而不是直接获取根logger进行处理;第三个问题通过使用TimedRotatingFileHandler等替换FileHandler进行处理。

更新代码如下:

import os
import datetime
import logging
import logging.handlers

class LogConfig:
  def __init__(self):
    pass

  def get_console_logger(self):
    def _gen_file_logger_handler():
      _handler = logging.StreamHandler()
      formatter = logging.Formatter(
        "[%(asctime)s %(msecs)03d][%(process)d][tid=%(thread)d][%(name)s][%(levelname)s] %(message)s [%(filename)s"
        " %(funcName)s %(lineno)s] ", datefmt="%Y-%m-%d %H:%M:%S")
      _handler.setLevel(logging.INFO)
      _handler.setFormatter(formatter)
      return _handler
    def _gen_console_logger():
      # 解决第一个问题--logging.basicConfig()会影响被调用库的日志--getLogger时给定一个名称而不是直接获取根logger
      _console_logger = logging.getLogger("console_logger")
      _console_logger.addHandler(handler)
      return _console_logger

    handler = _gen_file_logger_handler()
    console_logger = _gen_console_logger()
    return console_logger

  def get_file_logger(self,log_file_name):
    def _make_sure_log_dir_exist():
      if not os.path.isdir(log_file_dir):
        os.mkdir(log_file_dir)
    def _gen_file_logger_handler():
      # 操作系统本身不允许文件名包含:等特殊字符,所以这里也不要用,不然赋给filename时会报错
      # nowTime = datetime.datetime.now().strftime('%Y-%m-%d')
      file_path = f'{log_file_dir}/{log_file_name}'
      formatter = logging.Formatter(
        "[%(asctime)s %(msecs)03d][%(process)d][tid=%(thread)d][%(name)s][%(levelname)s] %(message)s [%(filename)s"
        " %(funcName)s %(lineno)s] ", datefmt="%Y-%m-%d %H:%M:%S")
      # 解决第三个问题--日志会不断增大需要手动去清理--使用TimedRotatingFileHandler等替换FileHandler
      # filename----日志文件
      # when----更换日志文件的时间单位
      # interval----更换日志文件的时间单位个数;这里是7天换一个文件
      # backupCount----保存的旧日志文件个数;这里即只保留上一个日志文件
      # encoding----日志文件编码
      _handler = logging.handlers.TimedRotatingFileHandler(filename=file_path,when='D',interval=7,backupCount=1,encoding='utf-8')
      # 实际发现有些时候这里setLevel并不起作用
      # _handler.setLevel(logging.INFO)
      _handler.setFormatter(formatter)
      return _handler
    def _gen_file_logger():
      # 解决第二个问题--不能定义多个日志文件--getLogger时给定一个名称而不是直接获取根logger
      _file_logger = logging.getLogger(log_file_name)
      _file_logger.addHandler(handler)
      return _file_logger

    log_file_dir = "log"
    _make_sure_log_dir_exist()
    handler = _gen_file_logger_handler()
    file_logger = _gen_file_logger()
    # 实际发现有些时候handler的setLevel并不起作用,要在这里setLevel
    file_logger.setLevel(logging.INFO)
    return file_logger

if __name__ == "__main__":
  # log_type = "console"
  # logger = LogConfig().get_console_logger()
  log_type = "file"
  # log_file_name不同,返回的是不同的logger,这样就可以方便地定义多个logger
  log_file_name = "random_file_name.log"
  logger = LogConfig().get_file_logger(log_file_name=log_file_name)
  logger.debug('print by debug')
  logger.info('print by info')
  logger.warning('print by warning')

以上这篇python3 配置logging日志类的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Python的log日志功能及设置方法

    引入:Python中有个logging模块可以完成相关信息的记录,在debug时用它往往事半功倍 一.日志级别(从低到高): DEBUG :详细的信息,通常只出现在诊断问题上 INFO:确认一切按预期运行 WARNING:一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如.磁盘空间低").这个软件还能按预期工作. ERROR:更严重的问题,软件没能执行一些功能 CRITICAL :一个严重的错误,这表明程序本身可能无法继续运行 注:这5个等级,也分别对应5种打日志的方法:

  • python3 logging日志封装实例

    一个完整的程序离不开日志,无论是开发阶段,还是测试阶段,亦或程序运行阶段,都可以通过日志查看程序的运行情况,或是定位问题. 下面是对 python3 的日志库 logging 进行了封装,对于大部分的需求应该是能满足的.(如果有不满足的地方,欢迎在下方留言) 程序结构: |--logger.py | |--singleton.py | |--demo.py | |--log | | | 2018-10-12.log logger.py import os import sys import ti

  • Python中内置的日志模块logging用法详解

    logging模块简介 Python的logging模块提供了通用的日志系统,可以方便第三方模块或者是应用使用.这个模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己实现具体的日志记录方式. logging模块与log4j的机制是一样的,只是具体的实现细节不同.模块提供logger,handler,filter,formatter. logger:提供日志接口,供应用代码使用.logger最长用的操作有两类:配置和发

  • python 日志 logging模块详细解析

    Python 中的 logging 模块可以让你跟踪代码运行时的事件,当程序崩溃时可以查看日志并且发现是什么引发了错误.Log 信息有内置的层级--调试(debugging).信息(informational).警告(warnings).错误(error)和严重错误(critical).你也可以在 logging 中包含 traceback 信息.不管是小项目还是大项目,都推荐在 Python 程序中使用 logging.本文给大家介绍python 日志 logging模块 介绍. 1 基本使用

  • python3 配置logging日志类的操作

    配置类config_file: from configparser import ConfigParser class config_file: def __init__(self,conf_filePath,encoding="utf-8"): #打开配置文件,实例化ConfigParser类,并以默认utf-8的编码格式读取文件 self.cf = ConfigParser() self.cf.read(conf_filePath,encoding) def get_Int_Val

  • Python基于yaml文件配置logging日志过程解析

    一.使用logging.config.dictConfig()函数读取配置信息,参数是字典类型 with open(file="./loggingconfigyaml.yaml", mode='r', encoding="utf-8")as file: logging_yaml = yaml.load(stream=file, Loader=yaml.FullLoader) # print(logging_yaml) # 配置logging日志:主要从文件中读取ha

  • python3中的logging记录日志实现过程及封装成类的操作

    作用: 主要记录信息,便于定位查看问题. python logging模块官网: https://docs.python.org/zh-cn/3.7/library/logging.html#formatter-objects 三种定位问题方法: print debug调试:代码写好后,就不需要再进行调试了,所以引入了logger logging.debug() – 一般在测试环境中用 logger:当生产环境中有问题时,可以查看logger定位问题 步骤: 1.初始化日志 收集器 2.设置日志

  • Java 配置log4j日志文件路径 (附-获取当前类路径的多种操作)

    1 日志路径带来的痛点 Java 项目中少不了要和log4j等日志框架打交道, 开发环境和生产环境下日志文件的输出路径总是不一致, 设置为绝对路径的方式缺少了灵活性, 每次变更项目路径都要修改文件, 目前想到的最佳实现方式是: 根据项目位置自动加载并配置文件路径. 本文借鉴 Tomcat 的配置方式 "${catalina.home}/logs/catalina.out", 通过相对路径的方式设置日志的输出路径, 有其他解决方案的小伙伴, 请直接评论区交流哦

  • Django logging日志模块实例详解(日志记录模板配置)

    目录 一.Django日志 二.Logger 记录器 Django 内置记录器 三.Handler 处理程序 Logging 自身携带Handler 四.Filter过滤器 五.Formatters格式化器 六:Django 集成日志logginger 模块 总结 一.Django日志 Django使用python内建的logging模块打印日志,Python的logging配置由四个部分组成: 1>.记录器(Logger) 2>.处理程序(Handler) 3>.过滤器(Filter)

  • Python Django框架实现应用添加logging日志操作示例

    本文实例讲述了Python Django框架实现应用添加logging日志.分享给大家供大家参考,具体如下: Django uses Python's builtin logging module to perform system logging. Django使用python的内建日志模块来记录系统日志,但是要想在django应用中开启此功能使我们的部分操作能够被记录到日志文件,那么就需要进行一定的配置并且根据具体的log类型来进行调用 step 1:配置setting.py 以下配置除了f

  • Python中logging日志记录到文件及自动分割的操作代码

    日志作为项目开发和运行中必备组件,python提供了内置的logging模块来完成这个工作:借助 TimedRotatingFileHandler 可以按日期自动分割日志,自动保留日志文件数量等,下面是对日志的一个简单封装和测试. import logging import os from logging import handlers class Logger(object): # 日志级别关系映射 level_relations = { 'debug': logging.DEBUG, 'in

  • python logging日志模块以及多进程日志详解

    本篇文章主要对 python logging 的介绍加深理解.更主要是 讨论在多进程环境下如何使用logging 来输出日志, 如何安全地切分日志文件. 1. logging日志模块介绍 python的logging模块提供了灵活的标准模块,使得任何Python程序都可以使用这个第三方模块来实现日志记录.python logging 官方文档 logging框架中主要由四个部分组成: Loggers: 可供程序直接调用的接口 Handlers: 决定将日志记录分配至正确的目的地 Filters:

  • Python logging日志模块 配置文件方式

    在一些微服务或web服务中我们难免需要日志功能,用来记录一些用户的登录记录,操作记录,以及一些程序的崩溃定位,执行访问定位等等; Python内置 非常强大的日志模块 ==> logging 今天给大家分享一下以配置文件形式进行配置log日志 ; Centos6.7 Python3.6 logging0.5.1.2 logging模块有三个比较重要的功能组件: 1.loggers 配置文件可定义一些输出日志的appname 2.handler 过滤器,比如设置日志的分隔大小,输出位置,日志文件创

随机推荐