logging | 项目开发中日志模块logging在整个工程中的应用

2024-09-03 00:36

本文主要是介绍logging | 项目开发中日志模块logging在整个工程中的应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

日志模块

  • 日志介绍
  • 1. logging使用场景
    • 设置级别
  • 2. 实际logging使用 - 学习版
    • 2.1 终端输出StreamHandler
    • 2.2 日志文件中输出FileHandler
    • 2.3 同时写入终端和文件
    • 2.4 .Formatter参数语句
  • 3. 封装logging模块 - 实战版 ⭐
    • 3.1 配置config文件夹下project_config.py文件
      • time模块
    • 3.2 封装util文件夹下logging_until.py文件
    • 3.3 其他模块下的mycode文件
    • 注意事项
      • 解决

日志介绍

一个合格的程序,日志是必须要输出的。 我们借助Python的logging库,来完成日志输出。先编写基础的日志模块代码,可供业务逻辑代码使用。

所说的日志就是程序在运行时,程序当前处于什么状态,通过对外输出信息来确定。对外输出的这个信息,就是程序的运行日志。`

在这里插入图片描述

  • 级别

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

1. logging使用场景

# 注意使用场景   每个类型的级别不同 
logging.debug('debug 日志输出')  # 罗嗦模式
logging.info("info日志输出")     # 代码关键点输出
logging.warning("warning日志输出")  # 可能出问题地方 警告输出
logging.error("error日志输出")      # 出问题
logging.fatal("fatal中志输出")  # 致命的  程序无法执行时

在这里插入图片描述
默认是warnging级别以上的输出信息

设置级别

import logginglogging.getLogger().setLevel(10) # 只会输出 大于等于该数值的 logging# 注意使用场景
logging.debug('debug 日志输出')  # 罗嗦模式
logging.info("info日志输出")     # 代码关键点输出
logging.warning("warning日志输出")  # 可能出问题地方 警告输出
logging.error("error日志输出")      # 出问题
logging.fatal("fatal中志输出")  # 致命的  程序无法执行时

默认的warning级别是30,当设置为10的时候,所有的日志都可以看到 方便我们开发时使用
设置为30 则有些日志 不需要让用看到 产品简介 同时关键信息 是让开发人员获取

2. 实际logging使用 - 学习版

  • Pycharm目录结构
    在这里插入图片描述

在这里插入图片描述

2.1 终端输出StreamHandler

核心理解:

  1. 导入模块 (自己的文件名不要和内置模块名称重名,否则内置模块无法使用)
  2. 日志管理对象: 负责日志的收集工作
  3. 日志处理器: 负责日志的输出形式管理(终端/文件) 日志格式: 负责日志的输出格式管理
  4. 日志格式:
'%(asctime)s - [%(levelname)s] - %(filename)s[%(lineno)d]:%(message)s'
  • 设置logger对象 假设是logger.py
# 导包
import logging##################### 日志器对象的创建和配置 #####################
# 1. 日志器对象的创建
logger = logging.getLogger()# 2. 日志处理器的创建  输出到终端
stream_handler = logging.StreamHandler()# 3. 将日志处理器绑定到日志器对象上
logger.addHandler(stream_handler)# TODO: 4. 创建一个格式对象
fmt = logging.Formatter('%(asctime)s - [%(levelname)s] - %(filename)s[%(lineno)d]:%(message)s')# TODO: 5. 将日志格式对象绑定到日志处理器上
stream_handler.setFormatter(fmt)
  • 在模块文件中引入 mycode.py
 ######################### 日志的输出 ######################## 1. 设置日志输出级别logger.setLevel(logging.INFO)  # INFO级别以上的输出# 2. 输出不同级别的日志信息logger.debug('这是一个debug级别的日志信息')logger.info('这是一个info级别的日志信息')logger.warning('这是一个warning级别的日志信息')logger.error('这是一个error级别的日志信息')logger.critical('这是一个critical级别的日志信息')

在这里插入图片描述

2.2 日志文件中输出FileHandler

  • logger.py 输出到文件
# 导入logging模块
import logging#################### 日志器对象的创建和配置 ####################
# 1. 日志器对象的创建
logger = logging.getLogger()# TODO: 2. 创建换一个文件类型的日志处理器
# 注意: filename要传入一个log文件的路径,可以使用绝对路径也可以使用相对路径,但是文件目录一定要存在,文件可以不存在
# 举例: ../logs/test.log 路径中 logs目录必须存在, test.log可以不存在
file_handler = logging.FileHandler(filename='../logs/test.log',mode='a',encoding='utf8'
)
# 3. 将日志处理器绑定到日志器对象上
logger.addHandler(file_handler)
# 4. 创建一个格式对象
fmt = logging.Formatter('%(asctime)s - [%(levelname)s] - %(filename)s[%(lineno)d]:%(message)s')
# 5. 将日志格式对象绑定到日志处理器上
file_handler.setFormatter(fmt)
  • mycode.py
######################### 日志的输出 #######################
# 1. 设置日志输出级别
logger.setLevel(logging.INFO)
# 2. 输出不同级别的日志信息
logger.debug('这是一个debug级别的日志信息')
logger.info('这是一个info级别的日志信息')
logger.warning('这是一个warning级别的日志信息')
logger.error('这是一个error级别的日志信息')
logger.critical('这是一个critical级别的日志信息')

提前创建好该文件filename=‘…/logs/test.log’

2.3 同时写入终端和文件

file_handler logging.FileHandler('../logs/test.log')
file_handler1 =logging.FileHandler('../logs/test.log')
stream_handler logging.StreamHandler()fmt = logging.Formatter('%(asctime)s - [%(levelname)s] - %(filename)s[%(lineno)d]:%(message)s')file_handler.setFormatter(fmt)
file_handler1.setFormatter(fmt)
stream_handler.setFormatter(fmt)

2.4 .Formatter参数语句

‘%(asctime)s - [%(levelname)s] - %(filename)s[%(lineno)d]:%(message)s’

在这里插入图片描述

3. 封装logging模块 - 实战版 ⭐

在这里插入图片描述

3.1 配置config文件夹下project_config.py文件

测试和发布的时候通过更改配置文件可以更快的帮助我们提高效率

我们的需求是每个整点生成log日志文件,因此要结合time模块

import timelog_root_path = 'E:\\pythonProject\\pythonetl\\logs\\'
log_filename = f'pytel-{time.strftime("%Y%m%d-%H",time.localtime())}.log'
# print(log_filename)   pytel-20240902-16.logslevel = 10

time模块

import timeprint(time.time())   # 距离1970年过了多少秒 (以秒为单位)
print(time.localtime()) #  time.struct_time(tm_year=2024, tm_mon=9, tm_mday=2, tm_hour=16, tm_min=10, tm_sec=57, tm_wday=0, tm_yday=246, tm_isdst=0)print(time.strftime("%Y %m %d",time.localtime())) # 2024 09 02
print(time.strptime("2022-10-20 16:18:30","%Y-%m-%d %H:%M:%S"))

在这里插入图片描述

'''
常见的时间格式化的格式:
%Y:4位数字的年份:2024
%m:2位数字的月份:09
%d:2位数字的日期:02
%H:24小时制的小时
%M:2位数字的分钟
%S:2位数字的秒
如果要格式化为:2022-05-1510:05:55
'''

3.2 封装util文件夹下logging_until.py文件

这里不仅在终端进行了输出日志信息,同时在文件中保存了日志信息

import logging
import osfrom config.project_config import log_root_path,log_filename,level
class Logging():def __init__(self,level=20):self.logger = logging.getLogger()self.logger.setLevel(level)def init_logger():logger = Logging(level).logger# 缓存机制 避免日志重复输出  ⭐⭐if logger.handlers:return loggerpath = log_root_path+log_filename# 创建并打开文件with open(path, 'w') as file:# 文件被创建,但这里不写入任何内容,所以它是空的pass# 构造handler# 优化日志存储文件 StreamHandlerstream_handler = logging.StreamHandler()file_handler = logging.FileHandler(filename=path,mode='a',encoding='utf-8')fmt = logging.Formatter('%(asctime)s - [%(levelname)s] - %(filename)s[%(lineno)d]:%(message)s')stream_handler.setFormatter(fmt)file_handler.setFormatter(fmt)# 组合logger.addHandler(stream_handler)logger.addHandler(file_handler)return logger

3.3 其他模块下的mycode文件

  • 测试1
from util.logging_util import init_loggerlogger = init_logger()
logger.info('This is a test!!')
logger.info('This is aaaaaaaaaaaaaaaaa test!!')

在这里插入图片描述
在这里插入图片描述

  • 测试2
from util.logging_util import init_loggerlogger = init_logger()
logger.info('This is a test!!')
logger.info('This is aaaaaaaaaaaaaaaaa test!!')
logger.info('This is bbbbbbbbbbbbbbbbbbb test!!')

在这里插入图片描述
在这里插入图片描述

注意事项

若是在模块中这样运行代码

from util.logging_util import init_logger#错误用法#是因为python的缓存机制,第一次调用init_logger函数
#这时会添加filehandler streamhandle
init_logger().info("测试info1")
#第二次调用时,因为履存了rootlogger,所以再次会添加filehandler streamhandler
init_logger().info("测试info2")
#第三次就变成了三个hand1er
init_logger().info("测试info3")

在这里插入图片描述

解决

在logging_until.py的init_logger()中加入是否存在句柄的语句

def init_logger():logger = Logging(level).logger# 缓存机制 避免日志重复输出if logger.handlers:return logger
...

这篇关于logging | 项目开发中日志模块logging在整个工程中的应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131525

相关文章

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

将Java项目提交到云服务器的流程步骤

《将Java项目提交到云服务器的流程步骤》所谓将项目提交到云服务器即将你的项目打成一个jar包然后提交到云服务器即可,因此我们需要准备服务器环境为:Linux+JDK+MariDB(MySQL)+Gi... 目录1. 安装 jdk1.1 查看 jdk 版本1.2 下载 jdk2. 安装 mariadb(my

Python结合PyWebView库打造跨平台桌面应用

《Python结合PyWebView库打造跨平台桌面应用》随着Web技术的发展,将HTML/CSS/JavaScript与Python结合构建桌面应用成为可能,本文将系统讲解如何使用PyWebView... 目录一、技术原理与优势分析1.1 架构原理1.2 核心优势二、开发环境搭建2.1 安装依赖2.2 验

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

python logging模块详解及其日志定时清理方式

《pythonlogging模块详解及其日志定时清理方式》:本文主要介绍pythonlogging模块详解及其日志定时清理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录python logging模块及日志定时清理1.创建logger对象2.logging.basicCo

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

SpringShell命令行之交互式Shell应用开发方式

《SpringShell命令行之交互式Shell应用开发方式》本文将深入探讨SpringShell的核心特性、实现方式及应用场景,帮助开发者掌握这一强大工具,具有很好的参考价值,希望对大家有所帮助,如... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F