5.1 Spring Boot Auto Configuration

파일: LoggerAutoConfiguration.java

@AutoConfiguration
public class LoggerAutoConfiguration {
	// Bean 정의...
}

5.1.1 Auto Configuration 동작 원리

Step 1: spring.factories 등록 src/main/resources/META-INF/spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
a306.dependency_logger_starter.config.LoggerAutoConfiguration

또는 Spring Boot 2.7+ 방식: src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:

a306.dependency_logger_starter.config.LoggerAutoConfiguration

Step 2: Spring Boot가 자동 로드 Spring Boot 애플리케이션이 시작되면:

  1. Classpath의 모든 spring.factories 또는 .imports 파일 스캔
  2. LoggerAutoConfiguration 발견
  3. 자동으로 Bean 생성

5.2 주요 Bean 등록

5.2.1 ObjectMapper

@Bean
@ConditionalOnMissingBean
public ObjectMapper objectMapper() {
	ObjectMapper mapper = new ObjectMapper();
	mapper.registerModule(new JavaTimeModule());
	return mapper;
}
  • @ConditionalOnMissingBean: 사용자가 정의한 ObjectMapper가 없을 때만 생성
  • JavaTimeModule: Java 8 날짜/시간 타입 지원

5.2.2 AsyncExecutor

@Bean
@ConditionalOnMissingBean
public AsyncExecutor asyncExecutor() {
	ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
	executor.setCorePoolSize(10);
	executor.setMaxPoolSize(20);
	executor.setQueueCapacity(100);
	executor.setTaskDecorator(new MDCTaskDecorator());
	executor.setThreadNamePrefix("async-");
	executor.initialize();
	
	return new AsyncExecutor(executor);
}

설정 값:

  • Core Pool Size: 10개의 기본 스레드
  • Max Pool Size: 최대 20개까지 확장
  • Queue Capacity: 100개의 작업 대기 가능
  • Task Decorator: MDC 자동 전달

5.2.3 TraceIdFilter

@Bean
@ConditionalOnProperty(
	prefix = "dependency.logger.trace",
	name = "enabled",
	havingValue = "true",
	matchIfMissing = true
)
 
public FilterRegistrationBean<TraceIdFilter> traceIdFilter() {
	FilterRegistrationBean<TraceIdFilter> registration = new FilterRegistrationBean<>();
	registration.setFilter(new TraceIdFilter());
	registration.addUrlPatterns("/*");
	registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
	registration.setName("traceIdFilter");
 
	return registration;
}

설정:

  • matchIfMissing = true: 설정이 없으면 기본 활성화
  • addUrlPatterns("/*"): 모든 URL에 적용
  • setOrder(HIGHEST_PRECEDENCE): 가장 먼저 실행

비활성화 방법 (application.yml):

dependency:
  logger:
    trace:
      enabled: false

5.2.4 DependencyLogSender

@Bean
public DependencyLogSender dependencyLogSender( @Value("${dependency.logger.collector.url:http://localhost:8081}") String collectorUrl, @Value("${dependency.logger.api-key}") String apiKey, @Value("${dependency.logger.sender.enabled:true}") boolean enabled) {
	return new DependencyLogSender(collectorUrl, apiKey, enabled);
}

필수 설정 (application.yml):

dependency:
  logger:
    api-key: "your-api-key" # 필수!
  collector:
    url: "http://collector-server:8081" # 선택 (기본값: localhost:8081)
  sender:
    enabled: true # 선택 (기본값: true)

5.2.5 DatabaseDetector

@Bean
@ConditionalOnMissingBean
public DatabaseDetector databaseDetector(Environment environment) {
	return new DatabaseDetector(environment);
}
  • Environment: Spring의 설정 정보 접근

5.2.6 DependencyCollector

@Bean
public DependencyCollector dependencyCollector(ApplicationContext applicationContext, ObjectMapper objectMapper, DependencyLogSender sender, DatabaseDetector databaseDetector) {
	return new DependencyCollector(applicationContext, objectMapper, sender, databaseDetector);
}

의존성 주입:

  • ApplicationContext: 모든 Bean 조회
  • ObjectMapper: JSON 변환
  • DependencyLogSender: 서버 전송
  • DatabaseDetector: DB 감지

5.2.7 MethodLoggingAspect

@Bean
@ConditionalOnProperty(
	prefix = "dependency.logger.method-execution",
	name = "enabled",
	havingValue = "true",
	matchIfMissing = true
)
public MethodLoggingAspect methodLoggingAspect(ObjectMapper objectMapper) {
	return new MethodLoggingAspect(objectMapper);
}

비활성화 방법:

dependency:
  logger:
    method-execution:
      enabled: false

5.2.8 ExceptionHandlerLoggingAspect

@Bean
@ConditionalOnProperty(
	prefix = "dependency.logger.exception-handler",
	name = "enabled",
	havingValue = "true",
	matchIfMissing = true
)
public ExceptionHandlerLoggingAspect exceptionHandlerLoggingAspect( ObjectMapper objectMapper) {
	return new ExceptionHandlerLoggingAspect(objectMapper);
}

@ExceptionHandler 메서드를 자동으로 로깅합니다.

5.2.9 FrontendLogFilter

@Bean
@ConditionalOnProperty(
	prefix = "dependency.logger.frontend",
	name = "enabled",
	havingValue = "true",
	matchIfMissing = false // 기본 비활성화
)
public FilterRegistrationBean<FrontendLogFilter> frontendLogFilter(
	@Value("${dependency.logger.frontend.log-path:./logs/fe/app.log}")
	String frontendLogPath) {
 
	FilterRegistrationBean<FrontendLogFilter> registration = new FilterRegistrationBean<>();
 
	registration.setFilter(new FrontendLogFilter(frontendLogPath));
	registration.addUrlPatterns("/api/logs/frontend");
	registration.setOrder(Ordered.LOWEST_PRECEDENCE);
	registration.setName("frontendLogFilter");
 
	return registration;
}

활성화 방법:

dependency:
  logger:
    frontend:
      enabled: true
    log-path: "./logs/frontend/app.log"

프론트엔드가 POST /api/logs/frontend로 로그를 전송하면 파일에 저장합니다.


5.3 전체 설정 예시

application.yml:

spring:
  application:
    name: my-service
 
  dependency:
    logger:
      # 필수 설정
      api-key: "your-api-key-here"
 
      # Collector 서버
      collector:
        url: "http://collector-server:8081"
 
      # TraceID 추적
      trace:
        enabled: true
 
      # 메서드 로깅
      method-execution:
        enabled: true
 
      # Exception Handler 로깅
      exception-handler:
        enabled: true
 
      # 스택트레이스 제어
      stacktrace:
        max-lines: 10 # 운영: 10줄만, 개발: -1 (전체)
  
      # 프론트엔드 로그 수집 (선택)
      frontend:
        enabled: false
        log-path: "./logs/fe/app.log"
 
      # 전송 활성화
      sender:
        enabled: true

5.4 조건부 Bean 등록 어노테이션

어노테이션의미
@ConditionalOnProperty특정 설정이 있을 때만 생성
@ConditionalOnMissingBean해당 타입의 Bean이 없을 때만 생성
@ConditionalOnClass특정 클래스가 Classpath에 있을 때만 생성

예시:

@Bean
@ConditionalOnProperty(
  prefix = "feature",
  name = "enabled",
  havingValue = "true",
  matchIfMissing = false
)
public MyFeature myFeature() {
  return new MyFeature();
}

feature.enabled=true일 때만 Bean 생성.