Java Logging FrameworkSLF4JLoggerSentry for Spring Bootlogback 설정하기요소AppenderConsoleAppender구현 시, 로그 중복 해결 방법 → additivity=”false”SocketAppender, SSLSocketAppenderServerSocketAppenderPatternLayoutConversion Rule 추가하기File로 logging 남길 때에러 로그만 따로 관리하기 (LevelFilter)실습 config 파일하이버네이트 SQL 로그Timezone 설정Log level 테이블CharsetSpring Logback ExtensionMapped Diagnostic Context (MDC)MDC의 주요 개념왜 MDC를 사용하는가?Slack 로깅 설정
- System.out.println —> 너무 자주 찍어대면 성능 문제가 생길 수 있음. 안에서 synchronized 가 있기 때문에 자주 쓰면 오버헤드가 생길 수 있음 ⇒ 운영 상에서는 안하는 거다. 절대 쓰지 마라
Java Logging Framework
- Log4J
- Logback — SpringBoot에서기본적으로 제공. 현재 제일 많이 사용됨
- SLF4J가 위의 두개를 공통적으로 쓸 수 있도록 묶어 준것. Log4J를 쓰다가 Logback으로 쓰다가 바꾸려면 코드 다 바꿔야 하니까. 이것을 도입한 것
SLF4J
- 여러 로깅 프레잌워크를 추상화해 놓은 것
- Facade Pattern을 이용한 Logging Framework임

- 안에 어떤 클래스가 있는지를 모르고 바깥에서 제공해주는 API통해서 안의 클래스들을 활용
- 좋은 로깅 프레임워크가 나올 때마다 코드를 변경해야 하면 너무 힘들다.. slf4j 이용하고 binding만 바꿔주면 코드 변경없이 그대로 사용!
- SLF4J가 다양한 로깅 프레임워크를 지원하는데 이는 바인딩 모듈을 통해서 처리됨

Logger
- 로거 이름은 클래스의 이름을 주는데, 패키지가 다 포함된 클래스명으로 이름 지음
- 클래스에 하나(객체마다 생기는 것이 아니라)만 생겨야 하기 때문에 static
- 다른사람이 변경하면 안되니까 private final로 선언함
- Logger이름을 통해서 logging을 제어함
Sentry for Spring Boot
[ Sentry Docs ] Getting Started
logback 설정하기
logback 설정파일 찾는 순서
- logback-test.xml 찾고, 없으면 (이 파일은 test - resource 폴더 아래에)
- logback.groovy 찾고, 없으면
- logback.xml 찾고
- 모두 없다면 기본 설정 전략을 따름 BasicConfiguration
https://logback.qos.ch/manual/configuration.html — logback configuration 참조
요소
- appender : Logback delegates the task of
writing a logging eventto components called appenders - Layout : logback components responsible for transforming an
incoming event into a String - Encoders : responsible for
transforming an event into a byte arrayas well as writing out that byte array into anOutputStream
- property — 환경변수처럼 변수 정의해서 사용이 가능함
- springProperty — application.yml에 정의된 값을 logback 설정으로 가져올 수 있음
- conversionRule
- filter : Logback filters are based on ternary logic
allowing them to be assembled or chained together to compose an arbitrarily complex filtering policy. They are largely inspired by Linux's iptables.
Appender
ConsoleAppender구현 시, 로그 중복 해결 방법 → additivity=”false”
- 새 logger를 만들어서 appender-ref에 STDOUT을 추가하면 로그가 중복되어 출력됨. 이 때 이를 막으려면
<logger name="org.prgms" level="debug" additivity="false">이런 식으로 attribute 할당 해주어야 함
SocketAppender, SSLSocketAppender
- SocketAppender : log를 원격 서버로 보내기 위해 쓰이는 Appender임
- SSLSocketAppender: logging events 가 secure channel을 통해 전송됨
ServerSocketAppender
- SocketAppender는 로깅 이벤트를 전달하기 위해서 커넥션을 어플리케이션이 시작을 해야 함. 이를 보완하기 위해 ServerSocketAppender는 직접 커넥션을 맺지 않고 TCP socket을 listen만 하고 있음
- 원격 클라이언트로부터 커넥션 연결이 들어오기까지
PatternLayout
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> 이부분- logger.info 같은거 호출할 때 우리는 string을 전달하지만 내부적으로는 logging event라는 것이 만들어짐
- 그 logging event를 문자열로 바꾸어 주는 것이 Layout pattern
Conversion Rule 추가하기
logback documentaion Chap6 에서 Creating a custom conversion specifier 키워드로 검색
- ColorConverter라는 class를 clr 가 쓰이면 적용하여서 해당하는 logging event를 문자열로 바꿀 때 ColorConverter의 로직이 적용되도록 함
PatternLayout작성 시, 괄호는 conversion pattern들을 묶기 위해서 사용할 수 있음. 만약 괄호를 literal로 쓰려면 escaping처리를 해줘야함
- conversionWorld 다음 { } 를 이용하여 해당 ConversionWord에 파라미터를 넘길 수 있음
- 예 :
%clr(…){cyan}
File로 logging 남길 때
- prudent mode 라는 것이 있어서, 다른 jvm에서 똑같은 파일에 쓸때에도 충돌나지 않게 하는 옵션이 있음
- append 옵션
- timestamp 변수 설정
- RollingFileAppender
- <file>과 <fileNamePattern>이 같이 있으면, 오늘의 로그(예로 7.1)는 access.log에 기록이 되고 다음날(7.2)이 되면 어제 로그파일(access-2021-07-01.log)이 어제 날짜로 바뀌게 되고 오늘 파일은 access.log가 됨 ⇒ 항상 access.log는 오늘의 로그
- <file>이 없고 <fileNamePattern>만 있으면, 그냥 날짜별로 access-yyyy-MM-dd.log 형태로 만들어짐
에러 로그만 따로 관리하기 (LevelFilter)
실습 config 파일
하이버네이트 SQL 로그
Timezone 설정
- logback은 기본적으로 jvm 레벨의 시간 설정을 가져오게 됨
- jvm 에서 timezone 설정 방법 —
java -Duser.timezone=Asia/Seoul Test
Log level 테이블

- log level을 application.yaml 에서 관리할 수도 있고 logback에서 관리할수도 있음
- 근데 이 둘다 설정 있으면 application.yaml의 설정을 더 우선시함
- 만약
application.yaml에서com.uplus.virtualoffice의 LEVEL을INFO로 설정하고logback-spring.xml의com.uplus.virtualofficeLEVEL을DEBUG로 설정해두고appender-ref를 달아두면,application.yaml의 LEVEL이 적용되어INFO이상의 로그에 대해서만 appender가 적용됨
Charset
- docker container 내부에서 spring application 을 실행시켰을 때, 한글 로그가 아래와 같이 깨지는 현상이 발생했음
com.uplus.virtualoffice.common.exception.admin.AccountLoginException: ??? ?? ????? ???????]ErrorResponse{code=1005, message='??? ?? ????? ???????'}
- 이 때, encoder 설정 안에 charset설정을 해주면 한글이 안 깨지고 잘 나오게 됨
Spring Logback Extension
Mapped Diagnostic Context (MDC)
특정 실행 스레드와 관련된 진단 정보를 저장하고 이를 로그 메시지와 함께 출력할 수 있도록 도와줍니다.
MDC의 주요 개념
- 맵(Map) 형태의 데이터 저장소:
- MDC는 키-값 쌍의 형태로 데이터를 저장합니다.
- 이 데이터는 특정 스레드에 국한되며, 해당 스레드의 작업이 완료되면 제거됩니다.
- 스레드 로컬(Thread-Local) 저장소:
- MDC는 스레드 로컬(ThreadLocal) 저장소를 사용하여 데이터를 저장합니다.
- 같은 애플리케이션 내에서 동시 실행 중인 여러 스레드 간에 데이터 충돌 없이 별도로 저장할 수 있습니다.
왜 MDC를 사용하는가?
MDC는 애플리케이션의 컨텍스트 정보를 로그 메시지에 추가하는 데 유용합니다. 예를 들어, 다음과 같은 경우에 활용할 수 있습니다: