Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/user-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ dependencies {
implementation 'org.apache.logging.log4j:log4j-slf4j2-impl:2.22.1'
implementation 'org.apache.logging.log4j:log4j-jul:2.22.1'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml'
implementation 'org.apache.logging.log4j:log4j-layout-template-json:2.22.1'

implementation 'org.apache.httpcomponents:httpclient:4.5.14'
implementation 'org.apache.httpcomponents:httpcore:4.4.16'
implementation 'pl.tkowalcz.tjahzi:log4j2-appender-nodep:0.9.17'

// 비동기 로깅
implementation 'com.lmax:disruptor:3.4.4'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ protected void doFilterInternal(
traceId = UUID.randomUUID().toString();
}

MDC.put("traceId", traceId.substring(0, 8));
// MDC.put("traceId", traceId.substring(0, 8));
MDC.put("traceId", traceId);

// ⭐️ 요청 객체에 attribute로 traceId를 저장하여 컨트롤러 등에서 사용할 수 있게 함
request.setAttribute("X-Request-ID", traceId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ mybatis:
map-underscore-to-camel-case: true

logging:
config: classpath:log4j2-develop.yml
config: classpath:log4j2-test-unit.yml
133 changes: 25 additions & 108 deletions apps/user-service/src/main/resources/log4j2-develop.yml
Original file line number Diff line number Diff line change
@@ -1,133 +1,50 @@
Configuration:
status: DEBUG
name: develop

properties:
property:
- name: "log-path"
value: "./logs"
- name: "charset-UTF-8"
value: "UTF-8"
# 통일된 콘솔 패턴 - 모든 로그에 RequestId 포함
- name: "console-layout-pattern"
value: "%highlight{[%-5level]} [%X{traceId}] %d{MM-dd HH:mm:ss} [%t] %n %msg%n%n"
# 파일용 상세 패턴 - RequestId 포함
- name: "file-layout-pattern"
value: "[%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
# 로그 파일 경로들
- name: "info-log"
value: ${log-path}/user-service/info.log
- name: "error-log"
value: ${log-path}/user-service/error.log
- name: "auth-log"
value: ${log-path}/user-service/auth.log
- name: "json-log"
value: ${log-path}/user-service/json-info.log
- name: "app-name"
value: "${env:APP_NAME:-user-service-app}"

# [Appenders] 로그 기록방식 정의
Appenders:
# 통일된 콘솔 출력
# 콘솔 appender
Console:
name: console-appender
target: SYSTEM_OUT
PatternLayout:
pattern: ${console-layout-pattern}
pattern: "[%-5level] [%X{traceId}] %d{MM-dd HH:mm:ss} [%t] %msg%n"

# 롤링 파일 로그
RollingFile:
name: rolling-file-appender
fileName: ${log-path}/rolling-file.log
filePattern: "logs/archive/rolling-file.log.%d{yyyy-MM-dd-hh-mm}_%i.gz"
# Tjahzi Loki Appender (올바른 문법)
Loki:
name: loki-appender
host: localhost
port: 3100
PatternLayout:
charset: ${charset-UTF-8}
pattern: ${file-layout-pattern}
Policies:
SizeBasedTriggeringPolicy:
size: "200KB"
TimeBasedTriggeringPolicy:
interval: "1"
DefaultRollOverStrategy:
max: "30"
fileIndex: "max"
pattern: "[%-5level] [%X{traceId}] %d{MM-dd HH:mm:ss} [%t] %msg%n"
Label:
- name: "app"
value: "${app-name}" # 고정 값
- name: "service"
value: "user-service" # 고정 값
- name: "traceId"
value: "${ctx:traceId}" # MDC에서 가져올 값만 넣음

# 파일 로그들
File:
- name: file-info-appender
fileName: ${info-log}
PatternLayout:
pattern: ${file-layout-pattern}
- name: file-error-appender
fileName: ${error-log}
PatternLayout:
pattern: ${file-layout-pattern}
- name: file-auth-appender
fileName: ${auth-log}
PatternLayout:
pattern: ${file-layout-pattern}
- name: file-json-info-appender
fileName: ${json-log}
PatternLayout:
pattern: ${file-layout-pattern}

# [Loggers] 로그 출력 범위를 정의
Loggers:
# [Loggers - Root] 모든 로그를 기록하는 최상위 로그를 정의
Root:
level: OFF
level: INFO
AppenderRef:
- ref: console-appender
- ref: rolling-file-appender

# [Loggers - Loggers] 특정 패키지나 클래스에 대한 로그를 정의
Logger:
# 1. Spring Framework 로그
- name: org.springframework
additivity: "false"
level: DEBUG
AppenderRef:
- ref: console-appender
- ref: file-info-appender
- ref: file-error-appender

# 2. 애플리케이션 로그
# 애플리케이션 로그만 Loki로 전송 (additivity 문법 수정)
- name: site.icebang
additivity: "false"
level: TRACE
additivity: false
level: INFO
AppenderRef:
- ref: console-appender
- ref: file-info-appender
- ref: file-error-appender
- ref: loki-appender

# 3. HikariCP 로그 비활성화
# HikariCP 로그 비활성화
- name: com.zaxxer.hikari
level: OFF

# 4. Spring Security 로그 - 인증/인가 추적에 중요
- name: org.springframework.security
level: DEBUG
additivity: "false"
AppenderRef:
- ref: console-appender
- ref: file-auth-appender

# 5. 웹 요청 로그 - 요청 처리 과정 추적
- name: org.springframework.web
level: DEBUG
additivity: "false"
AppenderRef:
- ref: console-appender
- ref: file-info-appender

# 6. 트랜잭션 로그 - DB 작업 추적
- name: org.springframework.transaction
level: DEBUG
additivity: "false"
AppenderRef:
- ref: console-appender
- ref: file-info-appender

- name: site.icebang.domain.auth.mapper
level: DEBUG
additivity: "false"
AppenderRef:
- ref: console-appender
- ref: file-info-appender
level: OFF
59 changes: 25 additions & 34 deletions apps/user-service/src/main/resources/sql/01-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -308,37 +308,28 @@ ALTER TABLE `department`

-- v0.4
-- 기존 execution_log 테이블 수정
ALTER TABLE `execution_log`
-- 새로운 컬럼 추가
ADD COLUMN `run_id` bigint unsigned NULL COMMENT 'workflow_run_id, job_run_id, task_run_id' AFTER `source_id`,
ADD COLUMN `status` varchar(20) NULL COMMENT 'success, failed, warning, running' AFTER `log_level`,
ADD COLUMN `duration_ms` int unsigned NULL COMMENT '실행 시간 (밀리초)' AFTER `executed_at`,
ADD COLUMN `error_code` varchar(50) NULL COMMENT '에러 코드' AFTER `duration_ms`,

-- 예비 컬럼 (향후 확장용)
ADD COLUMN `reserved1` varchar(100) NULL COMMENT '예비 컬럼 1',
ADD COLUMN `reserved2` varchar(100) NULL COMMENT '예비 컬럼 2',
ADD COLUMN `reserved3` int NULL COMMENT '예비 컬럼 3',
ADD COLUMN `reserved4` json NULL COMMENT '예비 컬럼 4',
ADD COLUMN `reserved5` timestamp NULL COMMENT '예비 컬럼 5';

-- 기존 컬럼 수정
ALTER TABLE `execution_log`
MODIFY COLUMN `log_message` varchar(500) NOT NULL COMMENT '요약 메시지',
MODIFY COLUMN `executed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '실행 시간';

-- 기존 불필요한 컬럼 제거 (있다면)
ALTER TABLE `execution_log`
DROP COLUMN IF EXISTS `config_snapshot`;

-- 새로운 인덱스 추가
ALTER TABLE `execution_log`
ADD INDEX `idx_run_id` (`run_id`),
ADD INDEX `idx_log_level_status` (`log_level`, `status`),
ADD INDEX `idx_error_code` (`error_code`),
ADD INDEX `idx_duration` (`duration_ms`);

-- 기존 인덱스 수정 (복합 인덱스 최적화)
ALTER TABLE `execution_log`
DROP INDEX IF EXISTS `idx_source_id_type`,
ADD INDEX `idx_execution_type_source` (`execution_type`, `source_id`);
-- 컬럼 추가 (한 번에 하나씩)
-- 컬럼 추가
ALTER TABLE execution_log ADD COLUMN run_id BIGINT NULL;
ALTER TABLE execution_log ADD COLUMN status VARCHAR(20) NULL;
ALTER TABLE execution_log ADD COLUMN duration_ms INT NULL;
ALTER TABLE execution_log ADD COLUMN error_code VARCHAR(50) NULL;
ALTER TABLE execution_log ADD COLUMN reserved1 VARCHAR(100) NULL;
ALTER TABLE execution_log ADD COLUMN reserved2 VARCHAR(100) NULL;
ALTER TABLE execution_log ADD COLUMN reserved3 INT NULL;
ALTER TABLE execution_log ADD COLUMN reserved4 json NULL;
ALTER TABLE execution_log ADD COLUMN reserved5 TIMESTAMP NULL;

-- 컬럼 수정
ALTER TABLE execution_log MODIFY COLUMN log_message VARCHAR(500) NOT NULL;
ALTER TABLE execution_log MODIFY COLUMN executed_at TIMESTAMP NOT NULL;

-- 컬럼 삭제
ALTER TABLE execution_log DROP COLUMN config_snapshot;

-- 인덱스 생성 (CREATE INDEX 별도)
CREATE INDEX idx_run_id ON execution_log(run_id);
CREATE INDEX idx_log_level_status ON execution_log(log_level, status);
CREATE INDEX idx_error_code ON execution_log(error_code);
CREATE INDEX idx_duration ON execution_log(duration_ms);
CREATE INDEX idx_execution_type_source ON execution_log(execution_type, source_id);
37 changes: 36 additions & 1 deletion docker/local/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,40 @@ services:
depends_on:
- mariadb

loki:
image: grafana/loki:2.9.0
container_name: loki
restart: unless-stopped
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
volumes:
- loki_data:/loki
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1"]
interval: 10s
timeout: 5s
retries: 5

grafana:
image: grafana/grafana:10.1.0
container_name: grafana
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
ports:
- "3030:3000"
volumes:
- grafana_data:/var/lib/grafana
depends_on:
- loki
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"]
interval: 30s
timeout: 10s
retries: 5

volumes:
mariadb_data:
mariadb_data:
loki_data:
grafana_data:
Loading