Spring Framework
[Logging] Log4j, Logback, Log4j2 로 MyBatis SQL 쿼리 남기기
헤르메스의날개
2021. 6. 17. 00:47
728x90
사용자 Appender 생성
아래 링크를 보면 Customer Appender 를 생성할 수 있는 소스가 있습니다.
이 Customer Appender가 왜 필요하냐면... 모든 Log 를 걸러낼 수 있기 때문입니다.
MyBatis Query Log 까지도 확인할 수 있습니다.
<Logger name="jdbc.sqltiming" level="INFO" additivity="false">
<AppenderRef ref="sqlLog" />
<AppenderRef ref="RollingFile" />
</Logger>
<Logger name="jdbc.sqlonly" level="INFO" additivity="false">
<AppenderRef ref="console" />
<AppenderRef ref="sqlLog" />
</Logger>
package com.github.dadiyang.appender;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
/**
* @author dadiyang
* @since 2019/4/30
*/
public class Log4jAppender extends AppenderSkeleton {
private String appName;
@Override
protected void append(LoggingEvent event) {
if (event == null || event.getMessage() == null) {
return;
}
// 必须设置 appName
if (appName == null || appName.isEmpty()) {
return;
}
String level = event.getLevel().toString();
String loggerName = event.getLoggerName();
String msg = event.getRenderedMessage();
String threadName = event.getThreadName();
Throwable throwable = event.getThrowableInformation() != null ? event.getThrowableInformation().getThrowable() : null;
// todo 这里实现自定义的日志处理逻辑
System.out.println(appName + ": 自定义 log4j appender, threadName: " + threadName + ", level: " + level + ", loggerName: " + loggerName + ", msg: " + msg);
if (throwable != null) {
throwable.printStackTrace();
}
}
@Override
public void close() {
}
@Override
public boolean requiresLayout() {
return false;
}
/**
* 定义 setter 方法,这样在配置文件中添加类似 log4j.appender.CustomAppender.appName=test_app_name 的配置项时,配置会被注入到这个 appender 中
*/
public void setAppName(String appName) {
this.appName = appName;
}
}
package com.github.dadiyang.appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.PatternLayout;
import java.io.Serializable;
/**
* 自定义实现log4j2的输出源
*
* @author dadiyang
* @since 2019/4/30
*/
@Plugin(name = "Log4j2Appender", category = "Core", elementType = "appender", printObject = true)
public final class Log4j2Appender extends AbstractAppender {
private String appName;
protected Log4j2Appender(String name, String appName, Filter filter, Layout<? extends Serializable> layout,
final boolean ignoreExceptions) {
super(name, filter, layout, ignoreExceptions);
this.appName = appName;
}
@Override
public void append(LogEvent event) {
if (event == null || event.getMessage() == null) {
return;
}
// 必须设置 appName
if (appName == null || appName.isEmpty()) {
return;
}
// 此处自定义实现输出
String level = event.getLevel().toString();
String loggerName = event.getLoggerName();
String msg = event.getMessage().getFormattedMessage();
String threadName = event.getThreadName();
Throwable throwable = event.getThrown();
// todo 这里实现自定义的日志处理逻辑
System.out.println(appName + ": 自定义 log4j2 appender, threadName: " + threadName + ", level: " + level + ", loggerName: " + loggerName + ", msg: " + msg);
if (throwable != null) {
throwable.printStackTrace();
}
}
/**
* log4j2 使用 appender 插件工厂,因此传参可以直接通过 PluginAttribute 注解注入
*/
@PluginFactory
public static Log4j2Appender createAppender(
@PluginAttribute("name") String name,
@PluginAttribute("appName") String appName,
@PluginElement("Layout") Layout<? extends Serializable> layout,
@PluginElement("Filter") final Filter filter) {
if (name == null) {
LOGGER.error("No name provided for Log4j2Appender");
return null;
}
if (appName == null) {
LOGGER.error("配置日志自定义 Appender 必须设置 appName 属性!!");
return null;
}
if (layout == null) {
layout = PatternLayout.createDefaultLayout();
}
return new Log4j2Appender(name, appName, filter, layout, true);
}
}
package com.github.dadiyang.appender;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.ThrowableProxy;
import ch.qos.logback.core.AppenderBase;
/**
* 自定义实现logback的输出源
*
* @author dadiyang
* @since 2019/4/30
*/
public class LogbackAppender extends AppenderBase<ILoggingEvent> {
private String appName;
@Override
protected void append(ILoggingEvent event) {
if (event == null || event.getMessage() == null) {
return;
}
// 必须设置 appName
if (appName == null || appName.isEmpty()) {
return;
}
String level = event.getLevel().toString();
String loggerName = event.getLoggerName();
String msg = event.getFormattedMessage();
String threadName = event.getThreadName();
Throwable throwable = event.getThrowableProxy() != null ? ((ThrowableProxy) event.getThrowableProxy()).getThrowable() : null;
// todo 这里实现自定义的日志处理逻辑
System.out.println(appName + ": 自定义 logback appender, threadName: " + threadName + ", level: " + level + ", loggerName: " + loggerName + ", msg: " + msg);
if (throwable != null) {
throwable.printStackTrace();
}
}
/**
* 定义 setter 方法,这样配置项会被注入到这个 appender 中
*/
public void setAppName(String appName) {
this.appName = appName;
}
}
https://github.com/dadiyang/appender
728x90