6.1 애플리케이션 시작 시

┌─────────────────────────────────────────┐
│  Spring Boot 애플리케이션 시작              │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  spring.factories 스캔                   │
│  → LoggerAutoConfiguration 발견          │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  Bean 생성                               │
│  ├─ ObjectMapper                        │
│  ├─ AsyncExecutor                       │
│  ├─ TraceIdFilter (Filter 등록)          │
│  ├─ MethodLoggingAspect (AOP 등록)       │
│  ├─ DatabaseDetector                    │
│  ├─ DependencyLogSender                 │
│  └─ DependencyCollector                 │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  모든 Bean 생성 완료                       │
│  의존성 주입 완료                           │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  ApplicationReadyEvent 발생              │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  DependencyCollector.collectDependencies()│
│                                         │
│  1. Controller 수집                      │
│     ├─ @RestController Bean 찾기         │
│     └─ 생성자 분석 → 의존성 추출              │
│                                         │
│  2. Service 수집                         │
│     ├─ @Service Bean 찾기                │
│     └─ 생성자 분석 → 의존성 추출              │
│                                         │
│  3. Repository 수집                      │
│     ├─ Interface-based (JPA)            │
│     │   └─ Spring Data Repository 찾기   │
│     └─ Class-based (@Repository)        │
│         └─ 생성자 분석 → 의존성 추출          │
│                                         │
│  4. Database 감지                        │
│     ├─ spring.datasource.url 파싱        │
│     ├─ NoSQL 설정 확인                    │
│     └─ DB 타입 리스트 생성                  │
│                                         │
│  5. 데이터 전송                            │
│     ├─ [1단계] 컴포넌트 전송                │
│     └─ [2단계] 의존성 관계 전송              │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  애플리케이션 준비 완료                       │
│  요청 처리 가능                            │
└─────────────────────────────────────────┘

6.2 런타임: HTTP 요청 처리

┌─────────────────────────────────────────┐
│  HTTP 요청 도착                           │
│  GET /api/users/123                     │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  TraceIdFilter.doFilter()               │
│                                         │
│  1. 헤더에서 X-Trace-Id 확인               │
│     └─ 없으면 UUID 생성                    │
│                                         │
│  2. Client IP 추출                       │
│     ├─ X-Forwarded-For 우선              │
│     └─ 없으면 RemoteAddr 사용              │
│                                         │
│  3. MDC에 저장                            │
│     ├─ MDC.put("traceId", ...)          │
│     └─ MDC.put("client_ip", ...)        │
│                                         │
│  4. 응답 헤더 추가                         │
│     └─ X-Trace-Id: a1b2c3d4-...         │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  DispatcherServlet                      │
│  → UserController.getUser(123) 호출      │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  MethodLoggingAspect (Before)           │
│                                         │
│  1. 메서드 정보 수집                        │
│     ├─ Class: UserController            │
│     ├─ Method: getUser                  │
│     ├─ Layer: CONTROLLER                │
│     └─ Parameters: {userId: 123}        │
│                                         │
│  2. HTTP 정보 추출                        │
│     ├─ Method: GET                      │
│     ├─ URI: /api/users/123              │
│     └─ QueryString: null                │
│                                         │
│  3. Request 로그 출력                     │
│     {                                   │
│       "trace_id": "a1b2c3d4-...",       │
│       "component_name": "UserController",│
│       "layer": "CONTROLLER",            │
│       "message": "Request received: getUser",│
│       "request": {                      │
│         "http": {...},                  │
│         "parameters": {userId: 123}     │
│       }                                 │
│     }                                   │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  UserController.getUser(123) 실행        │
│  → UserService.findById(123) 호출        │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  MethodLoggingAspect (Before)           │
│                                         │
│  1. 메서드 정보 수집                        │
│     ├─ Class: UserService               │
│     ├─ Method: findById                 │
│     ├─ Layer: SERVICE                   │
│     └─ Parameters: {userId: 123}        │
│                                         │
│  2. HTTP 정보 추출                        │
│     └─ null (Service 계층)               │
│                                         │
│  3. Request 로그 출력                     │
│     {                                   │
│       "trace_id": "a1b2c3d4-...",       │
│       "component_name": "UserService",  │
│       "layer": "SERVICE",               │
│       "message": "Request received: findById",│
│       "request": {                      │
│         "parameters": {userId: 123}     │
│       }                                 │
│     }                                   │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  UserService.findById(123) 실행          │
│  → UserRepository.findById(123) 호출     │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  MethodLoggingAspect (Before)           │
│                                         │
│  1. 메서드 정보 수집                        │
│     ├─ Class: UserRepository (프록시)     │
│     ├─ 실제 인터페이스: UserRepository      │
│     ├─ Method: findById                 │
│     ├─ Layer: REPOSITORY                │
│     └─ Parameters: {id: 123}            │
│                                         │
│  2. HTTP 정보 추출                        │
│     └─ null (Repository 계층)            │
│                                         │
│  3. Request 로그 출력                     │
│     {                                   │
│       "trace_id": "a1b2c3d4-...",       │
│       "component_name": "UserRepository",│
│       "layer": "REPOSITORY",            │
│       "message": "Request received: findById",│
│       "request": {                      │
│         "parameters": {id: 123}         │
│       }                                 │
│     }                                   │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  UserRepository.findById(123) 실행       │
│  → DB 쿼리 실행                           │
│  → User 엔티티 반환                        │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  MethodLoggingAspect (After)            │
│  [UserRepository]                       │
│                                         │
│  실행 시간: 15ms                          │
│                                         │
│  Response 로그 출력                       │
│     {                                   │
│       "trace_id": "a1b2c3d4-...",       │
│       "component_name": "UserRepository",│
│       "layer": "REPOSITORY",            │
│       "message": "Response completed: findById",│
│       "execution_time_ms": 15,          │
│       "response": {                     │
│         "result": {                     │
│           "id": 123,                    │
│           "name": "John"                │
│         }                               │
│       }                                 │
│     }                                   │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  MethodLoggingAspect (After)            │
│  [UserService]                          │
│                                         │
│  실행 시간: 25ms                          │
│                                         │
│  Response 로그 출력                       │
│     {                                   │
│       "trace_id": "a1b2c3d4-...",       │
│       "component_name": "UserService",  │
│       "layer": "SERVICE",               │
│       "message": "Response completed: findById",│
│       "execution_time_ms": 25,          │
│       "response": {                     │
│         "result": {                     │
│           "id": 123,                    │
│           "name": "John",               │
│           "email": "john@example.com"   │
│         }                               │
│       }                                 │
│     }                                   │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  MethodLoggingAspect (After)            │
│  [UserController]                       │
│                                         │
│  실행 시간: 50ms                          │
│  HTTP 상태 코드: 200                      │
│                                         │
│  Response 로그 출력                       │
│     {                                   │
│       "trace_id": "a1b2c3d4-...",       │
│       "component_name": "UserController",│
│       "layer": "CONTROLLER",            │
│       "message": "Response completed: getUser",│
│       "execution_time_ms": 50,          │
│       "response": {                     │
│         "http": {                       │
│           "method": "GET",              │
│           "endpoint": "/api/users/123", │
│           "statusCode": 200             │
│         },                              │
│         "result": {                     │
│           "id": 123,                    │
│           "name": "John Doe"            │
│         }                               │
│       }                                 │
│     }                                   │
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  TraceIdFilter (Finally)                │
│                                         │
│  1. MDC.remove("traceId")               │
│  2. MDC.remove("client_ip")             │
│                                         │
│  3. 완료 로그 출력                         │
│     "MDC 정리 완료: [GET] /api/users/123 - Status 200"│
└─────────────┬───────────────────────────┘


┌─────────────────────────────────────────┐
│  HTTP 응답 반환                           │
│                                         │
│  Status: 200 OK                         │
│  Headers:                               │
│    X-Trace-Id: a1b2c3d4-...             │
│  Body:                                  │
│    {"id": 123, "name": "John Doe"}      │
└─────────────────────────────────────────┘

6.3 로그 출력 타임라인

같은 TraceID로 모든 로그가 연결됩니다:

10:30:45.123 [INFO] {"trace_id":"a1b2c3d4-...","component_name":"UserController","layer":"CONTROLLER","message":"Request received: getUser",...}
 
10:30:45.130 [INFO] {"trace_id":"a1b2c3d4-...","component_name":"UserService","layer":"SERVICE","message":"Request received: findById",...}
 
10:30:45.135 [INFO] {"trace_id":"a1b2c3d4-...","component_name":"UserRepository","layer":"REPOSITORY","message":"Request received: findById",...}
 
10:30:45.150 [INFO] {"trace_id":"a1b2c3d4-...","component_name":"UserRepository","layer":"REPOSITORY","message":"Response completed: findById","execution_time_ms":15,...}
 
10:30:45.155 [INFO] {"trace_id":"a1b2c3d4-...","component_name":"UserService","layer":"SERVICE","message":"Response completed: findById","execution_time_ms":25,...}
 
10:30:45.173 [INFO] {"trace_id":"a1b2c3d4-...","component_name":"UserController","layer":"CONTROLLER","message":"Response completed: getUser","execution_time_ms":50,...}