Spring Log4j 로그 DB에 저장하기
JDBCAppender를 상속한 커스텀클래스 없이 진행하려 했으나...
로그에 포함된 특수문자 (')로 인하여 에러가 발생하였다...ㅠㅠ
여러가지 시도한 후 아직까지 에러가 나타나지 않은 방법을 기록해두기로 한다...
1. DB Table 작성 (Mysql)
CREATE TABLE `tbl_log` (
`regdate` timestamp NOT NULL,
`level` varchar(100) NOT NULL,
`logger` varchar(100) NOT NULL,
`message` varchar(5000) DEFAULT NULL
)
2. log4j.xml 수정
- log4j.xml 상단
<appender name="db" class="mini.home.jdbc.CustomJDBCAppender" />
<param name="driver" value="com.mysql.jdbc.Driver" />
<param name="URL" value="jdbc:mysql://DB주소" />
<param name="user" value="DB아이디" />
<param name="password" value="DB암호" />
<param name="sql" value="insert into tbl_log values(now(), '%p', '%C', '%m')" />
</appender>
- log4j.xml 하단
<root>
<priority value="warn" />
<appender-ref ref="console" />
<appender-ref ref="db" />
</root>
3. CustomJDBCAppender 작성 (https://bryan7.tistory.com/406)
import org.apache.log4j.LogManager;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.jdbc.JDBCAppender;
public class CustomJDBCAppender extends JDBCAppender {
@Override
protected String getLogStatement(LoggingEvent event) {
Object eventMsgObj = event.getMessage();
String eventMessage = "";
if( eventMsgObj != null && eventMsgObj.toString() != null ) {
// DB에 입력하기 위해서는 (') 를 ('')로 치환해야지 에러없이 제대로 입력된다.
eventMessage = eventMsgObj.toString().replaceAll("'", "''").replaceAll("(?<!\r)\n", "\r\n");
}
if (null != event.getThrowableInformation() ) {
// DB에 저장할 때는 "\r\n" 이 아닌 "\n"만 "\r\n"으로 바꾼다.
// 부정형 후방탐색 정규표현식 이용 => replaceAll("(?<!\r)\n", "\r\n")
Throwable throwable = event.getThrowableInformation().getThrowable();
String message = "";
if( throwable != null ) {
message = throwable.getMessage();
if( message != null ) {
message = message.replaceAll("'", "''").replaceAll("(?<!\r)\n", "\r\n");
}
}
Exception exception = new Exception(message, throwable);
exception.setStackTrace(throwable.getStackTrace());
LoggingEvent clone = new LoggingEvent(event.fqnOfCategoryClass,
LogManager.getLogger(event.getLoggerName()), event.getLevel(), eventMessage, exception);
return getLayout().format(clone);
} else {
LoggingEvent clone = new LoggingEvent(event.fqnOfCategoryClass, LogManager.getLogger(
event.getLoggerName()), event.getLevel(), eventMessage, null);
return getLayout().format(clone);
}
}
}
참조 블로그
2. https://bryan7.tistory.com/406
3. https://handcoding.tistory.com/135
4. https://itmore.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81-Log4j-%EB%8B%A4%EB%A3%A8%EA%B8%B0
5. https://www.tutorialspoint.com/log4j/log4j_logging_database.htm
** 잘못된 내용이 있으면 일러주시면 감사하겠습니다.
written by 미니아빠