Python学习第十二天——logging

2023-11-20

1.日志级别

CRITICAL = 50 #FATAL = CRITICAL
ERROR = 40
WARNING = 30 #WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0 #不设置
日志的设置是自下而上的,如果等级为ERROR,那么比他等级低的将不会被写入日志。

2. 默认级别为warning,默认打印到终端

import logging

logging.debug(‘调试debug’)
logging.info(‘消息info’)
logging.warning(‘警告warn’)
logging.error(‘错误error’)
logging.critical(‘严重critical’)

‘’’
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
‘’’

3.为logging模块指定全局配置,针对所有logger有效,控制打印到文件中

logging.basicConfig() 介绍
可在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有
filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

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 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息

使用:
import logging
logging.basicConfig(filename=‘access.log’,
format=’%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s’,
datefmt=’%Y-%m-%d %H:%M:%S %p’,
level=10)

logging.debug(‘调试debug’)
logging.info(‘消息info’)
logging.warning(‘警告warn’)
logging.error(‘错误error’)
logging.critical(‘严重critical’)

结果:
access.log内容:
2017-07-28 20:32:17 PM - root - DEBUG -test: 调试debug
2017-07-28 20:32:17 PM - root - INFO -test: 消息info
2017-07-28 20:32:17 PM - root - WARNING -test: 警告warn
2017-07-28 20:32:17 PM - root - ERROR -test: 错误error
2017-07-28 20:32:17 PM - root - CRITICAL -test: 严重critical

part2: 可以为logging模块指定模块级的配置,即所有logger的配置

4.logging模块的Formatter,Handler,Logger,Filter对象logging模块流程分析

#logger:产生日志的对象

#Filter:过滤日志的对象

#Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端

#Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式

5.Logger与Handler的级别

logger是第一级过滤,然后才能到handler,我们可以给logger和handler同时设置level,但是需要注意的是
Logger is also the first to filter the message based on a level — if you set the logger to INFO, and all handlers to DEBUG, you still won’t receive DEBUG messages on handlers — they’ll be rejected by the logger itself. If you set logger to DEBUG, but all handlers to INFO, you won’t receive any DEBUG messages either — because while the logger says “ok, process this”, the handlers reject it (DEBUG < INFO).

#验证
import logging

form=logging.Formatter(’%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s’,datefmt=’%Y-%m-%d %H:%M:%S %p’,)

ch=logging.StreamHandler()

ch.setFormatter(form)
#ch.setLevel(10)
ch.setLevel(20)

l1=logging.getLogger(‘root’)
#l1.setLevel(20)
l1.setLevel(10)
l1.addHandler(ch)

l1.debug(‘l1 debug’)

6.Logger的继承(了解)

import logging

formatter=logging.Formatter(’%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s’,datefmt=’%Y-%m-%d %H:%M:%S %p’,)

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

logger1=logging.getLogger(‘root’)
logger2=logging.getLogger(‘root.child1’)
logger3=logging.getLogger(‘root.child1.child2’)

logger1.addHandler(ch)
logger2.addHandler(ch)
logger3.addHandler(ch)
logger1.setLevel(10)
logger2.setLevel(10)
logger3.setLevel(10)

logger1.debug(‘log1 debug’)
logger2.debug(‘log2 debug’)
logger3.debug(‘log3 debug’)

‘’’
2017-07-28 22:22:05 PM - root - DEBUG -test: log1 debug
2017-07-28 22:22:05 PM - root.child1 - DEBUG -test: log2 debug
2017-07-28 22:22:05 PM - root.child1 - DEBUG -test: log2 debug
2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test: log3 debug
2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test: log3 debug
2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test: log3 debug
‘’’

7.应用

“”"
logging配置
“”"

import os
import logging.config

定义三种日志输出格式 开始

standard_format = ‘[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]’
‘[%(levelname)s][%(message)s]’ #其中name为getlogger指定的名字

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

id_simple_format = ‘[%(levelname)s][%(asctime)s] %(message)s’

定义日志输出格式 结束

logfile_dir = os.path.dirname(os.path.abspath(file)) # log文件的目录

logfile_name = ‘all2.log’ # log文件名

如果不存在定义的日志目录就创建一个

if not os.path.isdir(logfile_dir):
os.mkdir(logfile_dir)

log文件的全路径

logfile_path = os.path.join(logfile_dir, logfile_name)

log配置字典

logging配置文件:
LOGGING_DIC = {
‘version’: 1,
‘disable_existing_loggers’: False,
‘formatters’: {
‘standard’: {
‘format’: standard_format
},
‘simple’: {
‘format’: simple_format
},
},
‘filters’: {},
‘handlers’: {
#打印到终端的日志
‘console’: {
‘level’: ‘DEBUG’,
‘class’: ‘logging.StreamHandler’, # 打印到屏幕
‘formatter’: ‘simple’
},
#打印到文件的日志,收集info及以上的日志
‘default’: {
‘level’: ‘DEBUG’,
‘class’: ‘logging.handlers.RotatingFileHandler’, # 保存到文件
‘formatter’: ‘standard’,
‘filename’: logfile_path, # 日志文件
‘maxBytes’: 102410245, # 日志大小 5M
‘backupCount’: 5,
‘encoding’: ‘utf-8’, # 日志文件的编码,再也不用担心中文log乱码了
},
},
‘loggers’: {
#logging.getLogger(__ name __)拿到的logger配置
‘’: {
‘handlers’: [‘default’, ‘console’], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
‘level’: ‘DEBUG’,
‘propagate’: True, # 向上(更高level的logger)传递
},
},
}

def load_my_logging_cfg():
logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置
logger = logging.getLogger(__ name __) # 生成一个log实例
logger.info(‘It works!’) # 记录该文件的运行状态

if __ name __ == ‘__ main __’:
load_my_logging_cfg()

使用
“”"
MyLogging Test
“”"
import time
import logging
import my_logging # 导入自定义的logging配置

logger = logging.getLogger(__ name __) # 生成logger实例

def demo():
logger.debug(“start range… time:{}”.format(time.time()))
logger.info(“中文测试开始。。。”)
for i in range(10):
logger.debug(“i:{}”.format(i))
time.sleep(0.2)
else:
logger.debug(“over range… time:{}”.format(time.time()))
logger.info(“中文测试结束。。。”)

if __ name __ == “__ main __”:
my_logging.load_my_logging_cfg() # 在你程序文件的入口加载自定义logging配置
demo()

注意注意注意:
!!!关于如何拿到logger对象的详细解释!!!
#1、有了上述方式我们的好处是:所有与logging模块有关的配置都写到字典中就可以了,更加清晰,方便管理

#2、我们需要解决的问题是:
1、从字典加载配置:logging.config.dictConfig(settings.LOGGING_DIC)
2、拿到logger对象来产生日志
logger对象都是配置到字典的loggers 键对应的子字典中的
按照我们对logging模块的理解,要想获取某个东西都是通过名字,也就是key来获取的
于是我们要获取不同的logger对象就是
logger=logging.getLogger(‘loggers子字典的key名’)

但问题是:如果我们想要不同logger名的logger对象都共用一段配置,那么肯定不能在loggers子字典中定义n个key
‘loggers’: {
‘l1’: {
‘handlers’: [‘default’, ‘console’], #
‘level’: ‘DEBUG’,
‘propagate’: True, # 向上(更高level的logger)传递
},
'l2: {
‘handlers’: [‘default’, ‘console’ ],
‘level’: ‘DEBUG’,
‘propagate’: False, # 向上(更高level的logger)传递
},
‘l3’: {
‘handlers’: [‘default’, ‘console’], #
‘level’: ‘DEBUG’,
‘propagate’: True, # 向上(更高level的logger)传递
},

}

#我们的解决方式是,定义一个空的key
‘loggers’: {
‘’: {
‘handlers’: [‘default’, ‘console’],
‘level’: ‘DEBUG’,
‘propagate’: True,
},

}

这样我们再取logger对象时
logging.getLogger(__ name __),不同的文件__name __不同,这保证了打印日志时标识信息不同,但是拿着该名字去loggers里找key名时却发现找不到,于是默认使用key=’'的配置

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python学习第十二天——logging 的相关文章

随机推荐

  • 不同数据库获取新增加的主键值

    不同数据库获取新增加的主键值 数据库 获取新增主键的查询语句 DB2 IDENTITY VAL LOCAL Informix SELECT dbinfo sqlca sqlerrd1 FROM table Sybase SELECT IDE
  • LeetCode刷题-4

    数组 35 搜索插入位置 题目描述 题目样例 Java方法 二分查找 思路及算法 代码 执行结果 复杂度 题目描述 给定一个排序数组和一个目标值 在数组中找到目标值 并返回其索引 如果目标值不存在于数组中 返回它将会被按顺序插入的位置 请必
  • MySQL 通配符学习小结

    原文 http blog csdn net ithomer article details 5130386 MySQL 通配符 SQL的模式匹配允许你使用 匹配任何单个字符 而 匹配任意数目字符 包括零个字符 在 MySQL中 SQL的模式
  • 归并排序求逆序对

    一 归并排序原理 归并排序采用分治算法 将对整个数组排序的问题转化为合并两个有序子序列的问题 一 1 思想方法 以上是对数组进行排序的过程 首先 我们可认为 当区间长度为1时 每个区间都是有序的 接着 我们合并这些长度为1的区间 得到了第二
  • 抖音如何变现(赚钱)

    未来 每个人都能出名15分钟 安迪 沃霍尔 美国著名波谱艺术领袖 有必要见一下伟大预言家的风采 预言了短视频的兴起 突如一夜春风来 五洲四海刷抖音 2017 2018抖音突然火起了 从城市到农村 从国内到国外 从老人到小孩 从男人到女人 各
  • 小程序云服务器带宽要求,小程序云服务器带宽要求

    小程序云服务器带宽要求 内容精选 换一换 当您发现云服务器的运行速度变慢或云服务器突然出现网络断开的情况 则可能是云服务器的带宽和CPU利用率过高导致 如果您已经通过云监控服务创建过告警任务 当CPU或带宽利用率高时 系统会自动发送告警给您
  • JSONObject与JSONArray的简单使用

    JSONObject 大家看到JSONObject就应该真的这个类是和Json格式相关的吧 没错 JSONObject就是将数据json化的一个类 它是以键值对存在的 key value形式和map类型比较相像 下面我们先来简单使用一下这个
  • React class组件、react-hook函数组件分别实现五子棋

    react class类组件 react hook函数组件分别实现五子棋 前言 使用create react app脚手架简单搭建 不用安装其他依赖 纯 js css实现 这里就只是简单的说明目录结构和思路 具体的代码实现请转到 Githu
  • 解决:Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:

    报错信息如下 org apache ibatis exceptions PersistenceException Error querying database Cause com mysql jdbc exceptions jdbc4 M
  • 【学习笔记】开源中文对话预训练模型调研总结

    开源中文对话预训练模型调研 文章目录 开源中文对话预训练模型调研 1 CDial GPT 主要工作 LCCC数据集 数据清洗策略 基于规则的清洗 基于分类器的清洗 模型 输入表征 训练 2 GPT2 chitchat 3 EVA1 0 WD
  • 网络安全态势感知和OODA模型

    网络安全已经成为全球范围内的重要问题之一 随着信息化和数字化的发展 各种网络攻击和威胁不断出现 给个人 企业 组织和国家带来了巨大的安全风险和经济损失 为了应对这一挑战 网络安全态势感知和OODA模型成为了网络安全领域中非常重要的工具 一
  • python 安装selenium最方便的方法

    dp MacBook Pro 3 chromedriver mac arm64 apple pip install chromedriver autoinstaller Looking in indexes http pypi tuna t
  • springmvc多视图解析

  • linux 复位usb设备 模拟热插拔脚本

    获取USB设备数量 DEVICE NUM lspci grep USB awk F print 1 wc l 获取设备号 DEVICE lspci grep USB awk F print 0000 1 sed n i p 设备解绑 ech
  • IPsec ISAKMP

    Interne 安全连接和密钥管理协议 ISAKMP 是 IPsec 体系结构中的一种主要协议 该协议结合认证 密钥管理和安全连接等概念来建立政府 商家和因特网上的私有通信所需要的安全 因特网安全联盟和密钥管理协议 ISAKMP 定义了程序
  • 力软-获取jfGrid值,并改变值

    问题 页面中jfGrid为动态加载出来的 在js中动态改变cell值之后 需要将jfGrid的值重新赋值一遍 解决 var rowindex 0 jfgrid layout 0 jfGridGet rowdatas rowindex F R
  • Android 在模拟器上使用Geocoder解析Location报 grpc failed无解

    在做定位功能时 用Geocoder解析Location报了一个错 我把模拟器位置设立在印度孟买 按理说Location正常 经纬度可用 应该没问题 但却给我报出异常 在翻了很多资料后感觉是模拟器的原因 因为我在真机上定位的地方都能解析 而且
  • 小白入门C#初探Web简易页面显示信息小案例

    1 创建新项目 选择ASP NET Core Web应用 模型 视图 控制器 然后点击下一步 然后在项目名称里面填写CSharpDemo 点击下一步 直至创建即可 目录结构 Connected Services 是Visual Studio
  • CentOS 8安装并配置NFS服务

    先决条件 我们假设您有一台运行CentOS 8的服务器 我们将在该服务器上设置NFS服务器和其他充当NFS客户端的计算机 服务器和客户端应该能够通过专用网络相互通信 如果您的托管服务提供商不提供私有IP地址 则可以使用公共IP地址并配置服务
  • Python学习第十二天——logging

    1 日志级别 CRITICAL 50 FATAL CRITICAL ERROR 40 WARNING 30 WARN WARNING INFO 20 DEBUG 10 NOTSET 0 不设置 日志的设置是自下而上的 如果等级为ERROR