로깅 기능 개발하고 슬랙으로 알림 받기


LoggingFilter로 로그 남기기

Elasticsearch에 대해 알아보면서 ELK 스택도 함께 알게 되었고

ELK(ElasticSearch Logstash Kibana) 스택으로 로깅을 구현해보기로 했다.

Elasticsearch란?


구현 방법과 함께 어떤 모습으로 로그가 쌓이는지 확인해보고

Slack에 ERROR 로그 알람을 보내는 것까지 구현해보자.



1. Logback.xml

Spring에서 기본적으로 제공하는 로그가 있지만 Logstash에 로그를 쌓아

엘라스틱서치로 보내고 싶기 때문에 resource 에 다음 파일을 추가했다.

logback.xml 파일을 따로 생성해 설정해주지 않으면

스프링이 설정해둔 로그가 찍힌다.

logging




2. Gradle

implementation 'net.logstash.logback:logstash-logback-encoder:6.6'

logstash 사용을 위해 위 의존성을 추가한다.



3. LoggingFilter.java

@Component
public class LoggingFilter extends OncePerRequestFilter {

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
		FilterChain filterChain) throws IOException {
		ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
		ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);

		try {
			filterChain.doFilter(requestWrapper, responseWrapper);
		} catch (Exception e) {
			logger.error(e);
		} finally {
			LoggingRequest loggingRequest = getLoggingRequest(requestWrapper);
			String log = JsonUtils.toJson(loggingRequest);
			logger.info(log);
		}

		responseWrapper.copyBodyToResponse();
	}

	private LoggingRequest getLoggingRequest(ContentCachingRequestWrapper request) {
		String requestURI = request.getRequestURI();
		String method = request.getMethod();
		return new LoggingRequest(requestURI, method);
	}

}


OncePerRequestFilter는 모든 서블릿에 일관된 요청을 처리하기 위해 만들어진 필터이다.

이 추상 클래스를 구현한 필터는 사용자의 한번에 요청 당 딱 한번만 실행되는 필터를 만들 수 있다.

필터에 대한 자세한 이야기는 다른 포스팅에서 해보자.

필터에서 logger 로그를 남기면 kibana에서 로그를 확인할 수 있다.



4. docker-compose

https://github.com/deviantony/docker-elk

위 repository를 clone 받아서 설정을 마치고 docker-compose up 명령으로 elk를 띄운다.


설정해야 하는 부분

input {
	tcp {
		port => 5000
		codec => json_lines
	}
}

filter {
	json {
		source => "message"
		remove_field => ["message"]
	}
}

output {
	elasticsearch {
		hosts => "elasticsearch:9200"
	}
}


기본 포트



Error 로그 Slack으로 알림 받기

ELK 스택으로 로깅을 구현했다.

슬랙으로 알림을 받는건 더 쉽게 구현할 수 있다.




1. Logback.xml

<appender name="SLACK" class="com.github.maricn.logback.SlackAppender">
    <webhookUri>${webhook-uri}</webhookUri>
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %msg %n</pattern>
    </layout>
    <colorCoding>true</colorCoding>
</appender>

<appender name="ASYNC_SLACK" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="SLACK"/>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>WARN</level>
    </filter>
</appender>

<logger name="com.example.loggingslack" level="ALL">
    <appender-ref ref="ASYNC_SLACK"/>
</logger>


위에서 먼저 설정한 logstash 설정과 함께 Logback.xml에 작성해주면 된다.






2. Incoming Webhooks

슬랙 채널에서 Incoming Webhooks을 추가하여 원하는 형태로 설정하고

webhookUri를 복사해서 Logback.xml 에 넣어준다.

slack1



3. Gradle

salck 알람을 위해 다음 의존성을 추가해준다.

implementation "com.github.maricn:logback-slack-appender:1.4.0"



위 모든 설정이 끝나면 ERROR 로그가 찍힐 때마다

다음과 같이 내가 설정한 슬랙 채널에 알람이 온다.

slack


지금 전송된 알람은 테스트한 것이기 때문에 “ERROR” 라는 메시지만 전송되었지만

에러가 발생한 원인과 원하는 메시지가 전송되도록 설정해놓으면 된다.