python中logging库使用

news2024/11/15 8:31:03

文章目录

  • 1、前言
  • 2、日志的等级
  • 3、logging的基本应用
  • 4、logging的进阶应用
  • 5、logging的高阶应用
  • 6、简单调用
  • 7、参考

1、前言

  编程代码中,日志的合理使用,能够很好地监控代码的运行过程;在业务部署中,通过日志的记录情况,快速查看代码状态,定位代码运行异常信息,能高效地进行代码维护、管理、执行等。

2、日志的等级

  日志包含以下等级;设置日志等级之后,日志输出只会包含大于等于设置等级的日志信息。
在这里插入图片描述

3、logging的基本应用

  • 尝试创建一条日志,结果会打印所有的的信息
    在这里插入图片描述
import logging
# level默认为WARNING级别,不传入参数只会打印logging.waring及以下的日志
logging.basicConfig(level=logging.DEBUG)
logging.debug('这是一条debug日志')
logging.info('这是一条info日志')
logging.warning('这是一条warning日志')
logging.error('这是一条error日志')
logging.critical('这是一条critical日志')

  此外,可以设定参数控制日志输出的格式;

参数功能
%(asctime)s日志事件的发生时间
%(levelname)s该日志事件的级别
%(message)s日志记录的文本内容
%(name)s所使用日志器的名称,默认为’root’
%(pathname)s调用日志记录函数的文件全路径
%(filename)s调用日志记录函数的函数名
%(funcname)s调用日志记录函数的函数名
%(lineno)d调用日志记录函数的代码所在的行号
  • 使用以下代码再次尝试,对比不同之处
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt="%Y-%m-%d %H:%M:%S")
logging.debug('这是一条debug日志')
logging.info('这是一条info日志')
logging.warning('这是一条warning日志')
logging.error('这是一条error日志')
logging.critical('这是一条critical日志')
  • 在logging.basicConfig中加入filename参数,将日志输出到文件中
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt="%Y-%m-%d %H:%M:%S", filename='demo.log')
logging.debug('这是一条debug日志')
logging.info('这是一条info日志')
logging.warning('这是一条warning日志')
logging.error('这是一条error日志')
logging.critical('这是一条critical日志')

4、logging的进阶应用

  • 相关组件
名称作用
Loggers记录器,提供应用程序代码直接使用的接口
Handles处理器,将记录器产生的日志发送到目的地
Filters过滤器,提供更好的粒度控制,决定哪些日志会被输出
Formatters格式化器,设置日志内容的组成结构和消息字段

在这里插入图片描述

# 标准输出handler, 在终端输出
console_handler = logging.StreamHandler(stream=None)
# 文件handler, 将日志输出到文件中
file_handler = logging.FileHandler(filename,mode='a',encoding=None,delay=False)

# 其它handler
# BaseRotatingHandler
# Rotating Filehandler 滚动的多日志输出,按照时间or其他方式去生成多个日志
# TimedRotatingfilehandler

# ===========================
# 以下的使用较少
# Sockethandler
# Dataaramhandler
# Smtphandler
# Sysloghandler
# Nteventloghandler
# Httphandler
# WatchedFilehandler
# Qutelehandler
# Nullhandler
属性格式描述
asctime%(asctime)s日志产生的时间,默认格式为msecs2003-07-0816:49:45,896
msecs%(msecs)d日志生成时间的亳秒部分
created%(created)f生成的日志创建时间戳
message%(message)s具体的日志信息
filename%(filename)s生成日志的程序名
name%(name)s日志调用者
funcname%( funcname)s调用日志的函数名
levelname%(levelname)s日志级別( DEBUG,INFO, WARNING, 'ERRORCRITICAL)
levene%( leveling)s日志级别对应的数值
lineno%(lineno)d日志所针对的代码行号(如果可用的话)
module%( module)s生成日志的模块名
pathname%( pathname)s生成日志的文件的完整路径
process%( (process)d生成日志的进程D(如果可用)
processname(processname)s进程名(如果可用)
thread%(thread)d生成日志的线程D(如果可用)
threadname%( threadname)s线程名(如果可用)
  • 示例
#记录器
logger = logging.getLogger('cn.cccb.applog')
logger.setLevel(logging.DEBUG)
#必须设置为两个handler中级别更低的

#处理器handler
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.DEBUG)

#没有给handler指定日志级别,将使用logger的级别
fileHandler = logging.FileHandler(filename='addDemo.log')
consoleHandler.setLevel(logging.INFO)

#formatter格式
formatter = logging.Formatter("%(asctime)s|%(levelname)8s|%(filename)10s%lineno)s|%(message)s")
#里面的8,10实现了占位对齐

#给处理器设置格式
consoleHandler.setFormatter(formatter)
fileHandler.setFormatter(formatter)

#记录器要设置处理器
logger.addHandler(consoleHandler)
logger.addHandler(fileHandler)

#定义一个过滤器
flt = logging.Filter("cn.cccb")

#关联过滤器
# logger.addFilter(flt)
fileHandler.addFilter(flt)

#打印日志的代码
#logging.debug()#不能使用这个了!!!会使用WARNING的版本,不会用之前的记录器
logger.debug("姓名 %s, 年龄%d",name,age)
logger.debug("姓名 %s, 年龄%d",% (name,age))
logger.debug("姓名 {}, 年龄{}"format(name,age))
logger.debug(f"姓名{name}, 年龄{age}")

5、logging的高阶应用

  • logging的配置文件形式 .conf
#./logging.conf

#记录器:提供应用程序代码直接使用的接口
#设置记录器名称,root必须存在!!!
[loggers]
keys=root,applog

#处理器,将记录器产生的日志发送至目的地
#设置处理器类型
[handlers]
keys=fileHandler,consoleHandler

#格式化器,设置日志内容的组成结构和消息字段
#设置格式化器的种类
[formatters]
keys=simpleFormatter

#设置记录器root的级别与种类
[logger_root]
level=DEBUG
handlers=consoleHandler

#设置记录器applog的级别与种类
[logger_applog]
level=DEBUG 
handlers=fileHandler,consoleHandler
#起个对外的名字
qualname=applog
#继承关系
propagate=0

#设置
[handler_consoleHandler]
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter

[handler_fileHandler]
class=handlers.TimedRotatingFileHandler
#在午夜1点(3600s)开启下一个log文件,第四个参数0表示保留历史文件
args=('applog.log','midnight',3600,0)
level=DEBUG
formatter=simpleFormatter

[formatter_simpleFormatter]
format=%(asctime)s|%(levelname)8s|%(filename)s[:%(lineno)d]|%(message)s
#设置时间输出格式
datefmt=%Y-%m-%d %H:%M:%S
  • logging的字典配置形式
# logging_config.py
LOGGING_CONFIG = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'simpleFormatter': {
            'format': '%(asctime)s|%(levelname)8s|%(filename)s[:%(lineno)d]|%(message)s',
            'datefmt': '%Y-%m-%d %H:%M:%S'
        }
    },
    'handlers': {
        'consoleHandler': {
            'class': 'logging.StreamHandler',
            'stream': 'ext://sys.stdout',
            'level': 'DEBUG',
            'formatter': 'simpleFormatter'
        },
        'fileHandler': {
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': 'applog.log',
            'when': 'midnight',
            'interval': 1,
            'backupCount': 0,
            'level': 'DEBUG',
            'formatter': 'simpleFormatter'
        }
    },
    'loggers': {
        'root': {
            'handlers': ['consoleHandler'],
            'level': 'DEBUG',
            'propagate': False
        },
        'applog': {
            'handlers': ['fileHandler', 'consoleHandler'],
            'level': 'DEBUG',
            'propagate': False
        }
    }
}
  • 配置文件加载、调用
import logging
import logging.config
from logging_config import LOGGING_CONFIG

logging.config.fileConfig('logging.conf')
#使用字典就能从任意格式文件进行配置,字典是一种接口格式
# logging.config.dictConfig(LOGGING_CONFIG)

rootLogger = logging.getLogger('applog')
rootLogger.debug("This is root Logger, debug")

logger = logging.getLogger('cn.cccb.applog')
logger.debug("This is applog, debug")

try:
    int(a)
except Exception as e:
    logger.exception(e)

6、简单调用

  • 使用以上配置文件过程中,想要进行每天日志输出,输出日志的文件名每天不一样,发现总有些问题。问题是我在只使用root_logger记录器时,依然生成了datetime.now().strftime(‘applog_%Y-%m-%d.log’)命名的日志文件,代码如下:
import os
import logging
import logging.config
from datetime import datetime

# 确保日志目录存在
log_dir = 'logs'
if not os.path.exists(log_dir):
    os.makedirs(log_dir)

LOGGING_CONFIG = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standardFormatter': {
            'format': '%(asctime)s | %(levelname)8s | %(name)s | %(filename)s[:%(lineno)d] | %(message)s',
            'datefmt': '%Y-%m-%d %H:%M:%S'
        }
    },
    'handlers': {
        'consoleHandler': {
            'class': 'logging.StreamHandler',
            'stream': 'ext://sys.stdout',
            'level': 'DEBUG',
            'formatter': 'standardFormatter'
        },
        'fileHandler': {
            'class': 'logging.FileHandler',
            'filename': os.path.join(log_dir, datetime.now().strftime('applog_%Y-%m-%d.log')),
            'level': 'INFO',
            'formatter': 'standardFormatter',
            'encoding': 'utf-8'  # 指定编码
        }
    },
    'loggers': {
        'root': {  # root logger
            'handlers': ['consoleHandler'],  # 只包含控制台处理器
            'level': 'DEBUG',
            'propagate': False
        },
        'MyLogger': {
            'handlers': ['fileHandler', 'consoleHandler'],  # 包含文件和控制台处理器
            'level': 'INFO',
            'propagate': False
        }
    }
}

# 应用配置
logging.config.dictConfig(LOGGING_CONFIG)

# 使用root logger
root_logger = logging.getLogger('root')
root_logger.debug("This is a DEBUG message from root logger")
root_logger.info("This is an INFO message from root logger")

# 使用MyLogger logger
my_logger = logging.getLogger('MyLogger')
my_logger.debug("This is a DEBUG message from MyLogger")  # 不会显示,因为level是INFO
my_logger.info("This is an INFO message from MyLogger")
my_logger.error("This is an ERROR message from MyLogger")
  • 所以,采用了以下方法实现
import logging
import os
from datetime import datetime


def setup_logger(config):
    """
    使用配置字典创建并返回一个定制化的logger。
    :param config: 包含日志配置的字典
    """
    # 创建日志目录
    log_dir = config.get('log_dir', 'logs')
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    # 创建logger
    logger = logging.getLogger(config.get('name', 'PIESAT'))
    logger.setLevel(config.get('log_level', logging.INFO))

    # 创建日志格式
    formatter_config = config.get('formatter', {})
    formatter = logging.Formatter(formatter_config.get('format', '%(asctime)s - %(name)s - %(levelname)s - %(message)s'))

    # 创建文件处理器
    file_handler_config = config.get('file_handler', {})
    if file_handler_config:
        log_filename = datetime.now().strftime(
            file_handler_config.get('filename_format', "log_%Y-%m-%d_%H-%M-%S.log"))  # 修改这里
        file_handler = logging.FileHandler(os.path.join(log_dir, log_filename))
        # 设置等级
        file_handler.setLevel(file_handler_config.get('level', logging.DEBUG))
        # 设置格式
        file_handler.setFormatter(formatter)
        # 添加处理器
        logger.addHandler(file_handler)

    # 创建终端处理器
    console_handler_config = config.get('console_handler', {})
    console_handler = logging.StreamHandler()
    console_handler.setLevel(console_handler_config.get('level', logging.DEBUG))
    console_handler.setFormatter(formatter)
    logger.addHandler(console_handler)

    return logger


# 使用示例
logger_config = {
    'log_dir': 'logs',
    'name': 'MuYe',
    'log_level': logging.INFO,
    'file_handler': {
        'filename_format': "log_%Y-%m-%d_%H-%M.log",  # 修改这里
        'level': logging.INFO,
    },
    'console_handler': {
        'level': logging.DEBUG,
    },
    'formatter': {
        'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    }
}

logger = setup_logger(logger_config)
logger.info("This is an info message")

7、参考

Python基础之标准库logging
标准库系列:logging 日志打印

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2093387.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5G NR 辅同步信号SSS介绍 MATLAB实现

5G NR辅同步信号SSS,和PSS一起包含了小区的全部ID信息,跟NBIOT 和LTE不一样,PSS和SSS并不携带任何的帧信息,只携带帧头同步信息,所以搜索完成PSS和SSS并不知道当前的slot号和帧号,在5G NR中,PSS…

Clion 使用

1. 使用CLion进行ROS开发 安装基本的ROS环境 ROS环境的安装请参考安装ROS。 安装CLion 下载CLion Linux的下载地址如下:CLion 解压CLion 将下载的CLion复制到/opt目录下(你可以解压到适合自己的文件夹,只要保证后续使用的路径一致即可…

黑神话悟空-用签名检查以允许加载 mod .pak(安装MOD可以不用再使用“ -fileopenlog “命令)

安装 下载并解压到 BlackMythWukong\b1\Binaries\Win64 位置参考: 安装此 mod 后,再安装.pak类型MOD时就可以不再使用" -fileopenlog "命令也可以生效了.因为该命令可能会导致在具有常规 HDD 的低配置计算机上卡顿。 下载地址:h…

macos 10.15 Catalina 可用docker最新版本 Docker Desktop 4.15.0 (93002) 下载地址与安装方法

按照docker官方的4.16.0版本发行日志"4.16.0: (2023-01-12 Minimum OS version to install or update Docker Desktop on macOS is now macOS Big Sur (version 11) or later.)" , 这个4.16.0版本就必须要求最低版本os为 11版本, 所以 旧版本的macos 10.15 Catalina …

为了支持XR,3GPP R18都做了哪些增强?

这篇是R18 XR enhancement的第二篇,主要看下从NAS->L3->L2->L1针对XR都做了哪些增强。 1 PDU set QoS 在UL和DL中,XR-Awareness有助于优化gNB无线资源调度,但是这里就依赖于 PDU set和data burst。这两个东西是什么意思?其实PDU set就是由一个或多个 PDU组成,这…

【 OpenHarmony 系统应用源码解析 】-- Launcher 桌面布局

前言 阅读本篇文章之前,有几个需要说明一下: 调试设备:平板,如果你是开发者手机,一样可以加 Log 调试,源码仍然是手机和平板一起分析;文章中的 Log 信息所显示的数值可能跟你的设备不一样&…

C语言中的“#”和“##”

目录 开头1.什么是#?2.什么是##?3.#和##的实际应用输出变量的名字把两个符号连接成一个符号输出根据变量的表达式…… 下一篇博客要说的东西 开头 大家好,我叫这是我58。在今天,我们要学一下关于C语言中的#和##的一些知识。 1.什么是#? #&#xff0…

Datawhale X 李宏毅苹果书 AI夏令营-深度学入门task2:线性模型

1.线性模型 把输入的特征 x 乘上一个权重,再加上一个偏置就得到预测的结果,这样的模型称为线性模型(linear model) 2.分段线性模型 线性模型也许过于简单,x1 跟 y 可能中间有比较复杂的关系。线性模型有很大的限制&…

上书房信息咨询:商标相似性评估调研

商标相似性评估调研可以帮助确定商标之间的相似性程度,为商标注册、商标权利维护和商标侵权案件提供参考依据。以下是进行商标相似性评估调研的一般步骤: 1、收集商标信息:收集相关商标的注册证书、商标注册申请、商标注册公告等信息&#x…

【测试】——开发模型与测试模型

📖 前言:在软件开发过程中,理解和应用合适的开发模型与测试模型至关重要。本文将详细介绍几种常见的开发模型,如瀑布模型、螺旋模型、增量模型和敏捷过程,以及测试模型如V模型和W模型。 目录 🕒 1. 开发模型…

Mobile-Agent赛题分析和代码解读笔记(DataWhale AI夏令营)

前言 你好,我是GISer Liu,一名热爱AI技术的GIS开发者,本文是DataWhale 2024 AI夏令营的最后一期——Mobile-Agent赛道,关于赛题分析和代码解读的学习文档总结;这边作者也会分享自己的思路; 本文是对原视频的…

18045 前一个和后一个字符

### 思路 1. 读取输入的字符。 2. 判断输入是否为数字字符: - 如果不是数字字符,输出“error”。 - 如果是数字字符,进行以下判断: - 如果输入是0,输出“first”和1。 - 如果输入是9,输出8…

MACOS安装配置前端开发环境

官网下载安装Mac版本的谷歌浏览器以及VS code代码编辑器,还有在App Store中直接安装Xcode(里面自带git); node.js版本管理器nvm的下载安装如下: 参考B站:https://www.bilibili.com/video/BV1M54y1N7fx/?sp…

【Python 千题 —— 基础篇】评论倾向分析

Python 千题持续更新中 …… 脑图地址 👉:⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目描述 在某个电商平台的评论系统中,用户可以提交商品评论。为了分析评论的情感倾向,我们需要编写一个程序来处理用户评论,并对评论内容进行简单的分析和处理。…

在java中如何使用etcd的v2 和v3 api获取配置,并且对配置的变化进行监控和监听

etcd 和zookeeper 很像,都可以用来做配置管理。并且etcd可以在目前流行的Kubernetes中使用。 但是etcd 提供了v2版本合v3的版本的两种api。我们现在分别来介绍一下这两个版本api的使用。 一、Etcd V2版本API 1、java工程中使用maven引入 etcd v2的java api操作ja…

Pytorch实现自然风光图像场景分类识别(含训练代码和数据集)

Pytorch实现自然风光图像场景分类识别(含训练代码和数据集) 目录 Pytorch实现自然风光图像场景分类识别(含训练代码和数据集) 1. 前言 2. 自然风光图像场景分类数据集 (1)自然风光图像场景分类数据集 (2)自定义数据集 3. 自…

震惊!更换GPU会改变LLM的行为

文章目录 新发现前言1. Why this article ?2. Setup the experimentation3. The experiment results:A100/A10/30904. Why is it different?5. Why do the calculation differ depending on the GPU ?结论 新发现 最近在做RAG相关的工作,偶然间发现&a…

swift自定义数据集微调Qwen-7B大模型,转换模型后使用ollama跑起来

前文:swift微调Qwen-7B大模型-CSDN博客 我详细介绍了swift如何进行微调,但数据集均来自魔搭社区,如何想训练自定义数据集,实际上也很简单。 一、自定义数据集微调 export MKL_THREADING_LAYERGNU \ CUDA_VISIBLE_DEVICES0,1,2…

STM32:TIM定时中断配置的最全库函数讲解笔记

声明:本博客为哔哩哔哩up主江协科技 “STM32入门教程”的听课笔记,仅供学习、参考使用,不得用作其他用途,违者必究。如有版权问题,请联系作者修改。 目录 一、综述 二、TIM库 初始化 2.1、TIM_DeInit 恢复缺省值 …

经典文献阅读之--ParkingE2E(基于摄像头的端到端停车网络:从图像到规划)

0. 简介 自动泊车是智能驾驶领域的一项关键任务。传统泊车算法通常采用基于规则的方案来实现。然而,由于算法设计的复杂性,这些方法在复杂的泊车场景中效果欠佳。相比之下,基于神经网络的方法往往比基于规则的方法更加直观且功能多样。通过收…