"시스템의 고독한 독백, 개발자에겐 완벽한 단서가 되다."
Find a file
2026-06-25 07:28:18 +09:00
.vscode feat: Implement Monolog logging framework with multiple loggers 2026-06-13 23:18:25 +09:00
gradle fix: Update SLF4J version to 2.0.18 in libraries and MonologServiceProvider 2026-06-14 00:57:53 +09:00
monologo tragets jdk 17 2026-06-25 07:28:18 +09:00
.gitattributes feat: Implement Monolog logging framework with multiple loggers 2026-06-13 23:18:25 +09:00
.gitignore Refactor logging framework with enhanced failover management and retry logic 2026-06-19 00:24:15 +09:00
AGENTS.md feat: Implement Monolog logging framework with multiple loggers 2026-06-13 23:18:25 +09:00
gradle.properties feat: Implement Monolog logging framework with multiple loggers 2026-06-13 23:18:25 +09:00
gradlew feat: Implement Monolog logging framework with multiple loggers 2026-06-13 23:18:25 +09:00
gradlew.bat feat: Implement Monolog logging framework with multiple loggers 2026-06-13 23:18:25 +09:00
LICENSE feat: Implement Monolog logging framework with multiple loggers 2026-06-13 23:18:25 +09:00
monolog.conf.toml Refactor logging framework with enhanced failover management and retry logic 2026-06-19 00:24:15 +09:00
monolog.png Refactoring 2026-06-24 02:33:59 +09:00
README.md Refactoring 2026-06-24 02:33:59 +09:00
settings.gradle.kts Refactoring 2026-06-24 02:33:59 +09:00

Project Monolog

"시스템의 고독한 독백, 개발자에겐 완벽한 단서가 되다."

Monolog

Monolog는 SLF4J 2.0 API를 지원하는 자바 기반의 경량 로깅 프레임워크입니다. 최소한의 의존성으로 동작하며, 비동기 처리, 동적 설정 변경, 파일/네트워크 출력, 구조화된 failover 재전송을 제공합니다.


주요 특징

  • SLF4J 2.0 호환: 최신 SLF4J SPI를 구현하여 Fluent API 및 모든 표준 로깅 기능을 지원합니다.
  • 초경량 설계: slf4j-api 외에는 추가적인 외부 라이브러리 의존성이 없습니다.
  • 비동기 로깅 (AsyncLogger): BlockingQueue 기반의 워커 스레드를 통해 메인 로직의 성능 저하 없이 대량의 로그를 처리합니다.
  • 다중 핸들러 지원:
    • Console: ANSI 컬러 지원으로 가독성이 뛰어난 터미널 출력.
    • File: 크기/날짜 기반 롤링 및 자동 보관 기간 관리.
    • TCP/UDP: 고성능 원격 로그 수집 서버 연동 (TCP는 JSON 및 MDC 지원).
    • HTTP: REST API 전송 (JSON 레이아웃 및 MDC 필드 자동 확장 지원).
    • Email: SMTP 기반 장애 즉시 알림.
  • 네트워크 안정성 (Failover): HTTP/TCP 전송 실패 시 구조화된 레코드로 로컬 디스크에 저장하고, 이후 같은 대상에 다시 전송합니다.
  • 동적 설정 (Hot Reload): 애플리케이션 재시작 없이 monolog.conf.toml 파일 수정만으로 로깅 정책이 실시간 반영됩니다.
  • 계층적 설정: 루트 레벨 설정부터 패키지/클래스별 상세 레벨까지 정밀하게 제어할 수 있습니다.
  • 환경 변수 지원: ${ENV_VAR} 형식을 통해 클라우드 환경에서 유연한 설정 주입이 가능합니다.

설치 및 등록

1. 의존성 추가 (Gradle)

repositories {
    maven {
        name = "Elex Repository"
        url = uri("https://artifacts.elex-project.com/repository/maven/")
    }
}
dependencies {
    implementation("org.slf4j:slf4j-api:2.0.18")
    implementation("com.elex-project:monolog:1.0.0")
}

2. 모듈 시스템

Java 모듈 시스템을 사용하는 경우 module-info.java에 다음을 추가합니다:

requires org.slf4j;
requires com.elex_project.monolog;

설정 가이드 (monolog.conf.toml)

Monolog는 Classpath -> User Home -> Working Directory 순서로 설정 파일을 탐색하며, 환경 변수(MONOLOG_ 접두사)를 통한 오버라이드도 지원합니다. 설정 파일이 없으면 기본값으로 시작하며, 이 경우 콘솔 로거만 활성화됩니다.

Sample File

# 기본 설정
rootLevel = "INFO"
loggers = ["CONSOLE", "FILE", "HTTP"] # 활성화할 핸들러 목록
asyncQueueWarningThreshold = 0.8
discardIfFull = false
useAnsiColor = true

# 콘솔 핸들러 설정
[console]
level = "INFO"
layout = "%d{HH:mm:ss.SSS} [%5p] %c - %m"
useAnsiColor = true

# 파일 핸들러 설정
[file]
level = "DEBUG"
path = "logs/app.log"
maxSize = 10485760 # 10MB
maxBackups = 5
dailyRolling = true
maxHistory = 30 # 30일 보관

# HTTP 및 네트워크 장애 대응 설정
[http]
level = "ERROR"
url = "http://log-collector.internal/api/v1/logs"
json = true
userAgent = "Monolog-Agent-v1"
maxRetries = 3
initialRetryDelayMillis = 1000
maxRetryDelayMillis = 30000
app_name = "MyWebApp"
app_version = "1.0.0"
environment = "production"

# TCP 설정
[tcp]
level = "WARN"
host = "127.0.0.1"
port = 4560
json = true
app_name = "MyWebApp"
app_version = "1.0.0"

[failover]
enabled = true
path = "logs/failover-buffer.log"
interval = 60 # 60초마다 재시도
maxSize = 104857600 # 최대 100MB 보관

# 패키지별 상세 레벨 설정
[packageLevels]
"com.myapp.service" = "DEBUG"
"org.hibernate.SQL" = "TRACE"

레이아웃 토큰

토큰 설명
%d{format} 타임스탬프 (예: %d{yyyy-MM-dd HH:mm:ss})
%p 로그 레벨 (ERROR, WARN, INFO 등)
%t 현재 스레드 이름
%c 로거 이름 (클래스 경로)
%m 메시지 본문
%n 줄 바꿈

사용 예시

표준 SLF4J 사용 방식과 동일하므로 학습 비용이 전혀 없습니다.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyService {
    private static final Logger logger = LoggerFactory.getLogger(MyService.class);

    public void doWork(String data) {
        logger.debug("작업 시작: {}", data);
        try {
            // 비즈니스 로직
            logger.info("작업이 성공적으로 완료되었습니다.");
        } catch (Exception e) {
            logger.error("작업 중 오류 발생", e);
        }
    }
}

MDC (Mapped Diagnostic Context) 지원

HTTPLogger에서 JSON 레이아웃을 사용할 때, MDC에 담긴 값들은 자동으로 JSON 필드로 확장됩니다.

MDC.put("server_ip", "192.168.0.10");
MDC.put("user_id", "admin_01");
logger.info("결제 요청 처리"); 
// JSON 출력 예: {"timestamp":"...","level":"INFO","message":"결제 요청 처리","server_ip":"192.168.0.10","user_id":"admin_01"}

Failover 동작

HTTPLoggerTCPLogger는 전송 실패 시 FailoverManager에 구조화된 레코드로 저장합니다. 저장된 항목은 설정된 interval 주기로 다시 시도되며, 성공하면 failover 파일에서 제거됩니다.

  • HTTP 레코드에는 URL, method, user-agent, content-type, payload가 포함됩니다.
  • TCP 레코드에는 host, port, payload가 포함됩니다.
  • 기존 legacy 파일 형식도 일부 호환되도록 유지됩니다.

모니터링 API

관리자 도구나 대시보드 구성을 위해 현재 로거들의 상태를 조회할 수 있는 API를 제공합니다.

MonologLoggerFactory factory = (MonologLoggerFactory) LoggerFactory.getILoggerFactory();
List<LoggerStatus> statuses = factory.getLoggerStatuses();

statuses.forEach(status -> {
    System.out.println("로거: " + status.getName());
    System.out.println("레벨: " + status.getEffectiveLevel());
    if (status.getQueueSize() != null) {
        System.out.println("큐 상태: " + status.getQueueSize() + "/" + status.getQueueCapacity());
    }
});

고급 설정 (비동기 정책)

로그 폭주 상황에서 시스템을 보호하기 위한 정책을 설정할 수 있습니다.

  • Blocking (기본값): 큐가 가득 차면 빈 공간이 생길 때까지 메인 스레드가 대기합니다. (로그 유실 방지)
  • Discard: 큐가 가득 차면 새로운 로그를 버리고 즉시 제어권을 반환합니다. (성능 우선)
discardIfFull = true # Discard 정책 활성화
asyncQueueWarningThreshold = 0.8 # 큐가 80% 차면 경고 로그 발생

라이선스

이 프로젝트는 Apache License 2.0에 따라 라이선스가 부여됩니다.


Copyright (c) 2026 ELEX. All Rights Reserved.