JAVA日志记录方法
1. 一个最基本的例子
- 引入loggerg类和logger工厂类
- 声明logger
- 记录日志
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserService {
// 2. 声明一个Logger,这个是static的方式,我比较习惯这么写。
private final static Logger logger = LoggerFactory.getLogger(UserService. class);
public boolean verifyLoginInfo(String userName, String password) {
// 3. log it,输出的log信息将会是:"Start to verify User [Justfly]
logger.info("Start to verify User [{}]", userName);
return false;
}
}
- 静态Logger对象相对来说更符合语义,节省CPU,节省内存,不支持注入
- 对象变量Logger支持注入,对于一个JVM中运行的多个引用了同一个类库的应用程序,可以在不同的应用程序中对同个类的Logger进行不同的配置。比如Tomcat上部署了俩个应用,他们都引用了同一个lib。
2. Logger接口的方法
2.1 判断Logger级别是否开启的方法
- public boolean isTraceEnabled();
- public boolean isDebugEnabled();
- public boolean isInfoEnabled();
- public boolean isWarnEnabled();
- public boolean isErrorEnabled();
2 logger.debug("["+resultCount+"]/["+totalCount+"] of users are returned");
3 }
2 logger.debug("[{}]/[{}] of users in group are returned", resultCount,totalCount);
3 }
2.2 log信息的方法
2.2.1 方法说明
- public void info(String msg);
- public void info(String format, Object arg);
输出
- public void info(String format, Object arg1, Object arg2);
- public void info(String format, Object... arguments);
- public void info(String msg, Throwable t);
输出
java.io.FileNotFoundException: File not exists
at cn.justfly.training.logging.service.UserServiceTest.testLogResult(UserServiceTest.java:31) ~ [ test-classes/:na ]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~ [ na:1.6.0_45 ]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~ [ na:1.6.0_45 ]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~ [ na:1.6.0_45 ]
at java.lang.reflect.Method.invoke(Method.java:597) ~ [ na:1.6.0_45 ]
参数化说明
2.2.2 如何Log Exception
2.2.2.1 把Exception作为Log方法的最后一个参数
java.io.FileNotFoundException: File not exists
at cn.justfly.training.logging.service.UserServiceTest.testLogResult(UserServiceTest.java:30) [ test-classes/:na ]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~ [ na:1.6.0_45 ]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~ [ na:1.6.0_45 ]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~ [ na:1.6.0_45 ]
at java.lang.reflect.Method.invoke(Method.java:597) ~ [ na:1.6.0_45 ]
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) [ junit.jar:na ]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [ junit.jar:na ]
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) [ junit.jar:na ]
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [ junit.jar:na ]
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) [ junit.jar:na ]
2.2.2.2 Exception不会替换log信息中的参数
java.io.FileNotFoundException: File not exists
at cn.justfly.training.logging.service.UserServiceTest.testLogResult(UserServiceTest.java:30) [ test-classes/:na ]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~ [ na:1.6.0_45 ]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~ [ na:1.6.0_45 ]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~ [ na:1.6.0_45 ]
at java.lang.reflect.Method.invoke(Method.java:597) ~ [ na:1.6.0_45 ]
2.2.2.3 参数化Exception
- 把Exception的toString()方法的返回值作为参数
- 不要让Exception成为最后一个参数
3. Log什么
3.1 如何使用不同级别的Log
3.1.1 用户级别
3.1.1.1 Error
- 影响到程序正常运行、当前请求正常运行的异常情况,例如:
- 打开配置文件失败
- 第三方应用网络连接异常
- SQLException
- 不应该出现的情况,例如:
- 某个Service方法返回的List里面应该有元素的时候缺获得一个空List
- 做字符转换的时候居然报错说没有GBK字符集
3.1.1.2 Warn
- 不应该出现但是不影响程序、当前请求正常运行的异常情况,例如:
- 有容错机制的时候出现的错误情况
- 找不到配置文件,但是系统能自动创建配置文件
- 即将接近临界值的时候,例如:
- 缓存池占用达到警告线
3.1.1.3 Info
- 系统运行信息
- Service方法的出入口
- 主要逻辑中的分步骤
- 外部接口部分
- 客户端请求参数和返回给客户端的结果
- 调用第三方时的调用参数和调用结果
3.1.2 开发级别
3.1.2.1 Debug
- 用于记录程序变量,例如:
- 多次迭代中的变量
- 用于替代代码中的注释
![](http://www.blogjava.net/Images/dot.gif)
// 2. 获取用户休假情况
![](http://www.blogjava.net/Images/dot.gif)
// 3. 计算用户应得薪资
![](http://www.blogjava.net/Images/dot.gif)
![](http://www.blogjava.net/Images/dot.gif)
logger.debug("获取员工[{}] [{}]年的基本薪资为[{}]",employee,year,basicSalary);
logger.debug("开始获取员工[{}] [{}]年[{}]月休假情况",employee,year,month);
![](http://www.blogjava.net/Images/dot.gif)
logger.debug("员工[{}][{}]年[{}]月年假/病假/事假为[{}]/[{}]/[{}]",employee,year,month,annualLeaveDays,sickLeaveDays,noPayLeaveDays);
logger.debug("开始计算员工[{}][{}]年[{}]月应得薪资",employee,year,month);
![](http://www.blogjava.net/Images/dot.gif)
logger.debug("员工[{}] [{}]年[{}]月应得薪资为[{}]",employee,year,month,actualSalary);
3.1.2.2 Trace
3.2 Log中的要点
3.2.1 Log上下文
- "开始导入配置文件"
- "开始导入配置文件[/etc/myService/config.properties]"
3.2.2 考虑Log的读者
- "开始执行getUserInfo 方法,用户名[jimmy]"
- "开始获取用户信息,用户名[jimmy]"
- "无法解析参数[12 03, 2013],birthDay参数需要符合格式[yyyy-MM-dd]"
3.2.3 Log中的变量用[]与普通文本区分开来
- 在你阅读Log的时候容易捕捉到有用的信息
- 在使用工具分析Log的时候可以更方便抓取
- 在一些情况下不容易混淆
- "获取用户lj12月份发邮件记录数"
- "获取用户[lj1][2]月份发邮件记录数"
3.2.4 Error或者Warn级别中碰到Exception的情况尽量log 完整的异常信息
- 你是在做什么事情的时候出错了
- 你是在用什么数据做这个事情的时候出错了
- 出错的信息是什么
- log.error("获取用户[{}]的用户信息时出错",userName,ex);
- log.error("获取用户[{}]的用户信息时报错,错误信息:[{}]",userName,ex.getMessage());
- log.error("获取用户信息时出错");
3.2.5 对于Exception,要每次都Log StackTrace吗?
![](http://www.blogjava.net/Images/dot.gif)
} catch(Exception ex){
String errorMessage=String.format("Error while reading information of user [%s]",userName);
logger.error(errorMessage,ex);
throw new UserServiceException(errorMessage,ex);
}
- 这个信息很重要,我不确认再往上的异常处理层中是否会正常的把它的StackTrace打印出来。
- 如果这个异常信息在往上传递的过程中被多次包装,到了最外层打印StackTrace的时候最底层的真正有用的出错原因有可能不会被打印出来。
- 如果有人改变了LogbackException打印的配置,使得不能完全打印的时候,这个信息可能就丢了。
- 就算重复了又怎么样?都Error了都Warning了还省那么一点空间吗?
JAVA日志记录方法相关推荐
- php ci log,PHP框架CI CodeIgniter 的log_message开启日志记录方法
PHP框架CI CodeIgniter 的log_message开启日志记录方法 第一步:index.php文件,修改环境为开发环境 define('ENVIRONMENT', 'developmen ...
- qt 历史记录控件_基于Qt图形界面软件的操作日志记录方法及系统_2015106293015_说明书_专利查询_专利网_钻瓜专利网...
技术领域 本发明涉及一种软件系统的日志记录技术,特别涉及一种基于Qt图形界面软件的操作日志记录方法及系统. 背景技术 软件操作日志是记录用户在使用软件的过程中,通过鼠标和键盘在操作界面上执行的点击和输 ...
- java通用日志记录_JAVA实现通用日志记录方法
前言: 之前想在filter层直接过滤httpServerletRequest请求进行日志处理,但是之后再getWriter()的 时候报already been call异常.查了下,才发现原来流形 ...
- java日志记录的5条规则
日志记录是在软件开发过程中常常需要考虑的关键因素. 当产品运行出错时,日志文件通常是我们进行错误分析的首要选择. 而且,在很多情况下,它们是我们手上唯一可以用来查明发生状况和问题根本原因的信息. 可见 ...
- TinyLog –轻量级Java日志记录框架教程
TinyLog is a simple and lightweight logging framework for Java. We can use tinylog with Java, Kotlin ...
- 如何通过7个Logback调整立即改善Java日志记录
基准测试可帮助您发现Logback在压力下的性能 日志记录对于服务器端应用程序是必不可少的,但这是有代价的. 令人惊讶的是,微小的更改和配置调整对应用程序的日志记录吞吐量有多大影响. 在这篇文章中,我 ...
- Java日志记录函数调用栈方法
关于getStackTrace() public StackTraceElement[] getStackTrace() 返回一个表示该线程堆栈转储的堆栈跟踪元素数组.如果该线程尚未启动或已经终止,则 ...
- 用Java代码实现日志记录器_如何在此简单的Java日志记录实现中附加到日志文件? - java...
我得到了以下用于创建和管理Logger的类.每当执行代码和程序时,都会使用对静态getLogger()捕获块的调用进行记录. public class Log { private static fin ...
- Java日志记录最佳实践
作者:GeekerLou www.jianshu.com/p/546e9aace657 一.日志简介 1.1 日志是什么(WHAT) 日志:记录程序的运行轨迹,方便查找关键信息,也方便快速定位解决问题 ...
最新文章
- 详解OpenCV卷积滤波之边缘处理与锚定输出
- 【openlayers】修改源码支持SLD的graphicfill属性
- WSDM 2022 | 点击率模型特征交叉方向的发展及CAN模型介绍
- 浅析libcurl多线程安全问题
- [HTTP] 跨域资源共享
- 在拦截器里放入参数 controller_干货|SpringMVC拦截器的使用详解
- vegas怎么添加淡水墨效果?
- PAT乙级真题 | 1006 换个格式输出整数
- 还原数据库时不能独占访问
- 从一个组件的实现来深刻理解 JS 中的继承
- vue js代码混淆加密、压缩
- 计算机平面设计就业工资,cad制图工资一般多少
- 匈牙利算法(指派问题)
- 用R语言进行分位数回归
- 用数组统计字符串中26个大写字母的个数
- 还在搞三层架构?了解下 DDD 分层架构的三种模式吧
- 【数据结构】最小生成树(Prim算法,普里姆算法,普利姆)、最短路径(Dijkstra算法,迪杰斯特拉算法,单源最短路径)
- 零基础学javaDay06
- 股票数据的获取以及下载保存
- java中parseint函数_浅谈 js中parseInt函数的解析