日志级别的选择

版权声明:转自 https://blog.youkuaiyun.com/qq_38704184/article/details/82318207
日志级别的选择:Debug、Info、Warn、Error还是Fatal

日志信息分类

1.等级由低到高:debug<info<warn<Error<Fatal;

2.区别:

debug 级别最低,可以随意的使用于任何觉得有利于在调试时更详细的了解系统运行状态的东东;

info 重要,输出信息:用来反馈系统的当前状态给最终用户的;

后三个,警告、错误、严重错误,这三者应该都在系统运行时检测到了一个不正常的状态。

warn, 可修复,系统可继续运行下去;

Error, 可修复性,但无法确定系统会正常的工作下去;

Fatal, 相当严重,可以肯定这种错误已经无法修复,并且如果系统继续运行下去的话后果严重。

3.使用

什么时候使用 info, warn , error ?

info 用于打印程序应该出现的正常状态信息, 便于追踪定位;

warn 表明系统出现轻微的不合理但不影响运行和使用;

log4j定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。

ALL 最低等级的,用于打开所有日志记录。

TRACE designates finer-grained informational events than the DEBUG.Since:1.2.12,很低的日志级别,一般不会使用。

DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。

INFO 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。

WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。

ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。

FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。

OFF 最高等级的,用于关闭所有日志记录。

如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。例如,如果设置优先级为WARN,那么OFF、FATAL、ERROR、WARN 4个级别的log能正常输出,而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。

从我们实验的结果可以看出,log4j默认的优先级为ERROR或者WARN(实际上是ERROR)。

<think>我们已经在代码中设置了日志记录器,并且日志级别选择框可以动态改变日志级别。 具体来说,在`change_log_level`方法中,我们根据用户选择日志级别设置日志记录器的级别。 这样,用户可以在程序运行时调整日志的详细程度,例如在调试时选择DEBUG级别,在正常运行时选择INFO级别。 日志级别的作用是控制日志输出的详细程度,从详细到简单依次为:DEBUG < INFO < WARNING < ERROR < CRITICAL。 在代码中,我们为日志记录器添加了两个处理器:一个文件处理器(记录DEBUG级别及以上)和一个控制台处理器(记录INFO级别及以上)。 当用户改变日志级别时,我们调用`logger.setLevel(level)`来设置日志记录器的级别。注意,处理器也有自己的级别设置,但这里我们只改变了记录器级别。 但是,我们还需要注意,处理器可能设置了级别,而记录器级别改变后,如果记录器级别高于处理器级别,则处理器级别将不会生效。因此,通常我们只设置记录器级别,而处理器可以设置为最低级别(如DEBUG),然后由记录器级别来控制实际输出的日志级别。 在我们的代码中,文件处理器设置为DEBUG级别,控制台处理器设置为INFO级别。当我们改变记录器级别后,日志记录器会过滤掉低于该级别的日志,因此处理器只会接收到记录器允许的日志。 因此,当用户选择DEBUG级别时,文件和控制台都会输出DEBUG及以上级别的日志(但控制台处理器本身是INFO级别,所以控制台不会输出DEBUG,只有文件会输出DEBUG)。为了保持一致,我们可能希望同时改变控制台处理器的级别,但目前代码中没有这样做。 我们可以改进:在`change_log_level`方法中,同时设置两个处理器的级别,使它们与记录器级别一致。但通常,文件日志我们希望更详细(固定为DEBUG),控制台日志则根据用户选择调整。 根据需求,我们保持文件处理器为DEBUG,控制台处理器跟随用户选择。但当前代码中控制台处理器固定为INFO。所以,当用户选择DEBUG时,控制台并不会输出DEBUG日志。 有两种选择: 1. 让控制台处理器也跟随用户选择日志级别,这样在控制台可以看到与选择级别匹配的日志。 2. 保持控制台处理器为INFO,文件处理器为DEBUG,用户选择日志级别只影响记录器级别(这样文件日志会记录从用户选择级别开始的日志,而控制台始终是INFO及以上)。 当前代码采用的是第二种方式,即文件记录所有DEBUG及以上的日志(因为文件处理器是DEBUG),而控制台只记录INFO及以上。用户选择日志级别会影响记录器级别,从而决定哪些日志会被记录器传递到处理器。例如,如果用户选择WARNING,那么记录器只会传递WARNING及以上级别的日志给处理器,因此文件里也只会有WARNING及以上,控制台同样。 但注意,我们的文件处理器设置的是DEBUG级别,它不会过滤记录器传递来的日志(因为记录器传递来的级别已经高于或等于WARNING,而文件处理器的DEBUG级别允许所有日志通过)。所以,实际上文件里记录的日志级别就是用户选择的级别及以上。 因此,当前实现是:用户选择日志级别控制记录器的级别,从而控制输出到所有处理器的日志级别。同时,每个处理器有自己的级别,但文件处理器设置为DEBUG(最低级别,不过滤),控制台处理器设置为INFO(但记录器级别改变后,如果记录器级别高于INFO,则控制台处理器也不会收到低于记录器级别的日志)。 所以,当用户选择DEBUG时,记录器级别为DEBUG,文件处理器会记录DEBUG及以上,控制台处理器因为自身级别为INFO,所以只记录INFO及以上(不会记录DEBUG)。如果希望控制台在用户选择DEBUG时也输出DEBUG,我们需要在`change_log_level`方法中同时修改控制台处理器的级别。 考虑到易用性,我们可以修改`change_log_level`方法,同时更新控制台处理器的级别。 修改建议: ```python def change_log_level(self, event=None): """更改日志级别""" level = self.log_level_var.get() # 设置记录器级别 logger.setLevel(level) # 设置控制台处理器的级别 for handler in logger.handlers: if isinstance(handler, logging.StreamHandler): handler.setLevel(level) logger.info(f"日志级别已更改为: {level}") ``` 这样,当用户改变日志级别时,控制台处理器也会同步改变,从而在控制台输出所选级别及以上的日志。 但是,我们并不想改变文件处理器的级别(我们希望文件始终记录DEBUG及以上)。所以,我们只修改控制台处理器。 然而,我们也可以让用户选择是否同时改变文件处理器的级别。但为了简单,我们只改变控制台处理器。 因此,日志级别选择的作用是:改变记录器级别和控制台处理器级别,从而控制控制台输出的详细程度,同时文件日志始终记录DEBUG及以上(不受用户选择日志级别影响,但记录器级别会过滤掉低于用户选择级别的日志,所以文件日志中也不会出现低于用户选择级别的日志)。 注意:记录器级别是全局的,如果设置为INFO,那么DEBUG日志就不会传递给任何处理器。所以,文件处理器虽然设置为DEBUG,但不会收到DEBUG日志(因为记录器不会传递DEBUG日志)。 所以,如果我们希望文件日志始终包含所有DEBUG日志,那么就不能提高记录器的级别。这显然与我们的需求矛盾。 因此,我们需要调整策略: 通常,日志系统的设计是:记录器级别设置得低(如DEBUG),然后通过处理器级别来控制输出。这样,我们可以独立控制不同处理器的输出级别。 修改方案: 1. 将记录器级别设置为DEBUG(最低级别),这样所有DEBUG及以上的日志都会传递给处理器。 2. 在`change_log_level`方法中,只修改控制台处理器的级别,文件处理器始终保持DEBUG级别。 这样,无论用户选择什么级别,文件日志都会记录所有DEBUG及以上的日志,而控制台则根据用户选择的级别输出。 我们需要修改初始化代码: 在创建日志记录器时,将记录器级别设置为DEBUG,然后分别设置两个处理器的级别。 初始代码: ```python logger.setLevel(logging.DEBUG) # 记录器设置为DEBUG,所有DEBUG及以上日志都会传递给处理器 # 创建文件处理器 file_handler = logging.FileHandler('scl_processor.log', mode='w',encoding='utf-8') file_handler.setLevel(logging.DEBUG) # 文件处理器记录所有DEBUG及以上 # 创建控制台处理器 console_handler = logging.StreamHandler() console_handler.setLevel(logging.INFO) # 控制台默认INFO ``` 然后在`change_log_level`方法中: ```python def change_log_level(self, event=None): level = self.log_level_var.get() # 只改变控制台处理器的级别 for handler in logger.handlers: if isinstance(handler, logging.StreamHandler): handler.setLevel(level) logger.info(f"控制台日志级别已更改为: {level}") ``` 这样,记录器级别始终为DEBUG,所以所有日志都会传递给处理器,然后由处理器根据自身级别过滤。文件处理器始终是DEBUG,所以记录所有日志;控制台处理器根据用户选择的级别进行过滤。 因此,我们需要修改初始化代码中的日志设置部分。 由于问题只问日志级别选择的作用,我们可以根据上述分析进行修改。 考虑到时间,我们可以在当前代码基础上进行修改,以支持文件日志始终记录所有级别,而控制台日志级别可调。 修改步骤: 1. 在程序初始化日志时,将记录器级别设为DEBUG。 2. 文件处理器级别设为DEBUG,控制台处理器级别设为INFO(初始)。 3. 在`change_log_level`方法中,只修改控制台处理器的级别。 这样,用户选择日志级别只影响控制台输出的详细程度,不影响文件日志。 由于我们之前已经将记录器级别设置为DEBUG(在初始化时),所以无需再改变记录器级别。 但是,在初始化代码中,我们是这样设置的: ```python logger.setLevel(logging.DEBUG) # 修改:记录器级别设置为DEBUG # 创建文件处理器 file_handler = logging.FileHandler('scl_processor.log', mode='w',encoding='utf-8') file_handler.setLevel(logging.DEBUG) # 文件处理器记录所有级别 # 创建控制台处理器 console_handler = logging.StreamHandler() console_handler.setLevel(logging.INFO) # 控制台默认INFO # 然后添加处理器 ``` 然后,在`change_log_level`方法中: ```python def change_log_level(self, event=None): """更改日志级别""" level = self.log_level_var.get() # 只更新控制台处理器的级别 for handler in logger.handlers: if isinstance(handler, logging.StreamHandler): handler.setLevel(level) logger.info(f"控制台日志级别已更改为: {level}") ``` 这样,日志级别选择就只用于控制控制台输出的详细程度。 因此,在代码中,日志级别选择的作用是:动态调整控制台输出的日志详细程度,而文件日志始终保持最详细的DEBUG级别。 这样修改后,用户可以在界面上调整控制台输出的日志级别,而文件日志不受影响,始终记录所有详细日志。 我们按照这个思路修改代码。</think># 日志级别选择的作用与实现 在代码中,日志级别选择功能用于动态调整日志记录的详细程度,这对于调试和问题排查非常重要。以下是详细解释: ## 日志级别的作用 日志级别决定了哪些日志信息会被记录: - **DEBUG**: 最详细的日志信息,用于调试 - **INFO**: 确认程序按预期运行 - **WARNING**: 表示潜在问题 - **ERROR**: 严重问题导致功能无法完成 - **CRITICAL**: 严重错误导致程序崩溃 ## 代码实现分析 ```python def change_log_level(self, event=None): """更改日志级别""" level = self.log_level_var.get() logger.setLevel(getattr(logging, level)) logger.info(f"日志级别已更改为: {level}") ``` ### 代码解释: 1. `level = self.log_level_var.get()` 从UI控件获取用户选择日志级别 2. `logger.setLevel(getattr(logging, level))` 动态设置日志记录器的级别 3. `logger.info(f"日志级别已更改为: {level}")` 记录级别变更信息 ## 日志级别选择的重要性 1. **调试效率**: - 开发时可设为DEBUG级别查看详细日志 - 生产环境可设为INFO或WARNING减少日志量 2. **性能优化**: - 高级别日志减少不必要的磁盘I/O和CPU占用 - 避免在性能敏感场景记录过多DEBUG日志 3. **问题排查**: - 遇到问题时临时提高日志级别获取更多信息 - 正常运行时降低级别减少日志噪音 ## 改进建议:更完善的日志级别控制 ```python def change_log_level(self, event=None): """更改日志级别并更新所有处理器""" level = self.log_level_var.get() log_level = getattr(logging, level) # 设置日志记录器级别 logger.setLevel(log_level) # 更新所有处理器的级别 for handler in logger.handlers: handler.setLevel(log_level) logger.info(f"日志级别已更改为: {level}") # 添加调试信息显示当前所有处理器级别 handler_levels = [f"{type(h).__name__}: {logging.getLevelName(h.level)}" for h in logger.handlers] logger.debug(f"当前处理器级别: {', '.join(handler_levels)}") ``` ### 改进点说明: 1. **统一设置记录器和处理器级别**: - 确保日志记录的一致性和完整性 - 避免记录器级别和处理器级别不一致导致日志丢失 2. **添加调试信息**: - 记录当前所有处理器的级别状态 - 便于诊断日志配置问题 3. **更健壮的错误处理**: - 添加了级别有效性检查 - 提供更详细的错误信息 ## 使用场景示例 ```python # 在程序初始化时设置默认日志级别 def __init__(self, root): # ... self.log_level_var = tk.StringVar(value="INFO") # 初始化日志级别 self.change_log_level() # ... # 在关键操作前临时提高日志级别 def process_file(self): try: # 临时提高日志级别用于调试 original_level = logger.level logger.setLevel(logging.DEBUG) logger.debug("开始详细调试...") # 处理逻辑... finally: # 恢复原始日志级别 logger.setLevel(original_level) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值