程序中记录日志一般有两个目的:Troubleshooting和显示程序运行状态。好的日志记录方式可以提供我们足够多定位问题的依据。日志记录大家都会认为简单,但如何通过日志可以高效定位问题并不是简单的事情。这里列举下面三个方面的内容,辅以代码示例,总结如何写好日志,希望对他人有所启发和帮助:

  • 怎样记日志可以方便Troubleshooting
  • 程序运行状态可以记哪些
  • 应该避免怎样的日志方式

怎样记日志可以方便Troubleshooting?

1. 对外部的调用封装

程序中对外部系统与模块的依赖调用前后都记下日志,方便接口调试。出问题时也可以很快理清是哪块的问题

  1. LOG.debug("Calling external system:" + parameters);
  2. Object result = null;
  3. try {
  4. result = callRemoteSystem(params);
  5. LOG.debug("Called successfully. result is " + result);
  6. } catch (Exception e) {
  7. LOG.warn("Failed at calling xxx system . exception : " + e);
  8. }

2.状态变化

程序中重要的状态信息的变化应该记录下来,方便查问题时还原现场,推断程序运行过程

  1. boolean isRunning;
  2. isRunning = true;
  3. LOG.info("System is running");
  4. //...
  5. isRunning = false;
  6. LOG.info("System was interrupted by " + Thread.currentThread().getName());

3.系统入口与出口:

这个粒度可以是重要方法级或模块级。记录它的输入与输出,方便定位

  1. void execute(Object input) {
  2. LOG.debug("Invoke parames : " + input);
  3. Object result = null;
  4. //business logic
  5. LOG.debug("Method result : " + result);
  6. }

4.业务异常:

任何业务异常都应该记下来:

  1. try {
  2. //business logical
  3. } catch (IOException e) {
  4. LOG.warn("Description xxx" , e);
  5. } catch (BusinessException e) {
  6. LOG.warn("Let me know anything");
  7. } catch (Exception e) {
  8. LOG.error("Description xxx", e);
  9. }

5.非预期执行:

为程序在“有可能”执行到的地方打印日志。如果我想删除一个文件,结果返回成功。但事实上,那个文件在你想删除之前就不存在了。最终结果是一致的,但程序得让我们知道这种情况,要查清为什么文件在删除之前就已经不存在

  1. int myValue = xxxx;
  2. int absResult = Math.abs(myValue);
  3. if (absResult < 0) {
  4. LOG.info("Original int " + myValue + "has nagetive abs " + absResult);
  5. }

6.很少出现的else情况:

else可能吞掉你的请求,或是赋予难以理解的最终结果

  1. Object result = null;
  2. if (running) {
  3. result = xxx;
  4. } else {
  5. result = yyy;
  6. LOG.debug("System does not running, we change the final result");
  7. }

程序运行状态可以记哪些?

程序在运行时就像一个机器人,我们可以从它的日志看出它正在做什么,是不是按预期的设计在做,所以这些正常的运行状态是要有的。

1. 程序运行时间:

  1. long startTime = System.currentTime();
  2. // business logical
  3. LOG.info("execution cost : " + (System.currentTime() - startTime) + "ms"); 

2. 大批量数据的执行进度:

  1. LOG.debug("current progress: " + (currentPos * 100 / totalAmount) + "%");

3.关键变量及正在做哪些重要的事情:

执行关键的逻辑,做IO操作等等

  1. String getJVMPid() {
  2. String pid = "";
  3. // Obtains JVM process ID
  4. LOG.info("JVM pid is " + pid);
  5. return pid;
  6. }
  7. void invokeRemoteMethod(Object params) {
  8. LOG.info("Calling remote method : " + params);
  9. //Calling remote server
  10. }

应该避免怎样的日志方式?

1. 混淆信息的Log

日志应该是清晰准确的: 当看到日志的时候,你知道是因为连接池取不到连接导致的问题么?

  1. Connection connection = ConnectionFactory.getConnection();
  2. if (connection == null) {
  3. LOG.warn("System initialized unsuccessfully");
  4. }

2. 记错位置

产品代码中,使用console记录日志,导致没有找到日志。

  1. } catch (ConfigurationException e) {
  2. e.printStackTrace();
  3. }

3. 记错级别

记错级别常常发生,常见的如:混淆代码错误和用户错误,如登录系统中,如果恶意登录,那系统内部会出现太多WARN,从而让管理员误以为是代码错误。可以反馈用户以错误,但是不要记录用户错误的行为,除非想达到控制的目的。

  1. LOG.warn("Failed to login by "+username+");

4. 遗漏信息

这里可能包含两种情况:(1)用户自己少写了信息,导致毫无参考价值;(2)用户调用log的方式导致丢失信息,如下例,没有stack trace.

    1. } catch (Exception ex) {
    2. log.error(ex);
    3. }

日志记录的作用和方法 java的更多相关文章

  1. 【学习笔记】开源日志记录工具log4j使用方法

    http://blog.csdn.net/zouqingfang/article/details/37558469 一.在MyEclipse中使用log4j的步骤比较简单,主要分为以下四个步骤: 1. ...

  2. .NET Worker Service 添加 Serilog 日志记录

    前面我们了解了 .NET Worker Service 的入门知识[1] 和 如何优雅退出 Worker Service [2],今天我们接着介绍一下如何为 Worker Service 添加 Ser ...

  3. Spring Boot 之日志记录

    Spring Boot 之日志记录 Spring Boot 支持集成 Java 世界主流的日志库. 如果对于 Java 日志库不熟悉,可以参考:细说 Java 主流日志工具库 关键词: log4j, ...

  4. 巧用CurrentThread.Name来统一标识日志记录(java-logback篇)

    ▄︻┻┳═一Agenda: ▄︻┻┳═一巧用CurrentThread.Name来统一标识日志记录 ▄︻┻┳═一巧用CurrentThread.Name来统一标识日志记录(续) ▄︻┻┳═一巧用Cur ...

  5. Hibernate使用Log4j日志记录(使用xml文件)

    日志记录使程序员能够将日志详细信息永久写入文件. Log4j和Logback框架可以在hibernate框架中使用来支持日志记录. 使用log4j执行日志记录有两种方法: 通过log4j.xml文件( ...

  6. Hibernate使用Log4j日志记录(使用properties文件)

    我们知道,Log4j和Logback框架可用于支持日志记录hibernate,使用log4j有两种执行日志记录的方法: 通过log4j.xml文件(或) 通过log4j.properties文件 在这 ...

  7. 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)

    前言: 本章介绍自己写的基于java.util.logging的轻量级日志记录库(baseLog). 该版本的日志记录库犹如其名,baseLog,是个实现日志记录基本功能的小库,适合小型项目使用,方便 ...

  8. java异常处理 日志记录异常具体位置的方法

    首先要在方法处抛出 Exception异常 然后在方法调用处try catch接收此异常对象 这样就能够记录异常具体位置了 控制台输出: 日志: 要点: System.getProperty(&quo ...

  9. Java学习笔记(十九)——Java 日志记录 AND log4j

    [前面的话] 学习的进度应该稍微在快一点. Java日志到了必须学习怎么使用的时候了,因为在项目中要进行使用.基础性文章,选择性阅读. [结构] java日志对调试,记录运行,问题定位都起到了很重要的 ...

随机推荐

  1. 吴裕雄 实战PYTHON编程(6)

    import matplotlib.pyplot as plt plt.rcParams['font.sans-serif']=['Simhei']plt.rcParams['axes.unicode ...

  2. mysql安装笔记-rpm

    基本内容: 1.需要解决两个依赖 2.需要解决一个包冲突 3.安装mysql服务,以及客户端client 4.修改root的随机密码 5.授予root用户,从任何机器访问任何数据库的任何表的权限 1. ...

  3. LOG4J spring与mybatis整合

    1.导入包log4j-1.2.17.jar <dependency>            <groupId>log4j</groupId>            ...

  4. Zabbix安装(server和agent)及基本配置

    简介 zabbix([`zæbiks])是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制 ...

  5. Win32 Debug & Release

    今天帮汤老师调试程序,他生成的程序不能运行,怀疑子程序之间编译顺序的问题:我试了之后,也出现同样的问题,但是把Win32 Debug 换成Win32 Release却可以运行了. 网上搜索了下,在CV ...

  6. 锁机制(Lock) 信号量机制(Semaphore) 事件机制(Event)

    IPC  进程间通信(inter-Process Communicate) 锁机制(Lock) l = Lock() 开启一个锁机制(实例化)   一把锁配一个钥匙 l.acquire()  获得钥匙 ...

  7. 乱序字符串anagrams

    [抄题]: 给出一个字符串数组S,找到其中所有的乱序字符串(Anagram).如果一个字符串是乱序字符串,那么他存在一个字母集合相同,但顺序不同的字符串也在S中. 对于字符串数组 ["lin ...

  8. iOS 代码调试

    僵尸对象导致crash(Thread 1:EXC_BAD_ACCESS(code=EXC_I386_GPFLT)),需要给位release模式,debug模式不打印内存地址 https://blog. ...

  9. [leetcode]496. Next Greater Element I下一个较大元素

    You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of n ...

  10. springmvc使用数组接收页面商品列表批量删除传过来的参数,并完成批量删除的操作。

    1.1 需求 在商品列表页面选中多个商品,然后删除. 1.2 需求分析 此功能要求商品列表页面中的每个商品前有一个checkbox,选中多个商品后点击删除按钮把商品id传给controller,根据商 ...