程序中记录日志一般有两个目的: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. RESTORE 无法处理数据库 'Students',因为它正由此会话使用。建议在执行此操作时使用 master 数据库。

    恢复数据库是总弹出报错对话框如下:RESTORE 无法处理数据库 'Students',因为它正由此会话使用.建议在执行此操作时使用 master 数据库.RESTORE DATABASE 正在异常终 ...

  2. mysql中binlog_format的三种模式

    mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复 ...

  3. WebDriverException: Message: f.QueryInterface is not a function

    WebDriverException: Message: f.QueryInterface is not a function 使用webdriver打开c.highpin.cn,结果报错,见下图: ...

  4. Access to the path 'C:\inetpub\wwwroot\mysite\images\savehere' is denied.

    访问路径被拒绝 我解决了这个设置: IIS>应用程序池> [您的站点]>高级设置...>标识>内置帐户> LocalSystem

  5. Spring简单获得实体类的实例, 使用ApplicationContext()方法的几点注意事项

    今天接触了Spring的初步用法, 感觉跟实例化实体类没啥区别, 像这种简单的代码还不如直接实例化来的方便, 这样使用Spring的话总共需要三个文件 第一个当然是一个实体类了, 定义好属性, get ...

  6. java并发:volatile关键字

    java并发需要保证原子性,可见性,有序性. http://www.cnblogs.com/expiator/p/9226775.html 一.volatile关键字作用如下: 1.volatile关 ...

  7. apache中开启rewrite

    1.在apache配置文件httpd.conf中找到如下行: #LoadModule rewrite_module modules/mod_rewrite.so 去掉该行前面的#号 2.在httpd. ...

  8. OpenSource.iOS.ProtobufWithObjective-C

    2. 在iOS(Mac OS X)中使用protobuf 2.0 构建protoc A) 下载最新的protobuf版本 B) 依据README中的步骤依次进行 2.1 添加protobuf到工程中 ...

  9. 201621123008 《Java程序设计》第一周学习总结

    1. 本章学习总结 对于我们学计算机的学生而言,要想提高编程能力,只有多练习,把我们所学到的东西运用到实践中去,整天抱着书本冥思苦想而不动手到具体的环境中去试验是很难有所提升的.大一学C语言的时候平时 ...

  10. Codeforces 677C. Coloring Trees dp

    C. Coloring Trees time limit per test:2 seconds memory limit per test:256 megabytes input:standard i ...