首页 > 编程语言 >Python基础篇:日志logging

Python基础篇:日志logging

时间:2023-05-15 21:31:53浏览次数:48  
标签:info logger logging Python handler 日志 message


一:日志级别

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

二:日志格式化

https://docs.python.org/3/library/logging.html#logrecord-attributes

Attribute name

Format

Description

args

You shouldn’t need to format this yourself.

The tuple of arguments merged into msg to produce message, or a dict whose values are used for the merge (when there is only one argument, and it is a dictionary).

asctime

%(asctime)s

Human-readable time when the LogRecord was created. By default this is of the form 2003-07-08 16:49:45,896’ (the numbers after the comma are millisecond portion of the time).

created

%(created)f

Time when the LogRecord was created (as returned by time.time()).

exc_info

You shouldn’t need to format this yourself.

Exception tuple (à la sys.exc_info) or, if no exception has occurred, None.

filename

%(filename)s

Filename portion of pathname.

funcName

%(funcName)s

Name of function containing the logging call.

levelname

%(levelname)s

Text logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL).

levelno

%(levelno)s

Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL).

lineno

%(lineno)d

Source line number where the logging call was issued (if available).

message

%(message)s

The logged message, computed as msg % args. This is set when Formatter.format() is invoked.

module

%(module)s

Module (name portion of filename).

msecs

%(msecs)d

Millisecond portion of the time when the LogRecord was created.

msg

You shouldn’t need to format this yourself.

The format string passed in the original logging call. Merged with args to produce message, or an arbitrary object (see Using arbitrary objects as messages).

name

%(name)s

Name of the logger used to log the call.

pathname

%(pathname)s

Full pathname of the source file where the logging call was issued (if available).

process

%(process)d

Process ID (if available).

processName

%(processName)s

Process name (if available).

relativeCreated

%(relativeCreated)d

Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded.

stack_info

You shouldn’t need to format this yourself. Stack frame information (where available) from the bottom of the stack in the current thread, up to and including the stack frame of the logging call which resulted in the creation of this record.

thread

%(thread)d

Thread ID (if available).

threadName

%(threadName)s

Thread name (if available).

三:使用

3.1 编码方式(个人推荐使用这种)

封装一个日志类。

import os
import sys
import logging
from logging.handlers import RotatingFileHandler
import datetime

current_path = os.path.dirname(__file__)
log_path = os.path.join(current_path, f'../logs/app-{datetime.date.today()}.log')


class LogUtils:
    def __init__(self):
        self.log_path = log_path
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.DEBUG)

        formatter = logging.Formatter(
            fmt='%(asctime)s %(levelname)s %(thread)d --- [%(threadName)s] %(filename)s %(funcName)s:%(lineno)d:%(message)s')

        console_handler = logging.StreamHandler()
        console_handler.setFormatter(formatter)

		# RotatingFileHandler 根据日志文件大小自动生成日志文件
        # 单个文件最大3k,最多保存3份文件(除了当前写入的文件外),实际情况这个值要设的很大sys.maxsize,防止覆盖 超过则循环式覆盖
        rotating_file_handler = RotatingFileHandler(log_path, maxBytes=1024 * 3, backupCount=3, encoding='utf-8')

		# TimedRotatingFileHandler 往文件里写入: 根据时间间隔自动生成日志 文件
        # interval是时间间隔,
        # backupCount是备份文件的个数,如果超过这个个数,就会自动删除,
        # when是间隔的时间单位,单位有以下几种:S 秒, M 分, H 小时, D 天, W 每星期(interval==0时代表星期一, midnight 每天凌晨
        timed_rotating_file_handler = handlers.TimedRotatingFileHandler(filename=filename, when='D', backupCount=3, encoding='utf-8')

  
        rotating_file_handler.setFormatter(formatter)

        file_handler = logging.FileHandler(log_path, encoding='utf-8')
        file_handler.setFormatter(formatter)
        self.logger.addHandler(console_handler)
        # self.logger.addHandler(file_handler)
        self.logger.addHandler(rotating_file_handler)

    def get_logger(self):
        return self.logger


logger = LogUtils().get_logger()

日志测试

from common.log_utils import logger

if __name__ == '__main__':
    for i in range(40):
        logger.info(f" {i} info测试info测试info测试info测试info测试info测试info测试info测试info测试info测试info测试info测试info测试info测试.")

注意:这里和我的认知不太一样,这里先从最后一个日志文件开始写,即先从2号开始写,然后是1号,最后是没有标号的文件。

Python基础篇:日志logging_python


Python基础篇:日志logging_存到文件_02


Python基础篇:日志logging_python_03

3.2 配置文件方式 fileConfig

logging.conf

[loggers]
# 配置logger信息。必须包含一个名字叫做root的logger,当使用无参函数logging.getLogger()时,默认返回root这个logger,
# 其他自定义logger可以通过 logging.getLogger("fileAndConsole") 方式进行调用
keys=root,fileAndConsole

[handlers]
# 定义声明handlers信息。
keys=fileHandler,consoleHandler

[formatters]
# 设置日志格式
keys=simpleFormatter

[logger_root]
# 对loggers中声明的logger进行逐个配置,且要一一对应,在所有的logger中,必须制定level和handlers这两个选项,
# 对于非roothandler,还需要添加一些额外的option,其中qualname表示它在logger层级中的名字,在应用代码中通过这个名字制定所使用的handler,
# 即 logging.getLogger("fileAndConsole"),handlers可以指定多个,中间用逗号隔开,比如handlers=fileHandler,consoleHandler,同时制定使用控制台和文件输出日志
level=DEBUG
handlers=consoleHandler,fileHandler

[logger_fileAndConsole]
level=DEBUG
handlers=fileHandler,consoleHandler
qualname=fileAndConsole
propagate=0

[handler_consoleHandler]
# 在handler中,必须指定class和args这两个option,常用的class包括
# StreamHandler(仅将日志输出到控制台)、FileHandler(将日志信息输出保存到文件)、
# RotaRotatingFileHandler(将日志输出保存到文件中,并设置单个日志wenj文件的大小和日志文件个数),
# args表示传递给class所指定的handler类初始化方法参数,它必须是一个元组(tuple)的形式,即便只有一个参数值也需要是一个元组的形式;
# 里面指定输出路径,比如输出的文件名称等。level与logger中的level一样,而formatter指定的是该处理器所使用的格式器,
# 这里指定的格式器名称必须出现在formatters这个section中,且在配置文件中必须要有这个formatter的section定义;
# 如果不指定formatter则该handler将会以消息本身作为日志消息进行记录,而不添加额外的时间、日志器名称等信息;
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter

[handler_fileHandler]
class=FileHandler
args=('test.log', 'a')
level=DEBUG
formatter=simpleFormatter

[formatter_simpleFormatter]
format=%(asctime)s %(levelname)s %(thread)d --- [%(threadName)s] %(filename)s %(funcName)s:%(lineno)d:%(message)s
datefmt=%Y-%m-%d %H:%M:%S
import logging.config

logging.config.fileConfig('./config/logging.conf')
logger = logging.getLogger()

logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

3.3 配置字典方式 dictConfig

LOGGING_CONFIG = {
    "version": 1,
    "formatters": {
        "default": {
            'format': '%(asctime)s %(levelname)s %(thread)d --- [%(threadName)s] %(filename)s %(funcName)s:%(lineno)d:%(message)s',
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": logging.DEBUG,
            "formatter": "default"
        },
        "file": {
            "class": "logging.FileHandler",
            "level": logging.DEBUG,
            "filename": "./log.txt",
            "formatter": "default",
        }
    },
    "root": {
        "handlers": ["console", "file"],
        "level": "DEBUG"
    },
}

logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger()

logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')


标签:info,logger,logging,Python,handler,日志,message
From: https://blog.51cto.com/u_16114318/6281008

相关文章

  • 深入理解 python 虚拟机:多继承与 mro
    深入理解python虚拟机:多继承与mro在本篇文章当中将主要给大家介绍python当中的多继承和mro,通过介绍在多继承当中存在的问题就能够理解在cpython当中引入c3算法的原因了,从而能够帮助大家更好的了理解mro。python继承的问题继承是一种面向对象编程的概念,它可以让一......
  • python 操作 PostgreSQL 数据库,线程并行修改 5w 条数据,性能优化
    python操作PostgreSQL数据库,线程并行修改5w条数据,性能优化110 娃哈哈店长的个人博客 /  433 /  0 / 创建于 3年前  获取新xls表中的所有数据并整理为列表形式返回其实修改的代码量不大,但是要考虑保留之前我们用的函数和方法还要继续能使用。excel2......
  • python openpyxl 操作excel
     openpyxl是从1开始计数,遍历操作时请用1为起始点,且总数加一,例:foriinrange(1,n+1) 单元格样式所需导入模块fromopenpyxl.stylesimportAlignment,Font,Border,Side,PatternFill样式#设置边框线align=Alignment(horizontal='center',vertical='c......
  • SICP:元循环求值器(Python实现)
    求值器完整实现代码我已经上传到了GitHub仓库:TinySCM,感兴趣的童鞋可以前往查看。这里顺便强烈推荐UCBerkeley的同名课程CS61A。在这个层次结构的最底层是对象语言。对象语言只涉及特定的域,而不涉及对象语言本身(比如它们的文法规则,或其中的其体句子)。如要涉及它们,则要有一种元......
  • Python基础语法入门
    Python基础语法入门1、Python的注释符号1、什么是注释?#学习任何一门代码,先学注释,注释是代码之母注释就是对一段代码的解释说明,它不会参与到代码的运行,只是起到提示作用2、如何注释?2.1、#单行注释#它可以使用快捷键帮助我们把代码写的更加规范快捷键:Ctrl+alt+1(格式......
  • 了解Python的基本数据类型
    引入 我们学习变量是为了让计算机能够记忆事物的某种状态,而变量的值就是用来存储事物状态的,很明显事物的状态是分成不同种类的(例如水的液态,气态和固态),所以变量值也应该有不同的类型 一、数字类型int(整型)float(浮点型)不可变数据类型int,整型,是没有小数点的数字......
  • < Python全景系列-2 > Python数据类型大盘点
    <Python全景系列-2>Python数据类型大盘点欢迎来到我们的系列博客《Python全景系列》!在这个系列中,我们将带领你从Python的基础知识开始,一步步深入到高级话题,帮助你掌握这门强大而灵活的编程语法。无论你是编程新手,还是有一定基础的开发者,这个系列都将提供你需要的知识和技能。Py......
  • 使用 Easysearch,日志存储少一半
    在海量日志存储场景中,索引膨胀率是一个关键指标,直接影响存储成本和查询性能。它表示原始数据与索引数据在磁盘上所占空间的比率。较高的索引膨胀率不仅增加了存储成本,而且可能会影响查询速度,尤其是在I/O密集型的查询中。因此,我们需要密切关注和优化索引膨胀率。接下来,我们将比较......
  • Logstash关于日志清洗记录学习及应用
    logstash日志清洗:日志清洗任务,给了我乱七八糟资料之后看的一脸懵,最后决定自己动手整理整理这样有头绪点,记录一下自己学习过程。其中涉及到一些ip内容的我都改为ip,其他保持一致,欢迎大家一起讨论,我也是刚开始学习这个,如有写的不对请多指教。一、学习阶段1、首先理解logstash中各个......
  • python基础学习-读写CSV文件
    CSV文件介绍参考:Python-Core-50-Courses/第23课:用Python读写CSV文件.mdatmaster·jackfrued/Python-Core-50-Courses(github.com)CSV 全称逗号分隔值文件是一种简单、通用的文件格式,被广泛的应用于应用程序(数据库、电子表格等)数据的导入和导出以及异构系统之间的数据......