Overview

自定义Converter,通过conversionRule或者layout实现注入
常规使用Logback的方式不在本篇wiki的范围内
本文旨在解决我写的common_util.log组件在包装slf4j后丢失行号的问题,这是给出的logback解决方案

LineConverter

包装logback + slf4j之后,使用会丢失行号

    // 注入Converter,全局覆盖对“L”,“line”的处理<conversionRule conversionWord="L"converterClass="com.qunar.flight.pangolin.pay.web.SimpleConverter" /><conversionRule conversionWord="line"converterClass="com.qunar.flight.pangolin.pay.web.SimpleConverter" />// 针对appender设定Layout,局部覆盖defaultConverterMap<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender" ><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="com.qunar.flight.pangolin.pay.web.SimplePatternLayout"/></encoder><encoder><pattern>${normal-pattern}</pattern><charset>${encoding}</charset></encoder></appender>

Code

package com.qunar.flight.pangolin.pay.web;import ch.qos.logback.classic.ClassicConstants;
import ch.qos.logback.classic.pattern.LineOfCallerConverter;
import ch.qos.logback.classic.spi.CallerData;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;/*** @author guohang.ding on 16-11-10*/
public class SimpleConverter extends LineOfCallerConverter {private static final String FQCN = com.qunar.flight.log.LogService.class.getName();private static final String FQCN_BY_UTIL = com.qunar.flight.log.LogUtil.class.getName();@Overridepublic String convert(ILoggingEvent le) {if (!(le instanceof LoggingEvent)) {return super.convert(le);}if (!checkIsService(FQCN, FQCN_BY_UTIL)) {return super.convert(le);}StackTraceElement[] cda = getCallerData((LoggingEvent) le);if (cda != null && cda.length > 0) {return Integer.toString(cda[0].getLineNumber());} else {return CallerData.NA;}}private boolean checkIsService(String class1, String class2) {StackTraceElement[] steArray = new Throwable().getStackTrace();// check if LogService or LogUtilfor (StackTraceElement aSteArray : steArray) {if (class1.equals(aSteArray.getClassName())|| class2.equals(aSteArray.getClassName())) {return true;}}return false;}private StackTraceElement[] getCallerData(LoggingEvent event) {if (event.hasCallerData()) {StackTraceElement[] array = extract(new Throwable(), FQCN, FQCN_BY_UTIL, ClassicConstants.DEFAULT_MAX_CALLEDER_DATA_DEPTH);event.setCallerData(array);}return event.getCallerData();}private StackTraceElement[] extract(Throwable t, String fqnOfInvokingClass, String fqnOfInvokingClass2, final int maxDepth) {if (t == null) {return null;}StackTraceElement[] steArray = t.getStackTrace();StackTraceElement[] callerDataArray;int found = CallerData.LINE_NA;for (int i = 0; i < steArray.length; i++) {if (CallerData.isDirectlyInvokingClass(steArray[i].getClassName(), fqnOfInvokingClass) || fqnOfInvokingClass.equals(fqnOfInvokingClass2)) {// the caller is assumed to be the next stack frame, hence the +1.found = i + 1;} else {if (found != CallerData.LINE_NA) {break;}}}// we failed to extract caller dataif (found == CallerData.LINE_NA) {return CallerData.EMPTY_CALLER_DATA_ARRAY;}int availableDepth = steArray.length - found;int desiredDepth = maxDepth < (availableDepth) ? maxDepth : availableDepth;callerDataArray = new StackTraceElement[desiredDepth];for (int i = 0; i < desiredDepth; i++) {callerDataArray[i] = steArray[found + i];}return callerDataArray;}
}package com.qunar.flight.pangolin.pay.web;import ch.qos.logback.classic.PatternLayout;/*** @author guohang.ding on 16-11-10*/
public class SimplePatternLayout extends PatternLayout {static {defaultConverterMap.put("L", SimpleConverter.class.getName());defaultConverterMap.put("line", SimpleConverter.class.getName());}
}

logback 自定义相关推荐

  1. logback自定义日志格式

    logback自定义日志格式 1.ClassicConverter 继承ClassicConverter package com.demo.conf;import ch.qos.logback.cla ...

  2. logback自定义appender

    1.定义appender 1.1 logback.xml配置 <?xml version="1.0" encoding="UTF-8"?> < ...

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

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

  4. springboot logback自定义配置文件路径

    //需要在项目启动项执行 static {System.setProperty("logging.config", System.getProperty("user.di ...

  5. Logback学习笔记1

    Logback介绍 Logback 分为三个模块:Core.Classic 和 Access.Core模块是其他两个模块的基础. Classic模块扩展了core模块. Classic模块相当于log ...

  6. Logback日志跨线程追踪实践

    Logback日志跨线程追踪实践 当我们程序在服务器上面跑的时候,是不是很多时候很难定位问题? 当一大堆繁杂的日志文件丢给你的时候,你如何能从中定位到问题? 本项目源码已经上传Github: gith ...

  7. jpa日志 logback_SpringBoot | 第二十五章:日志管理之自定义Appender

    前言 前面两章节我们介绍了一些日志框架的常见配置及使用实践.一般上,在开发过程中,像log4j2.logback日志框架都提供了很多Appender,基本上可以满足大部分的业务需求了.但在一些特殊需求 ...

  8. 有赞统一日志平台初探

    https://tech.youzan.com/you-zan-tong-ri-zhi-ping-tai-chu-tan/ 一.引言 自有赞成立以来,发展迅猛,业务增长很快,业务系统数量大,每天都会产 ...

  9. android tmp目录权限不够,/tmp目录下执行脚本失败提示Permission denied

    Linux上执行Shell脚本运行失败提示Permission denied一个问题,挺好的问题,切中了知识盲点. 问题现象 Shell脚本在/tmp目录下,执行./test.sh运行失败,提示Per ...

最新文章

  1. DrugAI | 抗新型冠状病毒药物榜单解析
  2. [C++] vector 定义和初始化
  3. dba mysql命令_Mysql常用DBA命令
  4. C++中静态成员数据初始化问题
  5. 2019-03-19-算法-进化(报数)
  6. ASP.NET MVC 的多国语系支持
  7. python中的map()函数详解
  8. java比赛_javamq
  9. 月球好忙 蓝色起源2024年要将首位女性送上月球表面
  10. php可逆加密函数,简洁的PHP可逆加密函数
  11. C++11 新特性整理(2)
  12. NOSQL schema创建原则
  13. objective-c 2.0编程语言,Objective-C 2.0编程快速上手 EXE版[12MB]
  14. 1959=简单枚举类型
  15. android 好看的计算器,从未见过如此丑的计算器 – 计算管家 #Android
  16. spark 两个rdd求交集,差集,并集
  17. python调用win32api详解_Python调用Win32 API实现截图
  18. ubuntu--ogv格式转mp4格式
  19. 亲爱的朋友们,还记得我吗?
  20. Java SE 小白学习笔记 周周测 从小白到大牛

热门文章

  1. “蓝色巨人”转向,极氪会是吉利的一剂“良药”吗?
  2. oracle中三元运算符,三目运算符简介 - ZICK_ZEON的个人空间 - OSCHINA - 中文开源技术交流社区...
  3. 模拟时针--微信小程序制作
  4. 苹果呼叫转移设置不了_手机不想接电话怎么设置为空号教程
  5. 详解shell IFS分隔符
  6. 小南再谈Vue(QA)
  7. 最新的100个微信小程序-极乐Store
  8. O’Reilly创始人Tim O’Reilly谈领导力
  9. wxpython 界面 加密系统
  10. 将图片集合成一个视频