Java java.util.logging 框架中定制化日志消息的实践

Java java.util.logging 框架中定制化日志消息的实践

本教程旨在指导开发者如何在 java `java.util.logging` 框架中灵活定制日志消息。通过修改 `logger.log()` 或 `logger.info()` 等方法的参数,开发者可以为每次日志记录提供具体且有意义的上下文信息,从而提升日志的可读性和问题排查效率,避免千篇一律的通用日志输出。

软件开发中,日志是诊断问题、监控应用行为和理解系统运行状态的关键工具。Java 内置的 java.util.logging 框架提供了一套完整的日志记录机制。然而,仅仅记录通用或静态的日志消息往往不足以提供足够的上下文信息,尤其是在复杂的系统或异常场景下。为了提高日志的实用性和可读性,定制化日志消息变得至关重要。

核心实践:定制化日志消息

java.util.logging.Logger 类提供了多种方法来记录日志,其中最常用的是 info()、warning()、severe() 等快捷方法,以及更通用的 log() 方法。这些方法的核心在于它们的 msg 参数,它允许开发者传入一个字符串,这个字符串就是最终记录到日志中的消息。

当我们需要记录不同且具有特定上下文的消息时,关键在于在调用日志方法时,动态地构造或选择合适的字符串作为 msg 参数。

考虑以下原始示例代码,其中日志消息是固定的:

立即学习“Java免费学习笔记(深入)”;

import java.util.logging.FileHandler;import java.util.logging.Level;import java.util.logging.Logger;import java.util.logging.SimpleFormatter;public class Example {    private static final Logger logger = Logger.getLogger("MyLog");    public static void init(){        FileHandler fh;        try {            fh = new FileHandler("/Users/hp/Desktop/example1.log");            // fh = new FileHandler("/Users/hp/Desktop/example1.log", true); // 用于追加模式            logger.addHandler(fh);            SimpleFormatter formatter = new SimpleFormatter();            fh.setFormatter(formatter);            logger.info("Logger Initialized"); // 静态消息        } catch(Exception e) {            logger.log(Level.WARNING,"Exception ::", e); // 静态消息前缀        }    }    public static void main(String args[]) {        init();        try {            int a = 10/0; // 模拟算术异常        }        catch (Exception e) {            logger.log(Level.WARNING, "Exception ::",e); // 静态消息前缀        }        logger.info("End of program"); // 静态消息    }}

在上述代码中,无论发生何种异常,日志中都会出现 “Exception ::” 这个前缀,这使得在日志文件中区分不同的异常情况变得困难。为了实现消息的定制化,我们需要修改 msg 参数。

修改方案:

我们可以根据具体的上下文,在调用 logger.log() 或 logger.info() 时,传入更具描述性的消息字符串。

import java.io.IOException;import java.util.logging.FileHandler;import java.util.logging.Level;import java.util.logging.Logger;import java.util.logging.SimpleFormatter;public class CustomLogExample {    private static final Logger logger = Logger.getLogger("MyCustomLog");    private static final String LOG_FILE_PATH = "/Users/hp/Desktop/custom_example.log"; // 定义日志文件路径    public static void initLogger() {        FileHandler fh = null;        try {            // 使用定义的路径,并允许追加模式            fh = new FileHandler(LOG_FILE_PATH, true);             logger.addHandler(fh);            SimpleFormatter formatter = new SimpleFormatter();            fh.setFormatter(formatter);            // 定制化日志初始化消息,包含文件路径信息            logger.info("日志系统已成功初始化,日志文件路径为: " + LOG_FILE_PATH);        } catch (IOException e) {            // 定制化异常日志消息            logger.log(Level.SEVERE, "日志文件处理器初始化失败,路径: " + LOG_FILE_PATH, e);        } catch (SecurityException e) {            logger.log(Level.SEVERE, "日志文件处理器初始化时发生安全异常,路径: " + LOG_FILE_PATH, e);        }    }    public static void main(String[] args) {        initLogger(); // 初始化日志系统        try {            int numerator = 10;            int denominator = 0;            // 尝试执行可能导致异常的操作            int result = numerator / denominator;             logger.info("计算结果为: " + result); // 正常操作的日志        } catch (ArithmeticException e) {            // 针对算术异常,提供具体的上下文信息            logger.log(Level.WARNING, "执行算术操作时发生错误:除数为零。详细信息:", e);            logger.warning("请检查输入参数,避免除数为零的情况。"); // 记录额外提示信息        } catch (Exception e) {            // 针对其他通用异常,提供更广泛的描述            logger.log(Level.SEVERE, "程序执行过程中发生未知异常。异常类型:" + e.getClass().getName(), e);        }        logger.info("程序执行完毕。"); // 定制化程序结束消息    }}

在上述改进后的代码中:

在 initLogger() 方法中,日志初始化消息现在包含具体的日志文件路径,例如 logger.info(“日志系统已成功初始化,日志文件路径为: ” + LOG_FILE_PATH);。在 catch 块中,针对 ArithmeticException,我们提供了更具体的错误描述:“执行算术操作时发生错误:除数为零。”。还添加了一条额外的 logger.warning(“请检查输入参数,避免除数为零的情况。”);,以提供操作建议。对于通用的 Exception 捕获,消息包含了异常的类名,例如 logger.log(Level.SEVERE, “程序执行过程中发生未知异常。异常类型:” + e.getClass().getName(), e);。

通过这种方式,日志文件中的记录将更具描述性,有助于快速定位问题。

进阶技巧:带参数的日志消息

Logger 类还提供了一个非常有用的重载方法:log(Level level, String format, Object… params)。这个方法允许你使用格式字符串和可变参数来构建日志消息,类似于 String.format()。这种方式的优点在于,只有当日志级别被激活时,才会进行字符串的拼接操作,从而在一定程度上优化了性能。

// 示例:使用带参数的日志消息public void processData(String dataId, int value) {    logger.log(Level.INFO, "正在处理数据。数据ID: {0}, 值为: {1}", new Object[]{dataId, value});    try {        // 模拟一些操作        if (value < 0) {            throw new IllegalArgumentException("值不能为负数");        }        logger.log(Level.FINE, "数据 {0} 处理成功。", dataId);    } catch (IllegalArgumentException e) {        logger.log(Level.WARNING, "处理数据 {0} 时发生参数错误:{1}", new Object[]{dataId, e.getMessage()});    }}// 在 main 方法中调用// new CustomLogExample().processData("ABC-123", 100);// new CustomLogExample().processData("XYZ-456", -5);

在这个例子中,{0} 和 {1} 是占位符,它们会分别被 Object… params 数组中的第一个和第二个元素替换。这种方法使得日志消息的结构更加清晰,并且避免了手动拼接字符串的繁琐。

日志消息定制的最佳实践

提供清晰的上下文: 日志消息应包含足够的信息来理解事件发生时的系统状态。例如,涉及用户操作时应包含用户ID,涉及数据处理时应包含数据ID,涉及网络请求时应包含请求URL等。保持简洁明了: 避免冗余或不必要的信息。日志消息应该直接、准确地描述事件,而不是长篇大论。使用合适的日志级别: 根据事件的严重性和重要性选择正确的日志级别(如 FINEST, FINE, INFO, WARNING, SEVERE)。这有助于在分析日志时进行过滤和分类。避免记录敏感信息: 绝不应将密码、个人身份信息 (PII) 或其他敏感数据直接记录到日志中,这可能导致安全漏洞。一致性: 保持日志消息格式和风格的一致性,这有助于日志的解析和自动化处理。可操作性: 对于错误或警告日志,如果可能,提供一些关于如何解决问题的提示或建议。

总结

通过灵活定制 java.util.logging 框架中的日志消息,开发者可以极大地提升日志的价值。从简单的字符串拼接,到使用带参数的格式化消息,每种方法都旨在提供更丰富、更具体的运行时信息。遵循最佳实践,不仅能让日志在故障排查时事半功倍,也能为系统监控和性能分析提供坚实的基础。告别千篇一律的通用日志,拥抱清晰、有用的定制化日志,是构建健壮、可维护应用程序的重要一步。

以上就是Java java.util.logging 框架中定制化日志消息的实践的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/198540.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
windows10如何解决“关键进程已死亡”的蓝屏问题_windows10蓝屏故障排查方法
上一篇 2026年9月10日 21:25:59
deepseek官方社区网址_加入deepseek官方社区官网交流
下一篇 2026年9月10日 21:30:00

相关推荐

  • Laravel中的CSRF保护机制是什么?

    laravel通过生成和验证唯一的token来实现csrf保护。1)生成token并嵌入表单,2)验证提交的token是否与session中的token匹配,3)可将特定路由排除在csrf保护之外,4)使用@csrf指令生成token,5)中间件自动验证token,确保请求经过csrf验证。 Lar…

    2026年9月20日
    000
  • 系统垃圾清理:专业工具使用与注意事项

    选择合适的系统清理工具并规范操作可有效提升电脑性能。CCleaner适合日常维护,Wise Disk Cleaner有助于释放空间,Glary Utilities功能全面,Dism++安全性高。使用前应创建还原点,仔细核对扫描结果,避免多工具同时运行。注意从官网下载软件,慎用注册表清理,避免频繁操作…

    2026年9月20日
    000
  • 如何在Java中定义一个包含参数的方法

    定义Java带参方法需明确访问修饰符、返回类型、方法名及参数列表。例如:public static int add(int a, int b) { return a + b; },调用时传入对应类型参数,如add(5, 3)输出结果8,参数类型必须匹配,否则编译错误。 在Java中定义一个包含参数的…

    2026年9月20日
    100
  • 灵绘AI如何生成3D效果_灵绘AI3D效果生成的实用教程

    启用灵绘AI的3D视图增强模式,输入含景深等关键词的提示词,调整视角与深度参数并启用Z轴分层,生成后使用光影滤镜增强立体感,最后导出为WebP 3D或OBJ格式以保留深度信息。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ 如果您希望使用灵…

    2026年9月20日
    000
  • mac怎么合并多个PDF文件_Mac合并PDF文件方法

    使用macOS可便捷合并PDF:1. 用预览拖拽缩略图或插入文件;2. 通过访达快速操作批量合并;3. 借助在线工具如iLovePDF处理。 如果您需要将多个PDF文件整合为一个文档以便于分享或管理,macOS系统提供了多种便捷的合并方式。以下是一些有效的操作步骤: 本文运行环境:MacBook P…

    2026年9月20日
    000
  • mysql如何优化like模糊查询

    优先使用前缀匹配并建立索引,避免前置通配符导致全表扫描;对大字段采用全文索引或外部搜索引擎如Elasticsearch;合理设计覆盖索引,减少SELECT *,提升查询效率。 在MySQL中,LIKE模糊查询虽然常用,但容易导致性能问题,特别是在数据量大的情况下。优化的关键在于减少全表扫描、提升索引…

    2026年9月20日
    000
  • win10默认网关不可用怎么办_win10默认网关错误修复方法

    1、重启路由器和网卡适配器可刷新网络状态;2、重置TCP/IP协议栈以修复通信故障;3、更新或重装网卡驱动解决兼容性问题;4、关闭电源管理节能设置确保网卡持续工作;5、设置IPv4自动获取地址以正确获取网关信息。 如果您尝试访问互联网,但网络连接显示“默认网关不可用”,则可能是由于网络配置或设备通信…

    2026年9月20日
    000
  • 为什么VSCode的CSS代码提示不全?

    答案:VSCode CSS提示不全通常由配置或环境问题导致。1. 确保文件语言模式为CSS并正确关联扩展名;2. 更新VSCode以支持现代CSS特性,自定义属性需插件辅助;3. 安装IntelliSense、Tailwind或PostCSS等插件增强提示功能;4. 检查settings.json中…

    2026年9月20日
    000
  • 使用ThinkPHP构建RESTful API的规范

    使用thinkphp可以构建符合restful api规范的应用。1)定义路由和控制器来处理请求,如get用户信息。2)使用中间件处理认证。3)利用缓存机制优化性能。通过这些步骤,thinkphp支持快速、高效地构建restful api。 你想知道如何使用ThinkPHP来构建一个符合RESTfu…

    2026年9月20日
    100
  • 如何在Linux中自动重启 Linux systemd自动恢复

    答案:通过配置systemd服务文件中的Restart、RestartSec、WatchdogSec及StartLimitInterval等参数,可实现Linux服务的自动重启与看门狗监控,并避免无限重启循环,提升系统稳定性。 在Linux中,可以通过systemd来实现服务的自动重启,确保服务在崩…

    2026年9月20日
    000
  • JAXB中动态获取Java对象QName并创建JAXBElement的反射策略

    本文探讨了在jaxb中,当`jaxbintrospector.getelementname`无法获取java对象对应的`qname`时,如何通过反射机制调用`objectfactory`中生成的`create`方法来动态创建`jaxbelement`。该方法避免了大量类型判断,提高了代码的灵活性和可…

    2026年9月20日
    000
  • windows10如何关闭输入法的相关广告和推荐_windows10输入法广告关闭方法

    1、关闭微软输入法个性化推荐:在设置中禁用广告ID和自学习功能;2、清除搜狗输入法广告:通过注册表删除通知权限并关闭推荐选项;3、禁用后台任务与启动项:在任务计划程序和启动管理中阻止输入法相关广告行为,彻底提升输入体验。 如果您在使用Windows 10的输入法时频繁遇到广告或推荐内容干扰输入体验,…

    2026年9月20日
    000
  • 电脑开机要按F1因BIOS设置错误通过恢复默认设置解决

    开机需按F1主因是BIOS检测到配置错误或硬件信息丢失,常见于CMOS电池没电、硬盘模式设置错误等;恢复默认设置可解决多数问题。 电脑开机提示按F1才能进入系统,多数情况是BIOS设置异常导致的。最常见的原因是CMOS电池没电、硬盘模式设置错误、软驱或启动设备配置问题等。这类问题通常可以通过恢复BI…

    2026年9月20日
    100
  • 428万行业最强跑分!荣耀高管:Magic8同是骁龙 大有不同

    10月16日消息,昨晚荣耀magic8系列正式亮相,全系搭载第五代骁龙8至尊版处理器,这款芯片目前处于行业性能巅峰地位。 该处理器采用台积电第三代3nm工艺打造,在相同性能下功耗降低10%。其CPU架构为2+6的八核设计,其中超大核主频高达4.6GHz,创下移动平台新纪录,大核频率则为3.62GHz…

    2026年9月20日
    100
  • 超级键盘侠兑换码分享 超级键盘侠最新兑换码大全2025

    超级键盘侠当前可用通用兑换码包括:KB888、HACK2025等,可在游戏中直接兑换黄金键帽皮肤、双倍经验卡及1000声望奖励,数量有限,先兑先得!部分代码还可用于修改器获取额外特权。 无限资源|游戏辅助工具: 2025最新超级键盘侠兑换码汇总如下: KB888:领取稀有黄金键帽外观 HACK202…

    2026年9月20日
    100
  • Mockito中利用自定义ArgumentMatcher实现集合内参数匹配

    mockito并未提供直接的`in()`参数匹配器来判断方法参数是否包含在指定集合中。本文将详细介绍如何利用`intthat`(或`argthat`)结合lambda表达式或自定义匹配器,灵活实现对方法参数是否属于某个集合的条件匹配,从而在测试存根(stubbing)或验证(verification…

    2026年9月20日
    000
  • Linux如何解决rpm依赖关系错误

    Linux如何解决rpm依赖关系错误Linux如何解决rpm依赖关系错误Linux如何解决rpm依赖关系错误Linux如何解决rpm依赖关系错误

    使用YUM可自动解决RPM依赖,通过yum localinstall安装本地包或yum install自动处理依赖;2. 较新系统推荐使用DNF,命令为dnf install 包名.rpm,依赖解析更高效;3. 无法使用YUM/DNF时可手动处理,通过rpm -ivh查看缺失依赖,再下载并按序安装;…

    2026年9月20日 用户投稿
    000
  • 监控工具(Prometheus+Grafana)配置

    使用prometheus和grafana可以构建高效的监控系统。1) 配置prometheus收集指标数据,通过prometheus.yml文件定义监控目标和抓取间隔。2) 使用grafana可视化数据,添加prometheus作为数据源并创建仪表板展示关键指标。 在现代的软件开发和运维中,监控系统…

    2026年9月20日
    000
  • Java中将包含嵌套列表的对象列表扁平化为单一元素列表的转换技巧

    本文探讨了在java中如何将一个包含嵌套列表的对象列表进行转换,使其生成一个新的列表,其中每个对象内部的嵌套列表只包含一个元素。文章详细介绍了三种实现方式:基于java 7及以前版本的传统循环方法、利用java 8至java 15的stream api结合`flatmap`操作,以及java 16及…

    2026年9月20日
    200
  • VSCode怎么查看NPM版本_VSCode NPM版本查询教程

    在VSCode中查看NPM版本,需打开集成终端并输入npm -v或npm –version。1. 使用快捷键Ctrl + (Windows/Linux)或Cmd + (macOS)打开终端;2. 输入命令npm -v执行;3. 终端将显示当前NPM版本号,如8.19.2。该方法可快速验证…

    2026年9月20日
    000

发表回复

登录后才能评论
关注微信