[Java] SLF4J Logging

한호성·2024년 4월 6일
0

Index

  • SLF4J 키워드 및 개념
  • SLF4J 동작원리 및 특징
  • log4j2 & 사용한 방식

SLF4J 키워드 및 개념


키워드

Log

  • 로그란 어플리케이션에서 발생하는 이벤트를 기록하고 추적할 수 있는 도구를 의미합니다.
    • 프로그램 동작시 발생하는 모든 일을 기록하는 행위입니다.
  • 로그관리가 제대로 되어야, 문제가 생겼을 때 해결할 수 있습니다.
  • 로그 관리란? 어떤 것을 의미할까요?
    • 로그의 생성 집계 저장 분석 보관 및 폐기까지 이르는 모든 과정을 의미합니다.
    • 로그 관리를 위해서는, 어플리케이션, 네트워크.. 기타 모든 요소 에서의 모든 것을 기록해야 합니다.

Facade

  • SLF4J 라이브러리의 전체적인 구조를 나타내는 단어이다.
  • Facade(파사드) 구조는 여러 개의 작업들을 중앙에서 통제해서 관리하는 구조를 의미합니다.
    공통된 Interface(중앙 통제)를 사용해서, Interface 구현한 바인딩된 프레임워크를 호출하는 방식을 사용합니다.
    아래의 동작원리를 보면서 이해해보도록 합시다.

SLF4J란 무엇일까요?

  • 이름에서도 알 수 있듯이 자바를 위한 로깅 라이브러리이며, 구조는 파사드패턴을 기반으로 되어있습니다.
  • SLF4J는 그 자체로 작동하는 것이 아닌, 추상화된 라이브러리입니다. 사용하기 위해서는 구체화된 구현체들이 필요합니다.
    • 구현체들의 예시로는 log4j, logback, log4j2 가 존재합니다.
    • 인터페이스만 제공하고 ,각 구현체 들을 원하는대로 사용하면 되기 때문에, 개체지향의 장점을 잘 살려서 사용 가능합니다. (Solid 중 OCP, DIP 잘 적용한 예)

SLF4J 동작원리 및 특징


SLF4J는 3가지 모듈을 제공합니다. ( API, Binding, Bridging)

각 모듈은 다음과 같은 기능을 합니다.

1) SLF4J API

  • 추상화 되어서 호출될 API들이 모여있는 곳
  • 그림참조 (상위의 SLF4J) 추상화 API가 존재하는것을 확인할 수 있다.

2) SLF4jJ Binding

  • SLF4J 인터페이스를 로깅 구현체와 연결하는 어댑터 역할을 하는 모듈
  • 사용하길 원하는 구현체와 바인딩을 추가해야 합니다. (1개만) (그림참조)

3) SLF4J Bridging

  • 다른 로깅 API로의 호출을 SLF4J로 redircet 하여, SLF4J API가 대신 처리할 수 있도록 하는 일종의 어댑터 역할을 하는 모듈
  • 예를들어 JCL API, JUL API 호출을 대신 SLF4J에 대한 것처럼 리다이랙션을 하게 합니다. (그림참조)

SLF4J의 특징

  • 배포시 LoggingFramework 선택 가능
    • compile time에 오직 하나의 Logging Framework 사용하도록 바인딩
  • 빠른 속도로 동작
    • 클래스가 JVM에 의해 로드되는 방식으로 인해 프레임워크 바인딩은 초기에 확인
  • Bridging legacy logging API
    • log4J APi, JCL, 기타 .. 오래된 라이브러리를 Bridging 하여 SLF4J를 사용하도록 함

#cf) 로깅시, Systme.out.println() 을 사용 해도 될까?? 에 대한 설명입니다.

println() 메소드를 타고 들어가서 내부가 어떻게 도는지 확인해보겠습니다.

    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }

synchronized 키워드를 사용하기 때문에, 멀티쓰레딩 환경에서 여러곳에서 System.out.println()을 사용할 경우 성능저하의 큰 문제가 될 수 있습니다.

log4j2 & 사용한 방식


log4j2 사용

저는 가장 최신 버전인 log4J2를 활용하여 어플리케이션에 필요한 로깅방식을 취하기로 하였습니다.

그 이유로는 다음과 같습니다. ( springBoot 내장된 것은 logback이여 조금 번거롭지만, 사용해보았습니다.)

  • log4j의 업그레이드 버전
  • 다른 벤치마크 결과상, 처리율이 가장 높았음

사용방식

우선 배포버전, 개발버전을 나누어서 로깅방식을 채택하였습니다.

개발 시에는, 로그파일을 따로 관리할 필요가 없었기에 프로젝트 빌드 시, 환경변수를 주어서, log4j2 프레임워크를 바인딩 될 수 있도록 하였습니다.

ex) 예시

	//log4j2
	ext.profile = (!project.hasProperty('profile') || !profile) ? 'local' : profile
	if (ext.profile == 'prod' || ext.profile=='packaging') {
		implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.17.1'
		implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.17.1'
		implementation group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.17.1'
		implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.17.1'
		implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.32'
		implementation group: 'org.slf4j', name: 'jul-to-slf4j', version: '1.7.32'

		implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
	}

배포 시

  • log4j2를 활용하여서 로그를 남기도록 하였습니다.
  • 로그파일을 3종류로 나누어서 저장시키도록 하였습니다.
    • 로그파일 ,에러로그 파일, 디버그 파일
    • 일자별로 관리
    • 일정 크기 이상으로 커지게 될 경우 새파일 생성하도록 하였습니다.
  • log4jdbc 라이브러리를 활용하여서, sql 로그도 남기도록 하였습니다.

#cf) 최근 보안이슈가 있었기 때문에 버전을 잘 확인하셔야 합니다.

문제가 되었던 부분

이슈의 이름: CVE-2021-44228

이슈 내용:

log4j2를 이용하여, 원격 코드 실행 가능한 JNDI 인젝션 취약점으로, 사용자의 입력으로 발생한 로그를 기록할 때 해커의 임의코드 실행이 가능하게 된다는 점입니다.

즉 해커가 악용한다면 서버에 접근하는 것 만으로 사용자의 컴퓨터를 사실상 원격 조정할 수 있다고 한다.

2.15 이전의 버전들은 사용하면 안된다고 합니다!! (아래글을 참조하세요)

Log4J2 Vulnerability and Spring Boot

Reference

https://livenow14.tistory.com/63
https://gmlwjd9405.github.io/2019/01/04/logging-with-slf4j.html
https://www.slideshare.net/whiteship/ss-47273947

profile
개발자 지망생입니다.

0개의 댓글