개발자의 오르막
[Log4j 1.2.16-ver Json Layout 적용기 #03] Logstash - jsonevent-layout 라이브러리 적용 본문
Java
[Log4j 1.2.16-ver Json Layout 적용기 #03] Logstash - jsonevent-layout 라이브러리 적용
계단 2022. 7. 11. 14:33
Logstash 의 Jsonevent-layout 이란?
Logstash 의 jsonevent-layout 은 log4j를 위한 json Layout Format 을 지원하는 라이브러리이다.
log4j 에서는 로그 레이아웃을 지원하기 위해 Appender 형식을 사용하는데, Jsonevent-layout 은 log4j 의 Appender 를 커스텀하여 지원한다.
log4j.appender.uploadProcessFile.layout=net.logstash.log4j.JSONEventLayoutV1
따라서 우리는 log4j 의 1.x.x version 을 그대로 사용하면서 logstash 가 지원하는 JsonLayout 을 log4j Appender 로 사용할 수 있다.
추가 라이브러리
jsonevent-layout-1.7.jar | json-smart-2.3.jar | asm-1.0.2.jar | common-lang-2.6.jar |
log4j.properties 적용방법
log4j.logger.UploadProcessLog = INFO, uploadProcessFile
log4j.appender.uploadProcessFile.Threshold = INFO
log4j.appender.uploadProcessFile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.uploadProcessFile.File = logs/upload-process.log
log4j.appender.uploadProcessFile.DatePattern=.yyyy-MM-dd
log4j.appender.uploadProcessFile.layout=net.logstash.log4j.JSONEventLayoutV1
- 요구사항에 맞게 기존 Log 파일은 그대로 두되, 고객 업로드 감지에 대한 과정만 기록하는 JsonFormat 로그파일을 작성할 수 있도록 설정하였다.
- Threshold 는 자세한 데이터보다는 업로드 과정만을 보여주기 때문에 로그 레벨을 INFO 로 설정하였다.
- 매일 로그파일을 생성할 수 있도록 DailyRollingFileAppender 를 사용하였고, 신규 파일로 로그를 저장하기 위해 logs/upload-process.log 로 지정하였다.
- 그리고 logstash 의 Jsoneventlayout 을 연동시켜주었다.
Json format 로그 메시지 예시
{
"@timestamp":"2022-07-15T07:28:34.762Z",
"source_host":"DESKTOP-NQ55UGN",
"file":"CommonUtils.java",
"method":"moveToWorkDir",
"level":"INFO",
"line_number":"850",
"thread_name":"DefaultQuartzScheduler_Worker-1",
"@version":1,
"logger_name":"UploadProcessLog",
"message":"WORK File Info Send Http Server STEP",
"class":"net.catenoid.watcher.upload.utils.CommonUtils",
}
upload-process.log 파일 출력 형태 예시
{"level":"INFO ","timestamp":"2022-07-11 11:16:40","thread":"main","file":"UploadProcessMsg.java", "method":"infoJsonLog", "line":"35","message":"WORK File Info Send Http Server STEP"}
{"level":"INFO ","timestamp":"2022-07-11 11:16:43","thread":"main","file":"UploadProcessMsg.java", "method":"infoJsonLog", "line":"35","message":"WORK File Info Send Http Server STEP"}
UploadProcessLogDto 생성
public class UploadProcessLogDTO {
private UploadMode uploadMode;
private String currentStep;
private String totalStep;
private String stepName;
private String description;
private String title;
private String contentProviderKey;
private String physicalPath;
private String uploadPath;
private String uploadFileKey;
private ContentInfoDTO mediaInfo;
public UploadProcessLogDTO(UploadMode uploadMode, String currentStep, String stepName,
String description, ArrayList<FileItemDTO> files) {
this.uploadMode = uploadMode;
this.currentStep = currentStep;
this.totalStep = getTotalStep(uploadMode);
this.stepName = stepName;
this.description = description;
if (files.size() > 0) {
this.contentProviderKey = getContentProviderKey(files);
}
}
public String getJsonLogMsg() {
putMdcUploadInfo();
return this.stepName;
}
...
}
- 최초 UploadProcessLog 구현체를 생성하여, 위의 소스처럼 UploadProcessLogDto Logger 를 생성, 해당 구현체에만 의존성을 지니게 하려하였지만, 로그가 찍히는 위치가 구현체 내부로 일관되다보니 , 효용성이 많이 떨어지게 되었다.
- 어디 위치에서 log 가 찍혔는지, error 가 찍혀는지 알 수 있어야한다.
- 따라서 로그가 찍히는 클래스파일에 아래와 같은 Logger 를 별도 생성하였다.
private static Logger uploadProcessLog = Logger.getLogger("UploadProcessLog");
- 그 후 위의 Dto 인스턴스를 생성하여, 우리가 찍고자하는 Json 형태의 String 을 uploadProcessLog 에 주입하면, JSON 형태의 로그가 출력된다.
UploadProcessLogDTO step1Msg = new UploadProcessLogDTO(
UploadMode.FTP, "1", "Ls Parsing New File Items STEP",
"Ls parsing file cnt : " + files.size() + ", dirs cnt : " + dirs.size(),
files);
uploadProcessLog.info(step1Msg.getJsonLogMsg());
JSON MSG 로 로깅하기
JSONLayoutV1 을 통해 Log 메시지를 JSON Format 으로 제공할 수 있었다. 하지만 Message 에 들어가는 정보 또한 String 이 아닌 JSON 형태로 제공하는 것이 필요했다.
log4j2 에서는 org.apache.logging.log4j.message.ObjectMessage 을 제공하여 ObjectMessage 객체를 생성해 로그로 던지면 손쉽게 Json Message 를 출력할 수 있으나, log4j-1.x.x 에서는 제공하지 않는다.
따라서 log4j-1.x.x 에서도 지원하는 MDC ( Mapped Diagnostic Context ) 를 활용하여 Map 의 형태로 로깅을 지원하였다.
UploadProcessLogDto
private void putMdcUploadInfo() {
MDC.clear();
MDC.put("uploadMode", this.uploadMode);
MDC.put("currentStep", this.currentStep);
MDC.put("totalStep", this.totalStep);
MDC.put("description", hasText(this.description) ? this.description : "");
if (hasText(this.contentProviderKey)) {
MDC.put("contentProviderKey", this.contentProviderKey);
}
if (hasText(this.title)) {
MDC.put("title", this.title);
}
if (hasText(this.uploadPath)) {
MDC.put("uploadPath", this.uploadPath);
}
if (hasText(this.physicalPath)) {
MDC.put("physicalPath", this.physicalPath);
}
if (hasText(this.uploadFileKey)) {
MDC.put("uploadFileKey", this.uploadFileKey);
}
}
MDC Log 출력 형태
"mdc":{
"currentStep":"4-1",
"totalStep":"5",
"contentProviderKey":"jungin-kim",
"description":"move from \/home\/kollus\/upload\/jungin-kim\/_None\/sample.webm to \/mnt\/medianas\/working\/jungin-kim",
"uploadMode":"FTP",
"physicalPath":"\/home\/kollus\/upload\/jungin-kim\/_None\/sample.webm",
"title":"sample",
"uploadFileKey":"DSFDS123SDFDS",
"uploadPath":"\/jungin-kim\/_None\/sample.webm",
"mediaInfo":{
"imageWidth":null,
"videoRatio":"1.778",
"imageFormat":null,
"videoFormat":"AVC",
"rotation":"0",
"format":"Matroska",
"audioFormat":"Opus",
"videoFrameRate":null,
"audioCodec":null,
"audioBitrate":null,
"audioSampleRate":"48000",
"imageHeight":null,
"videoHeight":"720",
"duration":null,
"videoBitrate":null,
"videoWidth":"1280",
"videoDuration":null,
"scanType":null,
"audioDuration":null,
"videoCodec":null
}
}
Reference
- log4j-jsonevent-layouy Git Repository 주소 : https://github.com/logstash/log4j-jsonevent-layout
- 라이브러리 다운로드 주소 : https://mvnrepository.com/artifact/net.logstash.log4j/jsonevent-layout/1.7
- MDC 공식문서 : https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html
'Java' 카테고리의 다른 글
Java 로 외부 프로세스 실행하기, FFmpeg 활용 (Process Builder) (0) | 2022.08.18 |
---|---|
DTO 와 VO, 그리고 Entity 의 역할과 차이 (0) | 2022.08.03 |
[Log4j 1.2.16-ver Json Layout 적용기 #02] 기존 공통 라이브러리 의존성에 따른 Log4j2 Mig 이슈 (0) | 2022.07.11 |
[Log4j 1.2.16-ver Json Layout 적용기 #01] 로그 개선 방향 선정 (0) | 2022.07.04 |
Java - compile (0) | 2019.08.23 |
Comments