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.LoggerAutoConfigurationStep 2: Spring Boot가 자동 로드 Spring Boot 애플리케이션이 시작되면:
- Classpath의 모든
spring.factories또는.imports파일 스캔 LoggerAutoConfiguration발견- 자동으로 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: false5.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: false5.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: true5.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 생성.