서버 개발자가 로그를 보는건 그냥 서버들어가서 확인하면 된다.
하지만 프론트 개발자와 협업을 하는 경우 서버 로그 확인 요청을 받는 경우가 종종 있다.
이런 경우 웹에서 바로 로그를 확인하면 좋을 것 같아 만들어보았다.
Logback의 appender를 사용한 방법이다.
logback은 appender로 로그를 처리하는 방식을 관리한다.
여러가지 방식의 appender를 logback이 제공해주지만 기본 제공해주는 appender 중엔 웹 요청으로 응답을 처리하는 appender는 없다.
custom appender를 하나 만들어준다.
public class BlueskyLogbackAppender<E> extends UnsynchronizedAppenderBase<E> { private BlueskyLogbackAppenderService<E> blueskyLogbackAppenderService; @Setter private Encoder<E> encoder; public BlueskyLogbackAppender(BlueskyLogbackAppenderService<E> blueskyLogbackAppenderService) { this.blueskyLogbackAppenderService = blueskyLogbackAppenderService; } @Override protected void append(E eventObject) { if (!isStarted()) { return; } blueskyLogbackAppenderService.addLog(eventObject, new String(encoder.encode(eventObject))); } }
해당 appender는 append 실행 시 지정된 service의 메소드를 수행한다.
해당 서비스를 구현한다.
public class BlueskyLogbackAppenderService<E> { private static final int queueSize = 500; @Getter private Queue<LogObject<E>> logQueue = new LinkedBlockingQueue<>(queueSize); public void addLog(E eventObject, String logMessage) { if (logQueue.size() >= queueSize) { logQueue.remove(); } logQueue.offer(new LogObject<E>(eventObject, logMessage)); } @Data @AllArgsConstructor public static class LogObject<E> { E eventObject; String logMessage; } }
해당 서비스는 로컬 queue에 로그 내용을 담는 기능을 제공하고 500개가 초과하면 가장 오래된 로그를 비우고 추가하는 식으로 동작한다.
이제 기존 logback 설정에 위 custom appender를 추가한다.
@Configuration public class BlueskyLogbackConfig implements InitializingBean { @Bean public BlueskyLogbackAppenderService<ILoggingEvent> blueskyLogbackAppenderService() { return new BlueskyLogbackAppenderService<ILoggingEvent>(); } @Override public void afterPropertiesSet() throws Exception { LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); BlueskyLogbackAppender<ILoggingEvent> blueskyLogbackAppender = new BlueskyLogbackAppender<>(blueskyLogbackAppenderService()); blueskyLogbackAppender.setContext(loggerContext); blueskyLogbackAppender.setName("blueskyLogbackAppender"); RollingFileAppender<ILoggingEvent> appender = (RollingFileAppender<ILoggingEvent>) loggerContext.getLogger("ROOT").getAppender("FILE"); blueskyLogbackAppender.setEncoder(appender == null ? new PatternLayoutEncoder() : appender.getEncoder()); blueskyLogbackAppender.start(); loggerContext.getLogger("ROOT").addAppender(blueskyLogbackAppender); } }
위의 경우 logback.xml에 FILE이란 이름의 appender가 있는 경우 해당 appender의 encoder를 사용하는 설정이다.
파일로 남기는 로그의 로그 패턴을 그대로 사용하기 위해 가져왔다.
이제 log 가 발생할 때마다 blueskyLogbackAppenderService에 queue가 쌓이게 된다.
쌓아놓은 queue를 확인하는 호출 주소를 추가한다.
@RestController public class BlueskyLogbackDevCheckController { @Autowired private BlueskyLogbackAppenderService<ILoggingEvent> blueskyLogbackAppenderService; @GetMapping(value = "/logView", produces = MediaType.APPLICATION_JSON_VALUE) public List<String> logview() { return blueskyLogbackAppenderService.getLogQueue().stream().map(queue -> queue.getLogMessage().replaceAll(CoreConstants.LINE_SEPARATOR, "").replaceAll("\t", "")).collect(Collectors.toList()); } }
json으로 응답하는 것으로 설명을 했지만 appender는 이벤트 기반이기 때문에 특정 로그가 발생하면 메일로 알려준다거나 하는 식의 모니터링을 만들어 사용하는 방법이 실제론 더 효율적인 사용이 되지 않을까 싶다.
'Study > Java' 카테고리의 다른 글
Eclipse debug view의 Variables에 Error 가 표시되는 경우 (0) | 2019.04.19 |
---|---|
Eclipse Package Explorer 에서 Maven Dependencies 정렬하기 (0) | 2019.04.18 |
Spring Boot AutoConfigurtaion java.io.FileNotFoundException: class path resource [.class] cannot be opened because it does not exist 에러 (0) | 2019.04.03 |
Spring Boot AutoConfiguration 개발하기 (0) | 2019.03.28 |
Jasypt 암복호화 하기 (1) | 2019.03.01 |
Spring Boot log 설정하기 (0) | 2019.01.09 |
Spring Cloud Config Server 사용하기 (0) | 2019.01.03 |
Spring Data Mongodb 사용해보기 (0) | 2018.12.24 |
JDK 11에서 java.xml.bind 관련 에러 발생하는 경우 (0) | 2018.12.13 |
Spring Boot multi module, multi profile 환경에서 @PropertySouce 사용하기 (0) | 2018.12.10 |