본문 바로가기
Java

시스템에 로그(Log) 남기기.(SLF4J)

by 완기 2020. 12. 18.
728x90
반응형

개발을 하다 보면 Error나 Exception이 발생할 가능성이 있는 곳에

System.out.println()을 통해 값을 찍어보거나 프로그램이 어디까지 실행이 됐는지 확인을 할 수 있다.

 

나 또한 이런 방법을 많이 써왔는데, 로거나 로그 관련 프레임워크를 써보지 않았다는 점에서 많이 부끄러웠고,

 

이 참에 제대로 알아보기로 한다.

 

일단. 앞서 언급한 System.out.println()도 콘솔에 로그를 찍을 수 있는 가장 간단하면서 쉬운 방법이다.

 

하지만 프로그램이 운영되는 데는 전혀 쓸모없고,

무조건 실행되고

단지 실행 단계에서만 확인하려고 적어놓는 경우가 대부분이고 

실행 속도 또한 시스템에 의존적이고,

실행될 때, 다음 프린트 문을 기다리게 만들고 심한 경우 문자열 연산까지 더해진 경우도 있다.

 

쉽게 말해, 시스템의 성능에 좋지 않다는 말이다.

 

그렇다면 어떤 방법으로 디버깅을 하거나 로그를 찍는 게 좋을지에 대한 방법은 로그를 찍는 프레임워크에 있다.

 

SLF4J는 자바 진영의 다양한 로깅 프레임워크를 단순하게 사용하기 위해 인터페이스를 퍼사드 패턴 형태로 추상화된 API를 제공한다.

 

 

 

일단 사용을 위해선 gradle에 아래 내용을 추가해주자.

compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30'
testCompile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'

아래 내용을 추가해준 후, refresh를 한 번 해준 다음,

slj4j에 대한 설정이 필요한데, 이 설정 파일을 기반으로 로그를 찍을 범위(?)를 정한다.

 

//Log level
1.trace
2.debug
3.info
4.warn
5.error

위와 같은 5가지의 로그 레벨이 있는데,

 

1.trace : 프로그램이 실행되면서 발생되는 모든 것을 말 그대로 추적해서 콘솔에 찍는다. 별 다르게 많이 사용할 일은 없고 굉장히 많은 내용이 출력이 되기 때문에 시스템이 느려질 수 있다. 때문에 trace설정은 비추한다.

 

2.debug : 프로그램이 실행되는 과정에서 말 그대로 값을 찍어보고 싶을 때, 쓴다. 설정 파일의 레벨에 따라 출력되지 않을 수 있다.

 

3.info: 프로그램에 실행시 정보들을 출력하는데 default값이다. 로깅 프레임워크를 적용하기 전에 스프링을 실행하면

이런 정보들이 대부분 INFO에 해당하고 실제로 콘솔 좌측에도 INFO라고 표기된걸 볼 수 있다.

4.warn : 말 그대로 경고성 콘솔들이 출력된다. 예를 들면, Runtime환경에서 발생할 수 있는 요소들을 출력하거나 DB커넥션 정보 등, 당장 실행에는 문제가 없지만 특정 요청이 들어왔을 때, 필요한 것들이 제대로 설정되어있지 않거나 기타 여러 오류들에 대해 이런 오류를 띄운다.

example

5.error : 말 그대로 error 발생 시, 콘솔에 로그를 찍는 로그 레벨이다. 

보통의 try catch 문은 익셉션이 발생했을 때, e.printstacktrace();라는 메서드를 사용해서 내장 톰캣 디렉터리에 로그를 찍지만, 이 또한 콘솔에 로그를 찍고 IO를 발생시키기 때문에 성능에 영향을 준다. 

 

 

그래서 대신 쓸 수 있는 방법이 로거를 이용하는 것인데,

catch절에서 e.printstacktrace() 대신에 log.error()을 이용해서 에러가 발생했을 때, 로그를 찍는다.

위의 경우에는 에러가 발생했을때만 로그를 발생시켜 위와 비슷한 성능을 낼 수 있지만

일반적인 try문이나 기타 코드에 들어가게 되면 에러가 발생했을 때만 log.error()을 거치기 때문에

무조건 실행되는 System.out.println(); 보다는 좋은 성능을 기대할 수 있다.

 

 


설정파일

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">

    <!--어디에, 어떤 포맷으로 로그를 남길지 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>%d{HH:mm} %-5level %logger{36} - %msg%n</Pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
	      <file>{로그 파일을 남길 경로}</file>
        <!--언제 백업될지-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/Users/mac/Desktop/logs/access-%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--처음으로부터 최대 30개 생성,넘어가면 이전 로그 삭제-->
            <maxHistory>30</maxHistory>
        </rollingPolicy>

        <encoder>
            <Pattern>%d{HH:mm} %-5level %logger{36} - %msg%n</Pattern>
        </encoder>
    </appender>

    <!--name패키지에 속한 클래스에서 출력하는 로그는 info 이상의 레벨에 해당하는 것으로 출력-->
    <logger name="org.springframework" level="info"/>
    <logger name="kr.or.connect" level="debug"/>

    <root level="debug">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

java클래스 파일로도 설정할 수 있지만, 이번 게시글에선 xml파일로 설정하는 방법으로 진행한다.

일단 파일 이름은 logback-spring.xml로 설정하게 되면 스프링이 실행 시 해당 파일을 자동적으로 slf4j의 설정 파일로 인식한다.

 

그리고 나는 콘솔과 로그 파일로 남기길 원해서 appender에 console과 file로 남기게 되었고,

file안에는 남길 경로, 최대 생성 개수, 파일명 패턴 등을 설정할 수 있다. 

 

제일 아래쪽에 보면 위에서 언급한 logLevel을 설정할 수 있는데, debug로 설정되어있기 때문에, log.debug()가 로그에 찍힌다. 

 

 


사용방법

사용 방법은 매우 간단하다.

내가 로그를 찍을 자바 파일 제일 위에 어노테이션을 달아주면 된다.

첫 글자는 대문자 S이다.

소문자 s로 작성하게 되면 ide에서 자동완성이 안 뜰 수 있다.

 

일단 어노테이션으로 작성해주면

밑에서 두 번째 줄처럼 내가 원하는 위치에 로그를 찍을 수 있게 된다.

728x90
728x90

댓글