본문 바로가기
공부/JAVA

Spring Boot SLF4J + Logging(Logback) 으로 로그 파일 남기기

by yeaseul912 2022. 12. 21.
728x90

Log 를 file로 추출하고 싶어서 찾아보았다.


Logging이란?

정보를 제공하는 일련의 기록인 로그를 생성하도록 시스템을 작성하는 활동

Application 을 운영기위해선 요청을 보내거나, 응답을 받거나, 문제가 발생하였을때 생기는 정보들이 필요하다. 특히 아래와 같을때 유용하게 사용할 수 있다.

  • 초보자들은 프로그램을 이해하기 위해, 설계자들은 시스템의 복잡성을 이해하기 위해
  • 테스트 시 버그에 대한 정보를 알기위해
  • 구문 혹은 함수들 사이에 걸리는 시간 등의 성능에 관한 통계와 정보를 알기 위해

Log Library

 

가장 간단하게 로그를 출력하는 방법은 System.out.println() 이다.

하지만 System.out.println 은 출력되는 로그의 양과 수준을 조절할 수 없고, 출력된 로그를 파일 등에 저장하기 불편하다.

성능 면에서도 System.out.println을 자주 사용하면 어플리케이션이 굉장히 느려진다.

그래서 로깅을 할때 라이브러리를 사용한다.

  1. java.util.logging
    • JDK1.4 부터 포함된 표준 로깅 API, 별도의 라이브러리 추가할 필요가 없다.
    • 하지만 기능이 많이 부족하여 다른 로그 라이브러리를 더 많이 사용한다.
  2. Apache Commons Logging
    • 아파치 재단의 Commons Library중 로그 출력을 제공하는 라이브러리다.
  3. Log4j
    • 아파치 재단에서 제공하며, 가장 많이 사용되는 라이브러리다.
  4. Logback
    • Log4j를 개한 사람이 Log4j의 단점을 개선하고 기능을 추가하여 개발한 라이브러리다.

SLF4J는 이러한 라이브러리들을 하나의 통일된 방식으로 사용할 수 있는 방법을 제공하고 있다.


SLF4J란?

SLF4J는 로깅 Facade이다. 로깅에 대한 추상 레이어를 제공하는 interface의 모음이다.

여러 라이브러리를 같은 방법으로 사용할 수 있도록 도와준다.!!

아래 그림과 같이 어떤 logging 라이브러리를 쓰는 어플리케이션이라도 SLF4JAPI(하늘색 상자)를 사용하여 통합되고 있다. 따라서 더 좋은 logging 라이브러리가 나오면 바꾸어도 코드를 변경할 필요가 없어진다.

출처 https://www.slf4j.org/manual.html

 


SLF4J + Logback 실습

일단 내 환경은

java 11

spring boot 2.7.1

gradle 환경

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	implementation 'com.google.code.gson:gson:2.9.0'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	implementation 'org.springframework:spring-webflux:5.3.23'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

	// logback 사용을 위해 아래 library 추가함
	implementation 'org.slf4j:slf4j-api:1.7.5'
	implementation 'org.slf4j:jcl-over-slf4j:2.0.3'
}

logback-classic 라이브러리는 slf4j-api 1.7.x 버전과 바인딩 되기 떄문에 1.7.x 버전으로 설치해야 한다. 안그러면 No SLF4J providers were found 에러 뜸 (나처럼!)

 

/resource/logback.xml

<?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:ss} %-5level %logger{36} - %msg%n</Pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/tmp/access-1.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/tmp/access-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>

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

    <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>

Appender : 어디에 어떤 포맷으로 로그를 남길 것인지

    - ConsoleAppender : Console에 로그를 어떤 포맷으로 출력할지 설정

    - FileAppender : 파일에 로그를 어떤 포맷으로 출력할지 설정

    - RollingFileAppender : 로그 양이 많아지면 하나의 파일로 관리하기가 어려워졌을 때 하루 단위로 로그 파일을 백업하면서 로그를 남기고자 할 때 사용.

 

encoder    - Pattern : 로그를 출력할 포맷 지정        %d{HH:mm}  현재 시간        %-5level        로그 레벨을 5의 고정폭 값으로 출력        %logger{36}  logger의 이름을 축약해서 출력        %msg%n      메세지 출력 / 줄바꿈    - file : 기본적으로 기록되는 파일명    - rollingPolicy : 파일이 언제 백업 될지결정        - fileNamePattern : 백업된 로그파일 이름        - maxHistory : 최대 몇게 생성할 것인지, 최대 갯수가 다 차면 이전 로그 파일을 삭제하고 생성한다.디렉토리 경로가 없는데, 나같은 경우에는 C:\tmp\access.log에 있었따.

 

로그사용하기

Class를 생성하여 본다. 나는 스케쥴러 사용!

@Slf4j
@Component
public class Scheduler {
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Scheduled(fixedRate = 30000)
    public void scheduleTaskUsingfixedRate() {
        log.info("스케쥴러 작동 시작 ! 현재 시각 : {} ", dateFormat.format(new Date()));
        log.warn("이제 파일에 잘 저장되겠지?흐흐흐");
    }
}

 

C:\temp\access-1.log


공식홈페이지에 Logging 내용이 있어서 해석해 보았다.

결론은 java에서 Log를 사용하는데 여러 라이브러리들이 있고, 커스텀도 가능하고, 라이브러리 설정 방법 등이 나와있다. Logback 사용하는 방법 정도를 얻을 수 있엇다.

 

해석한 목차

  • 4.Logging
    • 4.1. Log Format
    • 4.2. Console Output
      • 4.2.1. Color-coded Output
    • 4.3. File Output     <-- 내가 원하던거 이거이거
    • 4.4. File Rotation

 

 

  • Spring boot 공식 홈페이지 > core features > Logging  

https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging

 

Core Features

Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use a variety of external configuration sources, include Java properties files, YAML files, environment variables, an

docs.spring.io

4. Logging

스프링 부트는  모든 내부 로그에  "Commons Logging" 을 사용하지만 기본 로그 구현은 열어둡니다. 초기 구성으로 Java Util Logging, Log4j2, Logback 등이 제공됩니다. 각각의 loggers 들은 콘솔 출력과 파일 출력 또한 가능하도록 미리 설정되어져있습니다.

 

기본적으로, Spring boot Starters 를 사용했다면 logging을 하는데 Logback을 사용합니다. 적절한 Logback 라우팅도 Java Util Logging, Commons Logging, Log4J, SLF4J를 사용하는 dependent libraries가 모두 올바르게 작동하도록 포함됩니다.

 

 Tips.

자바에는 로깅 프레임워크가 많이 있습니다. 목록이 많아 보여도 걱정마세요. 일반적으로 로깅 logging dependencies를 바꿀 필요 없이 Spring Boot Default 가 잘 작동합니다.

 

 Tips .

servlet container 나 application server에 Application을 배포할 때, Java Util Logging API와 함께 수행된 로깅은 application log에 전송되지 않습니다. 이를 해 container 나 배포된 다른 application이 수행한 로깅이 나의 application log에 나타나는 것을 방지합니다.

 

4.1 Log Format

Spring Boot 기본 로그 출력은 아래와 비슷합니다.

2022-11-24T17:02:47.423Z  INFO 18487 --- [           main] o.s.b.d.f.s.MyApplication                : Starting MyApplication using Java 17.0.5 with PID 18487 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2022-11-24T17:02:47.428Z  INFO 18487 --- [           main] o.s.b.d.f.s.MyApplication                : No active profile set, falling back to 1 default profile: "default"
2022-11-24T17:02:49.682Z  INFO 18487 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-11-24T17:02:49.709Z  INFO 18487 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-11-24T17:02:49.710Z  INFO 18487 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.1]
2022-11-24T17:02:49.877Z  INFO 18487 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-11-24T17:02:49.880Z  INFO 18487 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2384 ms
2022-11-24T17:02:50.499Z  INFO 18487 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-11-24T17:02:50.524Z  INFO 18487 --- [           main] o.s.b.d.f.s.MyApplication                : Started MyApplication in 4.578 seconds (process running for 5.179)

다음 항목이 출력됩니다.

  • 날짜와 시간 : 밀리초 단위의 정밀도와 시간순 정렬
  • 로그 레벨 : ERROR, WARN, INFO, DEBUG, TRACE 있음.
  • Process ID
  • --- :  실제 로그 메세지의 시작부분 구분 기호
  • Thread 이름 : 대괄호 ( [ ] ) 로 감싸져 있는 부분. ( 잘릴 수 있음 )
  • Logger 이름 : 일반적으로 소스 클래스 이름 ( 종종 축약됨 )
  • 로그 메세지

 Note. 

Logback에는 FATAL 레벨이 없습니다. ERROR 에 매핑됩니다.

 

4.2 Console Output

기본 로그 구성은 작성되는 대로 콘솔에 메시지를 나타냅니다.

$ java -jar myapp.jar --debug

 Note. 

 application.properties 에 debug=true 로 지정할 수도 있습니다.

 

debug 모드를 활성화 하면, core logger(embedded container, Hibernate, and Spring Boot) 들이 더 많은 정보를 출력 할 수 있습니다. debug 모드를 실행한다고 해서 debug 레벨의 모든 메시지를 기록하도록 application이 구성되지 않습니다. (=Enabling the debug mode does not configure your application to log all messages with DEBUG level.)

 

또는 application 시작 시 --trace 를 사용하여 "trace" 모드를 사용할 수도 있다.(혹은 application.properties trace=true)  그렇게 하면 core loggers 선택에 대한 추적 로깅이 가능합니다. (embedded container, Hibernate schema generation, and the whole Spring portfolio). (=Doing so enables trace logging for a selection of core loggers)

 

4.2.1. Color-coded Output

터미널에서 ANSI 를 지원한다면, 가독성을 위해 색상별로 출력을 합니다. 자동 감지를 재정의 하기 위해 지원되는  spring.output.ansi.enabled 를 설정할 수 있습니다.

 

color 코딩은 %clr 를 사용하여 구성합니다. 가장 간단한 형태에서 변경된 출력 색상은 log level을 따릅니다.

%clr(%5p)

log level 과 색상이 아래와 같이 매핑 됩니다.

Level Color
FATAL Red
ERROR Red
WARN Yellow
INFO Green
DEBUG Green
TRACE Green

또는 변환 옵션으로 제공하여 사용할 색상이나 스타일을 지정할 수 있습니다. 예를 들어 아래와 같이 설정하면 노란 글로 만들 수 있습니다.

%clr(%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}){yellow}

아래와 같은 색상과 스타일을 지원합니다.

  • blue
  • cyan
  • faint
  • green
  • magenta
  • red
  • yellow

4.3. File Output

기본적으로 Spring Boot 는 console 에서만 기록하고 로그 파일을 작성하지 않습니다. 로그파일을 작성하고 싶다면 logging.file.name 혹은 logging.file.path 를 설정해야 합니다. ( application.properties 같은데서 )

 

아래 테이블은 logging.* 속성을 사용할 수 있는 방법을 보여줍니다. 

loggin.file.name loggin.file.path Example Descrption
(none) (none)   Console only logging
Specific file (none) my.log 특정 로그 파일에 작성합니다. 이름은 절대경로 혹은 현재 directory에 상대경로일 수 있습니다.
(none) Specific file /var/log 특정 폴더에 spring.log 를 작성합니다.
절대경로 혹은 상대경로

로그 파일은 10MB가 넘어가면 교체되며(아카이브 형태로,4.4 참고),  콘솔 출력과 마찬가지로 기본적으로 ERROR-level, WARN-level, and INFO-level 메세지가 출력됩니다.

 

 Tips.

Logging 속성은 실제 로깅 인프라와 독립적입니다. 결과적으로 특정 구성 키 Spring Boot에 의해 관리되지 않습니다.(ex : logback.configurationFile )

 

4.4 File Rotation

Logback을 사용한다면, application.properties나 application.yaml 파일을 사용하여 로그 회전 설정?(= fine-tune log rotation)을 미세조정할 수 있습니다. 다른 모든 로깅 시스템의 경우, 직접 회전설정(= rotation settings)을 구성해야 합니다.(ex: Log4j2를 사용하면 log4j2.xml 이나 log4j2-spring.xml  파일을 추가할 수 있습니다.)

 

아래와 같은 회전 정책 설정(=rotation policy properties)을 지원합니다.

Name Description
logging.logback.rollingpolicy.file-name-pattern The filename pattern used to create log archives.
( log archives를 만드는데 사용되는 파일이름 패턴 )
logging.logback.rollingpolicy.clean-history-on-start If log archive cleanup should occur when the application starts.
어플리케이션을 시작할 때 log archive 정리가 일어나야 하는 경우
logging.logback.rollingpolicy.max-file-size The maximum size of log file before it is archived.
archive 가 되기 전 로그 파일의 최대 크기.
logging.logback.rollingpolicy.total-size-cap The maximum amount of size log archives can take before being deleted.
log archives가 삭제 되기 전에 취할 수 있는 최대 크기 
logging.logback.rollingpolicy.max-history The maximum number of archive log files to keep (defaults to 7).
보관할 archive log file의 최대 수

 

 

Reference

Java Logger example

SLF4J - Simple Logging Facade for Java

Spring Boot Logging

https://stackoverflow.com/questions/9740569/logger-for-java-library

SLF4J 이용하여 로그 남기는 방법 (with Logback)

로깅에 대하여

 

반응형

'공부 > JAVA' 카테고리의 다른 글

여러대의 서버에서 스케줄 처리하기 (ShedLock)  (0) 2023.05.15
Mac Java_Home 환경 변수 설정  (2) 2022.11.21
[JAVA] java 버전, maven(?) error  (0) 2022.07.04
[JAVA] Extends 와 Super  (0) 2022.06.22
[JAVA] 제네릭(Generic)  (0) 2022.06.21

댓글