java logger使用_这才是JAVA中打印日志的正确姿势
作者:lrwin
原文链接:http://t.cn/E9BkD7a
使用slf4j
1. 使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一
2. 实现方式统一使用: Logback框架
打日志的正确方式
什么时候应该打日志
1. 当你遇到问题的时候,只能通过debug功能来确定问题,你应该考虑打日志,良好的系统,是可以通过日志进行问题定位的。
2. 当你碰到if…else 或者 switch这样的分支时,要在分支的首行打印日志,用来确定进入了哪个分支
3. 经常以功能为核心进行开发,你应该在提交代码前,可以确定通过日志可以看到整个流程
基本格式
必须使用参数化信息的方式:
logger.debug("Processing trade with id:[{}] and symbol : [{}] ", id, symbol);
对于debug日志,必须判断是否为debug级别后,才进行使用:
if (logger.isDebugEnabled()) { logger.debug("Processing trade with id: " +id + " symbol: " + symbol);}
不要进行字符串拼接,那样会产生很多String对象,占用空间,影响性能。
反例(不要这么做):
logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
使用[]进行参数变量隔离
如有参数变量,应该写成如下写法:
logger.debug("Processing trade with id:[{}] and symbol : [{}] ", id, symbol);
这样的格式写法,可读性更好,对于排查问题更有帮助。
不同级别的使用
ERROR:
基本概念
影响到程序正常运行、当前请求正常运行的异常情况:
1. 打开配置文件失败
2. 所有第三方对接的异常(包括第三方返回错误码)
3. 所有影响功能使用的异常,包括:SQLException和除了业务异常之外的所有异常(RuntimeException和Exception)
不应该出现的情况:
- 比如要使用Azure传图片,但是Azure未响应
如果有Throwable信息,需要记录完成的堆栈信息:
log.error("获取用户[{}]的用户信息时出错",userName,e);
说明
如果进行了抛出异常操作,请不要记录error日志,由最终处理方进行处理:
反例(不要这么做):
try{ ....}catch(Exception ex){ String errorMessage=String.format("Error while reading information of user [%s]",userName); logger.error(errorMessage,ex); throw new UserServiceException(errorMessage,ex);}
WARN
基本概念
不应该出现但是不影响程序、当前请求正常运行的异常情况:
1. 有容错机制的时候出现的错误情况
2. 找不到配置文件,但是系统能自动创建配置文件
即将接近临界值的时候,例如:
- 缓存池占用达到警告线
业务异常的记录,比如:
- 当接口抛出业务异常时,应该记录此异常
INFO:
基本概念
系统运行信息
1. Service方法中对于系统/业务状态的变更
2. 主要逻辑中的分步骤
外部接口部分
1. 客户端请求参数(REST/WS)
2. 调用第三方时的调用参数和调用结果
说明
1. 并不是所有的service都进行出入口打点记录,单一、简单service是没有意义的(job除外,job需要记录开始和结束,)。
反例(不要这么做):
public List listByBaseType(Integer baseTypeId) { log.info("开始查询基地"); BaseExample ex=new BaseExample(); BaseExample.Criteria ctr = ex.createCriteria(); ctr.andIsDeleteEqualTo(IsDelete.USE.getValue()); Optionals.doIfPresent(baseTypeId, ctr::andBaseTypeIdEqualTo); log.info("查询基地结束"); return baseRepository.selectByExample(ex);}
2. 对于复杂的业务逻辑,需要进行日志打点,以及埋点记录,比如电商系统中的下订单逻辑,以及OrderAction操作(业务状态变更)。
3. 对于整个系统的提供出的接口(REST/WS),使用info记录入参4. 如果所有的service为SOA架构,那么可以看成是一个外部接口提供方,那么必须记录入参。5. 调用其他第三方服务时,所有的出参和入参是必须要记录的(因为你很难追溯第三方模块发生的问题)
DEBUG
基本概念
1. 可以填写所有的想知道的相关信息(但不代表可以随便写,debug信息要有意义,最好有相关参数)
2. 生产环境需要关闭DEBUG信息
3. 如果在生产情况下需要开启DEBUG,需要使用开关进行管理,不能一直开启。
说明
如果代码中出现以下代码,可以进行优化:
//1. 获取用户基本薪资//2. 获取用户休假情况//3. 计算用户应得薪资
优化后的代码:
logger.debug("开始获取员工[{}] [{}]年基本薪资",employee,year);logger.debug("获取员工[{}] [{}]年的基本薪资为[{}]",employee,year,basicSalary);logger.debug("开始获取员工[{}] [{}]年[{}]月休假情况",employee,year,month);logger.debug("员工[{}][{}]年[{}]月年假/病假/事假为[{}]/[{}]/[{}]",employee,year,month,annualLeaveDays,sickLeaveDays,noPayLeaveDays);logger.debug("开始计算员工[{}][{}]年[{}]月应得薪资",employee,year,month);logger.debug("员工[{}] [{}]年[{}]月应得薪资为[{}]",employee,year,month,actualSalary);
TRACE
基本概念
特别详细的系统运行完成信息,业务代码中,不要使用.(除非有特殊用意,否则请使用DEBUG级别替代)
规范示例说明
@Override@Transactionalpublic void createUserAndBindMobile(@NotBlank String mobile, @NotNull User user) throws CreateConflictException{ boolean debug = log.isDebugEnabled(); if(debug){ log.debug("开始创建用户并绑定手机号. args[mobile=[{}],user=[{}]]", mobile, LogObjects.toString(user)); } try { user.setCreateTime(new Date()); user.setUpdateTime(new Date()); userRepository.insertSelective(user); if(debug){ log.debug("创建用户信息成功. insertedUser=[{}]",LogObjects.toString(user)); } UserMobileRelationship relationship = new UserMobileRelationship(); relationship.setMobile(mobile); relationship.setOpenId(user.getOpenId()); relationship.setCreateTime(new Date()); relationship.setUpdateTime(new Date()); userMobileRelationshipRepository.insertOnDuplicateKey(relationship); if(debug){ log.debug("绑定手机成功. relationship=[{}]",LogObjects.toString(relationship)); } log.info("创建用户并绑定手机号. userId=[{}],openId=[{}],mobile=[{}]",user.getId(),user.getOpenId(),mobile); }catch(DuplicateKeyException e){ log.info("创建用户并绑定手机号失败,已存在相同的用户. openId=[{}],mobile=[{}]",user.getOpenId(),mobile); throw new CreateConflictException("创建用户发生冲突, openid=[%s]",user.getOpenId()); }}
我目前是在职Java开发,如果你现在正在了解Java技术,想要学好Java,渴望成为一名Java开发工程师,在入门学习Java的过程当中缺乏基础的入门视频教程,你可以关注并私信我:01。我这里有一套最新的Java基础JavaSE的精讲视频教程,这套视频教程是我在年初的时候,根据市场技术栈需求录制的,非常的系统完整。
java logger使用_这才是JAVA中打印日志的正确姿势相关推荐
- 这才是JAVA中打印日志的正确姿势
作者:lrwin 原文链接:http://t.cn/E9BkD7a 使用slf4j 1. 使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一 2. 实现方式统一使用: Logback框架 打 ...
- 别在 Java 代码里乱打日志了,这才是打印日志的正确姿势!
本文来源:http://t.cn/E9BkD7a 使用slf4j 使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一 实现方式统一使用: Logback框架 打日志的正确方式 什么时候应该打 ...
- 有一说一!这才是RabbitMQ实现分布式事务的正确姿势(项目实战)
分布式事务 随着互联网快速发展,微服务,SOA 等服务架构模式正在被大规模的使用,现在分布式系统一般由多个独立的子系统组成,多个子系统通过网络通信互相协作配合完成各个功能. 有很多用例会跨多个子系统才 ...
- 这样才是代码管理和 Commit 的正确姿势 | 研发效能提升36计
简介:效能提升从小习惯开始,这样才是代码管理和 Commit 的正确姿势! 专栏策划|雅纯 志愿编辑|张晟 软件交付是以代码为中心的交付过程,其中代码的作用有几点:第一,最终的制品要交付成什么样,需要 ...
- hashcode是什么意思_什么才是 Java 的基础知识?
作者:晓风轻 链接:zhuanlan.zhihu.com/p/28615617 近日里,很多人邀请我回答各种j2ee开发的初级问题,我无一都强调java初学者要先扎实自己的基础知识,那什么才是java ...
- java 判断类型_如何快速入门Java编程学习(干货)
一.初识Java 1.生活中的程序: 从起床到教室上课的过程 穿衣打扮>起床>洗漱>出宿舍>>吃早餐>到教室 按照特定的顺序去完成某一件事的过程我们叫做生活中的程序 ...
- 支持java虚拟主机_为何缺乏支持Java的虚拟主机
现在很多站长们,都青睐于香港虚拟主机建站.现在常见的是asp和PHP的程序空间很多,但是Java的少之又少,下面小编我给大家聊一聊! 一.香港Java虚拟主机成本高 使用Java程序建站,就必须要用支 ...
- idea看java版本设置_详解IntelliJ IDEA 中如何配置多个jdk版本即(1.7和1.8两个jdk都可用)...
详解IntelliJ IDEA 中如何配置多个jdk版本即(1.7和1.8两个jdk都可用) 有时候需要看Java源码,但是 Java 1.7 和 Java 1.8的差别的关系,有时候你想查看不同jd ...
- java python算法_用Python,Java和C ++示例解释的排序算法
java python算法 什么是排序算法? (What is a Sorting Algorithm?) Sorting algorithms are a set of instructions t ...
最新文章
- 0414复利计算6.0--结对
- c语言测试代码怎么写,初学C语言,写了一个测试手速的工具,代码发上来,存着。。...
- boost::mp11::mp_transform_third相关用法的测试程序
- c语言素数个数_C语言试题及答案
- 智能巡检云监控指标的实践
- NOIP2002复赛 普及组 第1题
- python向下_如何在python中向下转换
- 如何才能快速匹配到大号?
- IT江湖,哪个门派最挨踢?
- 关于主数据管理及病人主索引的说明
- [C#][转载]Sqlite操作大全
- python宿舍管理系统!
- 自动驾驶寻找「商业闭环」
- 苹果手机10秒解除锁屏_苹果密码忘了不想刷机怎么办_苹果手机10秒解除锁屏
- 2021-03-17 RK3288 接PHILIPS 4K显示器HDMI开机概率性不显示的问题
- mysql简单数据库定期备份
- 我们可以用什么来编辑html文件,编辑HTML文件要用什么软件?
- 淘宝天猫API详情接口调用分享
- 关于AI测试与评价的讨论
- 为什么好学生,学不好编程?
热门文章
- 新款iPad,抱回家!
- IDEA新特性:提前知道代码怎么走!
- 陆奇:疫情后将出现哪些创业新机会?
- 阿里高工流生 | 云原生时代的 DevOps 之道
- Java内存不足之PermGen space错误探究
- 关于freemarker的classic_compatible属性的使用场景和解决
- 虚拟机系列 | 执行引擎和垃圾回收
- SpringBoot2.0 基础案例(16):配置Actuator组件,实现系统监控
- SpringBoot2.0 基础案例(04):定时任务和异步任务的使用方式
- Redis快速扫描Scan