프레임워크/스프링

[log4j2] Custom Appender 사용법 - 쿼리 출력 사용자화

지이구 2021. 12. 20. 17:02

 

 

쿼리 출력 사용자화

이미 만들어져있는 appender를 쓰는 방법은 널리고 널려있어서
사용자화해서 쿼리 출력할 수 있는 사용자 appender 사용법을 정리해보고자 한다

 

 

🏀 필요한 파일

1. pom.xml - log4j2 dependency 설정

2. Log4j2Appender.java - 실제로 쿼리 출력을 다룸

3. log4j2.xml - 1번의 appender를 사용하도록 설정하는 파일

 

🏀 pom.xml (실제 파일 예시)

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.15.0</version>
</dependency>

 

제일 기본이 되는 pom 설정.. 2.17.0 사용을 권장한다

나도 업그레이드 해야되는데 아직 못함 ..

 

 

🏀 log4j2Appender.java (실제 파일 예시)

package Appender.java파일의 패키지;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

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;

@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;
        }
       
        if (appName == null || appName.isEmpty()) {
            return;
        }
        
        String level = event.getLevel().toString(); //레벨
        
        long timemill = event.getTimeMillis();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String timestamp = df.format(timemill); //타임스탬프
        
        String loggerName = event.getLoggerName(); //로거 이름
        String msg = event.getMessage().getFormattedMessage(); //내용
        Throwable throwable = event.getThrown();
        
        //쿼리 출력 부분
        System.out.println("["+level+"] " +"["+timestamp+"] [" + loggerName + "] " + msg);
        if (throwable != null) {
            throwable.printStackTrace();
        }
    }

    @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("Error! Name is Null");
            return null;
        }
        if (appName == null) {
            LOGGER.error("Error! AppName is Null");
            return null;
        }
        if (layout == null) {
            layout = PatternLayout.createDefaultLayout();
        }
        return new Log4j2Appender(name, appName, filter, layout, true);
    }

}

 

 

appender 클래스는 주석 부분 읽고 print 하는 부분을 사용자화해서 사용하면 된다

🏀 log4j2.xml (실제 파일 예시)

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN" packages="Appender.java파일의 패키지">
	<appenders>
        <!-- Custom Appender -->
        <Log4j2Appender name="CustomAppender" appName="test_appender"/>

        <!-- Backup Log File -->
        <RollingFile name="file" fileName="로그파일위치/${date:yyyy}${date:MM}/Log.log"
        		filePattern="로그파일위치/${date:yyyy}${date:MM}/Log_%d{yyyy-MM-dd}_%i.log">
        	<PatternLayout pattern="[%-5p] %d{HH:mm:ss} [%C] - %m%n" /> <!--파일에 찍히는 형식 -->
			<Policies>
				<SizeBasedTriggeringPolicy size="10MB" />
				<TimeBasedTriggeringPolicy module="true" interval="1" /><!-- 매일 하나씩 -->
			</Policies>
			<DefaultRolloverStrategy max="500" fileIndex="min" /> <!-- 최대 500개 -->
   		</RollingFile>
    </appenders>
    <loggers>
        <!-- Root Logger Configuration -->
        <root level="INFO">
            <appender-ref ref="CustomAppender"/>
        </root>
        
        <!-- Custom Logger Configuration -->
		<logger name="org.mybatis" level="warn" additivity="false">
			<AppenderRef ref="CustomAppender" />
		</logger>

        <!-- Custom Logger Configuration -->
        <logger name="com.mytest" level="debug" additivity="false">
			<AppenderRef ref="CustomAppender" />
		</logger>
		<logger name="com.mytest.user.UserMapper.loginUser" level="debug" additivity="false">
			<AppenderRef ref="file" />
		</logger>
    </loggers>
</configuration>

 

위의 설정에서 Custom Appender 설정만 빼서 보면 아래와 같다

 

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN" packages="Appender.java파일의 패키지">
	<appenders>
        <!-- Custom Appender -->
        <Log4j2Appender name="CustomAppender" appName="test_appender"/>
    </appenders>
    <loggers>
        <!-- Root Logger Configuration -->
        <root level="INFO">
            <appender-ref ref="CustomAppender"/>
        </root>
    </loggers>
</configuration>

 

 

Appender를 CustomAppender로 설정할 때 최소한의 설정이고 이것만 가지고도 로그 출력이 가능하다

위의 실제 파일예시는 로그파일을 저장하는 것이 추가되어있는건데 특정 쿼리(login)만 sql을 모아 파일로 저장하는 예시이다

로그때문에 삽질하는 개발자들이 줄어들길 ㅠㅠㅠㅠㅠㅠ

어떤건 긁어다가 쓰기만해도 잘 출력되는데

긁어 쓸 자료가 마땅치 않을 때가 많다.....

코딩은 끝없는 구글링과의 싸움아닐까 ㅠ

그래서 쉽고 유용한 정보를 공유하자!!!!!!!! 개발자들이여!!!

 

728x90
반응형