为什么要用slf4j实现日志打印,在阿里的开发规范中有这么一段:

【强制】应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架
SLF4J中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。
大概意思就是说 SLF4J 是一个日志抽象层,允许你使用任何一个日志系统,并且可以随时切换还不需要动到已经写好的程序。
但是我们在使用slf4j的时候一般会像下面这样:

public class MySlf4j {private static final Logger logger = LoggerFactory.getLogger("MySlf4j");public static void info(String msg) {logger.info(msg);}
}

在每个类里定义Logger,这就是重复的劳动,必须对logger进行封装,编写封装类需要注意,slf4j我们如果不做处理我们调用方法记录日志,像 类名、方法名、行数都变成Logger这个类的信息,这样就无法准确定位日志来源。这样的问题是无法忍受的。
所有我们对Mylf4j工具类做了如下修改:
1.通过Throwable获取堆栈信息。
2.通过SharedSecrets.getJavaLangAccess(),我们访问堆栈信息通过stackDepth定位到调用者类信息。
具体的代码如下:

public class MySlf4j {/**空数组*/private static final Object[] EMPTY_ARRAY = new Object[] {};/**全类名*/private static final String FQCN = MySlf4j.class.getName();/*** 获取栈中类信息* @param stackDepth 栈深(下标) 2:调用者类信息* @return org.slf4j.spi.LocationAwareLogger* @author wxt* @date 2019/7/10 8:40*/private static LocationAwareLogger getLocationAwareLogger(final int stackDepth) {/**通过堆栈信息获取调用当前方法的类名和方法名*/JavaLangAccess access = SharedSecrets.getJavaLangAccess();Throwable throwable = new Throwable();StackTraceElement frame = access.getStackTraceElement(throwable, stackDepth);return (LocationAwareLogger) LoggerFactory.getLogger(frame.getClassName());}/*** 封装Debug级别日志* @param msg* @param arguments* 作者:wxt* 日期:2019年3月27日下午5:38:01*/public static void textDebug(String msg, Object... arguments) {if (arguments != null && arguments.length > 0) {MessageFormat temp = new MessageFormat(msg);msg = temp.format(arguments);}getLocationAwareLogger(2).log(null, FQCN, LocationAwareLogger.DEBUG_INT, msg, EMPTY_ARRAY, null);}/*** 封装Info级别日志* @param msg* @param arguments* 作者:wxt* 日期:2019年3月27日下午5:37:42*/public static void textInfo(String msg, Object... arguments) {if (arguments != null && arguments.length > 0) {MessageFormat temp = new MessageFormat(msg);msg = temp.format(arguments);}getLocationAwareLogger(2).log(null, FQCN, LocationAwareLogger.INFO_INT, msg, EMPTY_ARRAY, null);}/*** 封装Warn级别日志* @param msg* @param arguments* 作者:wxt* 日期:2019年3月27日下午5:37:30*/public static void textWarn(String msg, Object... arguments) {if (arguments != null && arguments.length > 0) {MessageFormat temp = new MessageFormat(msg);msg = temp.format(arguments);}getLocationAwareLogger(2).log(null, FQCN, LocationAwareLogger.WARN_INT, msg, EMPTY_ARRAY, null);}/*** 封装Error级别日志* @param msg* @param arguments* 作者:wxt* 日期:2019年3月27日下午5:37:14*/public static void textError(String msg, Object... arguments) {if (arguments != null && arguments.length > 0) {MessageFormat temp = new MessageFormat(msg);msg = temp.format(arguments);}getLocationAwareLogger(2).log(null, FQCN, LocationAwareLogger.ERROR_INT, msg, EMPTY_ARRAY, null);}/*** 异常堆栈转字符串* @param e* @return* 作者:wxt* 日期:2019年3月27日下午5:37:08*/public static String ExceptionToString(Exception e) {StringWriter sw = null;PrintWriter pw = null;try {if (e == null) {return "无具体异常信息";}sw = new StringWriter();pw = new PrintWriter(sw);e.printStackTrace(pw);return sw.toString();} catch (Exception ex) {MySlf4j.textError("异常堆栈转字符串异常", ex);return "";} finally {sw.flush();pw.flush();pw.close();}}
}

loback.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?><configuration scan="true"><!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--><property name="APP_NAME" value="wxt-provider" /><property name="LOG_HOME" value="/usr/local/logs/${APP_NAME}" /><!-- 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [${APP_NAME}] [%thread] [%X{traceId}] %logger{50} - [%class : %method : %line] - %msg%n</pattern></encoder></appender><!-- 按照每天生成日志文件 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender" additivity="false"><File>${LOG_HOME}/${APP_NAME}.log</File><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [${APP_NAME}] [%thread] [%X{traceId}] %logger{50} - [%class : %method : %line] - %msg%n</pattern></encoder><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_HOME}/${APP_NAME}.%d{yyyy-MM-dd}.log</fileNamePattern></rollingPolicy></appender><root level="INFO"><appender-ref ref="STDOUT" /><appender-ref ref="FILE" /></root>
</configuration>

这样我们通过调用该工具类就可以打印出调用者的类相关信息。


欢迎关注公众号: 编码是个技术活

Slf4j+logback实现日志打印-获取调用者类及方法行数信息相关推荐

  1. SpringBoot+logback实现日志打印

    SpringBoot+logback 一.日志简介 1.SLF4J介绍 二.SpringBoot集成logback 1.配置文件详解 1.彩色日志 2.appender 3.root和logger详解 ...

  2. Java日志(slf4j+logback)及打印彩色日志

    一.maven依赖 在pom文件增加slf4j+logback依赖 <!-- 版本配置 --> <properties><slf4j.version>1.7.21& ...

  3. SpringBoot 项目使用 SLF4J+logback 进行日志记录,来增强可维护性

    点击上方 好好学java ,选择 星标 公众号重磅资讯,干货,第一时间送达 今日推荐:推荐19个github超牛逼项目!个人原创100W +访问量博客:点击前往,查看更多 作者:云深不知处 blog. ...

  4. java lombok logback 配置日志打印

    一.maven 引入 <dependency><groupId>org.projectlombok</groupId><artifactId>lombo ...

  5. slf4j + logback 输出日志:mybatis sql语句

    1 引入jar包:maven resposity 中 选择logback classic module <dependency> <groupId>ch.qos.logback ...

  6. slf4j 日志打印

    Spring Boot 默认使用 SLF4J+Logback 记录日志,并提供了默认配置,即使我们不进行任何额外配,也可以使用 SLF4J+Logback 进行日志输出. 日志级别 trace (追踪 ...

  7. spring项目中使用slf4j和log4j2日志框架

    为什么要使用slf4j和log4j2 1.多日志实现组件存在问题 java世界里有许多实现日志功能的工具,最早得到广泛使用的是 log4j,许多应用程序的日志部分都交给了 log4j,不过作为组件开发 ...

  8. java agent开发 日志打印

    简介 目前java 打印日志用的比较多的就是slf4j配合log4j/logback进行日志打印,但是呢agent是独立的jar包, 使用slf4j就需要将包引入agent中,这样就可能和业务自身的s ...

  9. logback - 自定义日志脱敏组件,一种不错的脱敏方案

    前言 在我们书写代码的时候,会书写许多日志代码,但是有些敏感数据是需要进行安全脱敏处理的. 对于日志脱敏的方式有很多,常见的有①使用conversionRule标签,继承MessageConverte ...

  10. 踏雪寻梅 —— 日志打印

    日志要清晰.便于理解: 日志级别: 日志打印所在的类.方法位置(调用点),日志打印的时间: 1. 经典使用日志的场景 对于服务器等一般长时间运行的应用程序,每一步操作(成功或失败),都要输出相关日志: ...

最新文章

  1. [K/3Cloud]关于数据库sa密码更改,管理中心登录不上的问题。
  2. 教育部:不得将研究生当作廉价劳动力!也不得故意拖延毕业时间!
  3. 字符串中包含汉字和\u,显示出汉字来
  4. Latex入门:编辑器(texmaker+texlive)安装
  5. CVPR 2018 FlowTrack:《End-to-end Flow Correlation Tracking with Spatial-temporal Attention》论文笔记
  6. javase基础第三天
  7. 2019年第二届全国大学生大数据技能竞赛通知
  8. Hive--sql中的窗口函数
  9. 别再刷百度厂长被浇水啦!来看看大百度APP-首屏秒开优化实践
  10. 免费的思维导图软件都有哪些?
  11. 2021高考北京大峪中学成绩查询,2014年北京市各区高考成绩汇总
  12. 计算机弹音乐百度百科,电子音乐合成器
  13. 多线程情况下如何保证线程安全
  14. 【微信小程序+echarts点亮中国地图】微信小程序echarts中国地图点亮功能
  15. 有哪些数据恢复软件?13个好用的数据恢复工具分享
  16. C语言:比较三个数(double类型)的大小
  17. RK3568-SPI
  18. html中如何写if判断,HTML中的if判断用法
  19. 搜狗输入法android皮肤,搜狗输入法皮肤盒子app
  20. 解决远程桌面连接“这可能是由于CreddSSP加密数据库修正”的问题

热门文章

  1. 比特率控制模式ABR、VBR、CBR
  2. SEGY数据的读取与写出C++
  3. 喜马拉雅FM下载的音频转换为正常文件的JAVA实现
  4. 什么是索引,索引的作用,什么时候需要使用索引,什么时候不需要使用索引
  5. mysql导出忽略指定前缀_mysql批量删除指定前缀或后缀表
  6. 怎么修改图片尺寸大小?电脑上怎么图片改大小?
  7. 用 .NET Core开发BT下载的Tracker服务器
  8. Excel单元格保护
  9. 如何用深度学习对几种类型的图片进行分类(tensorflow,CNN)
  10. [ERROR] melodic运行比较新的包时报错,我这里是racecar的包出错