103 lines
2.6 KiB
Markdown
103 lines
2.6 KiB
Markdown
# Log Message Format 예시
|
|
|
|
## 좋은 예시
|
|
|
|
### 예시 1. 사건 설명 + key-value 필드를 함께 남긴다
|
|
|
|
```java
|
|
log.info("Created user. actorId={} userId={} requestPath={}",
|
|
actorId, userId, requestPath);
|
|
```
|
|
|
|
**좋은 이유:**
|
|
|
|
- 사건이 짧게 드러난다
|
|
- 검색 가능한 핵심 키가 있다
|
|
- free text만으로 끝나지 않는다
|
|
|
|
### 예시 2. 실패 메시지에 운영 키를 먼저 담고 예외를 붙인다
|
|
|
|
```java
|
|
log.error("Failed external auth request. provider={} actorId={} durationMs={}",
|
|
provider, actorId, durationMs, ex);
|
|
```
|
|
|
|
**좋은 이유:**
|
|
|
|
- 메시지 자체만 봐도 무엇이 실패했는지 알 수 있다
|
|
- stack trace는 추가 정보로 붙는다
|
|
- 운영 키가 빠지지 않는다
|
|
|
|
### 예시 3. 재시도/대체 경로도 명시적 사건으로 남긴다
|
|
|
|
```java
|
|
log.warn("Applied external auth fallback. provider={} actorId={} fallback={} durationMs={}",
|
|
provider, actorId, "cached-public-key", durationMs);
|
|
```
|
|
|
|
**좋은 이유:**
|
|
|
|
- fallback 발생 사실이 바로 드러난다
|
|
- 이후 검색과 집계가 쉽다
|
|
|
|
### 예시 4. structured logging 전환을 고려한 키 이름을 쓴다
|
|
|
|
```java
|
|
log.info("Completed session cleanup. job={} deletedCount={} durationMs={}",
|
|
"expired-session-cleanup", deletedCount, durationMs);
|
|
```
|
|
|
|
**좋은 이유:**
|
|
|
|
- 텍스트 로그에서도 구조가 보인다
|
|
- JSON 로그로 전환해도 의미가 유지된다
|
|
|
|
## 나쁜 예시
|
|
|
|
### 예시 1. 설명만 길고 검색 키가 없다
|
|
|
|
```java
|
|
log.info("The user registration process was completed successfully after all checks had been passed");
|
|
```
|
|
|
|
**나쁜 이유:**
|
|
|
|
- 누가, 어떤 요청에서, 어떤 리소스가 생성됐는지 알 수 없다
|
|
- 검색/집계가 어렵다
|
|
|
|
### 예시 2. 예외 메시지를 그대로 제목으로 쓴다
|
|
|
|
```java
|
|
log.error(ex.getMessage(), ex);
|
|
```
|
|
|
|
**나쁜 이유:**
|
|
|
|
- 사건 맥락이 없다
|
|
- 운영 키가 없다
|
|
- 예외 메시지 품질에 로그 제목이 종속된다
|
|
|
|
### 예시 3. 민감정보를 그대로 남긴다
|
|
|
|
```java
|
|
log.debug("Login request. email={} password={} accessToken={}",
|
|
request.email(), request.password(), accessToken);
|
|
```
|
|
|
|
**나쁜 이유:**
|
|
|
|
- 민감정보가 원문으로 노출된다
|
|
- 디버그 로그라도 허용되지 않는다
|
|
|
|
### 예시 4. 같은 의미를 제각각 다른 키 이름으로 쓴다
|
|
|
|
```java
|
|
log.info("Created user. uid={} path={} timeMs={}", userId, requestPath, durationMs);
|
|
log.info("Deleted user. userId={} requestUri={} duration={}", userId, requestPath, durationMs);
|
|
```
|
|
|
|
**나쁜 이유:**
|
|
|
|
- 같은 의미의 키 이름이 섞인다
|
|
- 검색/집계/알람 규칙이 복잡해진다
|