首先用google搜索,找不到再用百度搜索
1.logger用于指定工程中的logger,一般使用名字匹配,appender用于指定logger的具体实现
2.每个appender中可以指定layout
3.Layout负责将LoggingEvent中的信息格式化成一行日志信息
解决方式:
可以google搜索log4j2 custom log或者是log4j2 custom layout
https://stackoverflow.com/questions/44005200/log4j2-custom-layout
可以github搜索
https://github.com/search?q=log4j2+customize+log
https://github.com/search?q=log4j2+customize+layout
https://github.com/ivandzf/log4j2-custom-layout
解决方式二:
普通的配置文件中,或者是官方配置文件中有相关信息
例如:
<Console name="LogToConsole" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
其中有PatternLayout可以查看其实现方式和继承关系,模仿其自定义一个具体的layout实现
log4j和logback道理一样。
以下引用自
logback自定义Appender和Layout - 简书
logback自定义Appender和Layout
- Appender是logback中最重要的组件之一,它委托encoder组件来完成LoggingEvent的格式化和记录,具体源码分析网上有很多, 本文主要是应用实践.
- Layout组件来将LoggingEvent进行格式化,返回一个String,然后通过OutputStream.write()方法,把格式化之后的日志信息写到目的地.
继承RollingFileAppender,重写输出文件格式
- 场景
工程中期望输出到日志中的是JSON格式, 但是在业务中log.info(变量),此变量会有带引号的情况下, 会影响最终输出结构,因为重写file appender.
- logback.xml
<encoder>-->
<charset>UTF-8</charset>
<pattern>{"time":"${bySecond}","level":"%-5level","msg":"%msg"} %n</pattern>-->
</encoder>
%msg是logback输出的日志内容,此字符串如果本身带引号,则造成输出到日志文件里的JSON格式无法解析.
- 解决办法
- 集成logback默认的RollingFileAppender,获取msg内容并做格式化替换
- 在logback.xml中<appender class="替换自定义的Appender"/>
public class UserFileAppender extends RollingFileAppender<ILoggingEvent> {
@Override
protected void subAppend(ILoggingEvent event){
// 获取event中的message内容
event.getFormattedMessage().replace("\"","\\\"");
start();
super.subAppend(event);
}
}
进阶:异步处理log.xxxx()日志
- 场景
当在程序中输出了一些日志,并期望对这些日志内容做特定处理(存储DB/解析发送消息等)
- 集成UnsynchronizedAppenderBase
public class TransportDBLoggerAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
@Override
public void append(ILoggingEvent event) {
try {
String content = event.getFormattedMessage();
Map<String, String> map = new HashMap<>();
map.put("LOG_LEVEL", event.getLevel().levelStr);
map.put("CONTENT", content.replace("'", "''"));
// 处理逻辑
} catch (Exception e) {
System.err.println(e);
}
}
}
- 上述代码继承了UnsynchronizedAppenderBase,重写了append方法,里面可以根据event对象获取log中的内容和默认的系统提供的参数(level等),可以在此做各种业务逻辑, 此内容是异步操作,节省我们在工程上自己构建异步日志收集等工作量,适合小应用的场景.
Layout:自定义日志输出格式
- 场景
在上述场景中发现只输出msg还不够满足业务的需求,业务里有需要把MDC存储的上下文也加到输出的JSON日志中,因此使用了layout自定义输出.
- logback.xml
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="自定义layout类" />
</encoder>
- Java
public class LoggingConsoleLayout extends LayoutBase<ILoggingEvent> {
@Override
public String doLayout(ILoggingEvent event) {
StringBuilder sbuf = new StringBuilder();
if (null != event && null != event.getMDCPropertyMap()) {
sbuf.append("{");
sbuf.append("\"time\":\"");
sbuf.append(System.currentTimeMillis());
sbuf.append("\",");
sbuf.append("\"level\":\"");
sbuf.append(event.getLevel());
sbuf.append("\",");
sbuf.append("\"tag\":\"");
sbuf.append(event.getMDCPropertyMap().get("tag"));
sbuf.append("\",");
sbuf.append("\"msg\":\"");
sbuf.append(event.getFormattedMessage().replace("\"", "\\\""));
sbuf.append("\",");
sbuf.append("\"source\":\"dialog\"} \n");
}
return sbuf.toString();
}
}
- 利用自定义的encoder layout,输出程序中存在的各种变量,输出不同需求自定义的日志格式
作者:voltric
链接:https://www.jianshu.com/p/a0eb78b8c775
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。