动态替换logback FileAppender/RollingFileAppender 配置- Programmatically configure logback FileAppender/RollingBackAppender
一、本文实际解决的问题
如何在代码中修改logback的RollingFileAppender配置(本文代码实例为修改日志文件路径)
二、针对的场景:
本文解决的问题属于一个大需求的一部分,需求为:需要特殊处理的请求的相关日志,需要与正常日志分开打印;同时不能去推动全公司应用修改代码,这样成本过高,尽量通过引入二方包解决问题
本文主要介绍获取Logger之后如何修改Logger配置,实现日志输出到别的路径
三、logback logger结构简述

四、实现流程
1、获取Logger
private static Logger logger = LoggerFactory.getLogger(TaskHistoryService.class);
2、获取所有Appender
// 获取从logger到RootLogger的所有appenders
public static ArrayList<Appender> getAppendersTraversal(Logger logger){
Logger parent = logger;
ArrayList<Appender> result = new ArrayList<>();
while(parent != null){
ArrayList<Appender> tempResult = getAppenders(parent);
if (tempResult != null){
result.addAll(tempResult);
}
parent = getParent(parent);
}
return result;
}
// 获取logger中的appenders
public static ArrayList<Appender> getAppenders(Logger logger){
AppenderAttachableImpl<ILoggingEvent> aai;
ArrayList<Appender> fileAppenders = new ArrayList<>();
try {
Class<?> clazz = ch.qos.logback.classic.Logger.class;
Field aaiField = clazz.getDeclaredField("aai");
aaiField.setAccessible(true);
AppenderAttachableImpl<ILoggingEvent> markedAai;
aai = (AppenderAttachableImpl<ILoggingEvent>)aaiField.get(logger);
if (aai == null){
return null;
}
Iterator<Appender<ILoggingEvent>> aaiIterator = aai.iteratorForAppenders();
while (aaiIterator.hasNext()){
Appender<ch.qos.logback.classic.spi.ILoggingEvent> appender = aaiIterator.next();
fileAppenders.add(appender);
}
return fileAppenders;
} catch (NoSuchFieldException e){
e.printStackTrace();
return fileAppenders;
} catch (IllegalAccessException e){
e.printStackTrace();
return fileAppenders;
}
}
// 获取logger的parent logger
public static Logger getParent(Logger logger) {
Class<?> clazz = ch.qos.logback.classic.Logger.class;
try {
Field parentField = clazz.getDeclaredField("parent");
parentField.setAccessible(true);
Logger parent = (Logger)parentField.get(logger);
return parent;
} catch (NoSuchFieldException e){
e.printStackTrace();
return null;
} catch (IllegalAccessException e){
e.printStackTrace();
return null;
}
}
3、获取RollingFileAppender
public static RollingFileAppender getRollingFileAppender(Appender appender){
if (appender instanceof RollingFileAppender){
return (RollingFileAppender)appender;
}
return null;
}
4、更新Policy
private static RollingFileAppender updateRollingPolicyToMark(RollingFileAppender rollingFileAppender, String newFile, String newPattern){
RollingPolicy rollingPolicy = rollingFileAppender.getRollingPolicy();
TriggeringPolicy triggeringPolicy = rollingFileAppender.getTriggeringPolicy();
RollingPolicyBase rollingPolicyBase = (RollingPolicyBase)rollingPolicy;
rollingPolicyBase.setFileNamePattern(newPattern);
// stop all:appender + policy
stopRollingFileAppender(rollingFileAppender);
// set fileName
setFileName(rollingFileAppender, newFile);
// start
startRollingFileAppender(rollingFileAppender);
return rollingFileAppender;
}
private static void stopRollingFileAppender(RollingFileAppender rollingFileAppender){
rollingFileAppender.stop();
}
private static void startRollingFileAppender(RollingFileAppender rollingFileAppender){
rollingFileAppender.getTriggeringPolicy().start();
rollingFileAppender.getRollingPolicy().start();
rollingFileAppender.start();
}
private static void setFileName(RollingFileAppender rollingFileAppender, String fileName){
RollingPolicy rollingPolicy = rollingFileAppender.getRollingPolicy();
TriggeringPolicy triggeringPolicy = rollingFileAppender.getTriggeringPolicy();
// remove policy
rollingFileAppender.setRollingPolicy(null);
rollingFileAppender.setTriggeringPolicy(null);
// set fileName
rollingFileAppender.setFile(fileName);
// set policy
rollingFileAppender.setRollingPolicy(rollingPolicy);
rollingFileAppender.setTriggeringPolicy(triggeringPolicy);
}
动态替换logback FileAppender/RollingFileAppender 配置- Programmatically configure logback FileAppender/RollingBackAppender的更多相关文章
- maven 打包时动态替换properties资源文件中的配置值
pom build节点下面添加resource配置: <resources> <resource> <directory>src/main/resources/&l ...
- 使用Nginx反向代理和内容替换模块实现网页内容动态替换功能
2016年11月21日 10:30:00 xian_02 阅读数:10943 Nginx是一款轻量级高性能服务器软件,虽然轻量,但功能非常强大,可用于提供WEB服务.反向代理.负载均衡.缓存服务. ...
- logback.xml常用配置
一.logback的介绍 Logback是由log4j创始人设计的又一个开源日志组件.logback当前分成三个模块:logback-core,logback- classic和logback-acc ...
- logback学习与配置使用
Logback介绍 Logback 分为三个模块:Core.Classic 和 Access.Core模块是其他两个模块的基础. Classic模块扩展了core模块. Classic模块相当于log ...
- logback logback.xml常用配置详解(三)
logback logback.xml常用配置详解 <filter> <filter>: 过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之 ...
- Logback日志基础配置以及自定义配置
Logback日志基础配置 logback日志配置有很多介绍,但是有几个非常基础的,容易忽略的.下面是最简单的一个配置,注意加粗的描述 <?xml version="1.0" ...
- SpringBoot配置(2) slf4j&logback
SpringBoot配置(2) slf4j&logback 一.SpringBoot的日志使用 全局常规设置(格式.路径.级别) SpringBoot能自动适配所有的日志,而且底层使用slf4 ...
- 利用springloaded进行java class动态替换
我们知道对于一个java文件,如Test.java,首先需要通过javac命令(javac Test.java)进行编译,生成class文件,再将class文件在jvm上进行加载运行,也就是java命 ...
- logback logback.xml常用配置详解(一)<configuration> and <logger>
logback logback.xml常用配置详解(一)<configuration> and <logger> 博客分类: Log java loglogback 原创文章 ...
随机推荐
- U9249 【模板】BSGS
题目描述 给定a,b,p,求最小的非负整数x 满足a^x≡b(mod p) 若无解 请输出“orz” 输入输出格式 输入格式: 三个整数,分别为a,b,p 输出格式: 满足条件的非负整数x 输入输出样 ...
- 前端css3样式前缀自动补全工具--autoprefixer
最近在学习一份来自git的动画框架源码,看懂70%的核心代码后,打算自己动手实践一版,然鹅,所有框架搭起来以后,在动画这块却出了问题: 想设计一个slideInLeft的动画,必然想到了要从偏移-10 ...
- colormap画出的图不是彩色问题
针对matlab2017渲染出的彩色图是黑白的问题. t=labels; t(tstSet(:,end-))=Relabels; t=reshape(t,,); t=t'; figure imshow ...
- vim插件minibuf配置
1.去下载网站下载minibufexpl.vim文件放入到~/vim/plugins中,有的系统路径是~/.vim/plugins; 下载网址如下 https://www.vim.org/script ...
- 重构29-Remove Middle Man(去掉中间人)
有时你的代码里可能会存在一些"Phantom"或"Ghost"类,Fowler称之为"中间人(Middle Man)".这些中间人类仅仅简单 ...
- Node.js——req、res对象
requset对象类型<http.IncomingMessage>,继承stream.Readable类 requset对象: req.headers req.rawHeaders req ...
- 2015年度精品 最新力作32位和64位xp,win7,win8,win10系统下载(电脑城专用版)
一.系统主要特点 1.安装维护方便快速 - 全自动无人值守安装,采用万能GHOST技术,安装系统过程只需3-5分钟,适 合新旧各种机型. - 集成常见硬件驱动,智能识别+预解压技术,绝大多数硬件可以快 ...
- 2017huas_ACM第三天
暑假集训第三天. 就在刚才AC了第十题,本周做题拿到了满分. 软件工程专业没有学习C++语言,这在做题过程中给了我不少的麻烦.遇到什么不懂的,不确认的,都要上网查阅或者开了新项目自己尝试一下.耗费了不 ...
- C++学习_继承覆盖重载
今天通过对实验二继承,重载,覆盖的学习,让我更深一步理解了这些概念的区别. 首先来明确一个概念,函数名即地址,也就是说函数名就是个指针. 编译阶段,编译器为每个函数的代码分配一个地址空间并编译函数代码 ...
- js 给url添加时间戳 解决浏览器缓存
//解决浏览器缓存 function timestamp(url){ // var getTimestamp=Math.random(); var getTimestamp=new Dat ...