[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -1,133 +1,210 @@
|
||||
---
|
||||
id: wiki-2026-0508-로그-logs
|
||||
title: 로그 Logs
|
||||
title: 로그 (Logs)
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: []
|
||||
aliases: [Logs, Logging, Application Logs]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.92
|
||||
tags: [auto-wikified, technical-documentation]
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [observability, logging, sre, telemetry, structured-logging]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-08
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
tech_stack:
|
||||
language: unspecified
|
||||
framework: unspecified
|
||||
language: TypeScript/Go
|
||||
framework: OpenTelemetry / Loki / Datadog
|
||||
---
|
||||
|
||||
# 로그 (Logs)
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
로그(Logs)는 소프트웨어 시스템의 실행 중 발생하는 이벤트, 스택 트레이스(Stack trace) 및 에러 메시지를 기록한 데이터입니다 [1]. 새로운 코드베이스나 복잡한 시스템을 분석할 때 정적 코드 읽기의 한계를 극복하고 시스템의 동적인 특성과 작동 흐름을 파악하게 해주는 필수적인 탐색 도구이며 [1, 2], 마이크로서비스 아키텍처에서는 시스템 전체의 가시성을 확보하기 위한 중앙 집중식(Centralized) 인프라의 핵심 요소로 작용합니다 [3, 4].
|
||||
## 매 한 줄
|
||||
> **"매 log 는 system 의 외부 관측 가능성(observability)의 세 기둥 중 하나로 매 metric/trace 의 sibling 이며 매 high-cardinality narrative event 의 sink"**. 매 2026 의 표준은 structured JSON + OpenTelemetry semantic conventions + 5-level severity + sampling/aggregation pipeline.
|
||||
|
||||
## 📖 Core 동Content
|
||||
- **동적 분석 및 코드베이스 탐색의 수단:** 정적인 코드 읽기만으로는 파악하기 어려운 시스템의 동적인 특성은 로그, 중단점(Breakpoints), 그리고 런타임 프로파일링을 통해 분석해야 합니다 [2]. 무작위 입력을 서비스에 전달하여 의도적으로 오류를 발생시킨 뒤, 스택 트레이스와 에러 로그를 살펴보면 코드가 입력을 어떻게 파싱하고 실패하는지를 명확히 드러내어 코드 파악에 큰 단서를 제공합니다 [1].
|
||||
- **코드 학습을 위한 능동적 로깅:** 낯선 코드베이스를 이해하기 위해 코드 구조를 단순히 읽는 것에 그치지 않고, 코드 내부에 추가적인 로깅이나 사용자 인터페이스 상의 디버그 출력을 삽입하는 등 작은 수정을 가해보는 과정 자체가 코드를 학습하는 데 매우 유용한 방법이 됩니다 [5].
|
||||
- **아키텍처 수준에서의 중앙 집중식 로깅:** 마이크로서비스 아키텍처(Microservices Architecture)와 같이 분산된 환경에서는 시스템의 가시성을 확보하기 위해 강력한 모니터링과 '중앙 집중식 로깅(Centralized Logging)'이 필수적입니다 [3, 4].
|
||||
- **API 게이트웨이의 로깅 책임:** 아키텍처 설계에서 단일 진입점 역할을 하는 API 게이트웨이(API Gateway)는 클라이언트 요청에 대한 라우팅, 인증, 로드 밸런싱과 더불어 로깅을 처리하는 책임을 지며 시스템 통신을 기록합니다 [6].
|
||||
## 매 핵심
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
- **디버깅 도구로서의 한계:** 런타임 흐름을 파악하기 위해 로그를 사용하는 것은 디버깅의 가장 원시적인(primitive) 방법일 수 있습니다 [7]. 때로는 로그에만 의존하기보다 IDE의 중단점(Breakpoints)을 활용하는 것이 호출 스택(Call stack)이나 변수의 상태 값 등에 대해 훨씬 더 풍부한 정보를 제공할 수 있습니다 [7].
|
||||
- *추가 참고:* 로깅으로 인한 시스템 성능 저하, 디스크 용량 한계 등 시스템 최적화나 아키텍처 도입에 따른 구체적인 부작용에 대해서는 소스에 관련 정보가 부족합니다.
|
||||
### 매 Three pillars of observability
|
||||
- **Metrics**: 매 numeric, low-cardinality, aggregable. (Prometheus, OTLP metrics)
|
||||
- **Logs**: 매 textual, high-cardinality, event-narrative.
|
||||
- **Traces**: 매 request-scoped causal chain across services.
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
### Related Concepts
|
||||
### 매 Log levels (RFC 5424 + practice)
|
||||
- **FATAL/EMERGENCY**: 매 process death imminent.
|
||||
- **ERROR**: 매 user-facing failure or unexpected condition.
|
||||
- **WARN**: 매 degraded state, fallback engaged.
|
||||
- **INFO**: 매 lifecycle events (start, stop, deploy).
|
||||
- **DEBUG**: 매 development troubleshooting.
|
||||
- **TRACE**: 매 fine-grained step-level (rarely on in prod).
|
||||
|
||||
#### [분석 및 디버깅 도구]
|
||||
- [[중단점 (Breakpoints)]]
|
||||
- 연결 이유: 로그와 함께 코드의 동적 흐름을 추적하는 데 사용되는 대표적인 도구이기 때문입니다 [2, 7].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 로그가 제공하는 정보의 한계를 보완하여 런타임 시점의 호출 스택과 변수값을 실시간으로 확인하고 런타임 흐름을 분석하는 방법 [7].
|
||||
- [[스택 트레이스 (Stack Trace)]]
|
||||
- 연결 이유: 에러 로그 발생 시 함께 출력되어 오류가 발생한 코드의 호출 경로를 보여주는 핵심 정보이기 때문입니다 [1].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 실패 지점으로부터 시스템의 내부 논리와 데이터 처리 구조를 역추적(상향식 접근)하는 방법 [1].
|
||||
### 매 Structured logging (2026 default)
|
||||
- **JSON line format**: 매 1 event = 1 line, machine-parseable.
|
||||
- **Required fields**: timestamp (RFC3339), level, service, trace_id, span_id, message.
|
||||
- **OTel semantic conventions**: 매 http.method, db.system, exception.type.
|
||||
- **PII redaction**: 매 in-stream filter for compliance (GDPR/HIPAA/PCI).
|
||||
|
||||
#### [아키텍처 및 기반 기술]
|
||||
- [[마이크로서비스 아키텍처 (Microservices Architecture)]]
|
||||
- 연결 이유: 시스템이 잘게 분리된 아키텍처 특성상 중앙 집중식 로깅이 필수적인 아키텍처 스타일이기 때문입니다 [3, 4].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 단일 모놀리식 구조가 아닌 다수의 서비스가 협력하는 구조에서, 왜 분산된 로그를 한 곳으로 모으는 것이 가시성 확보에 필수적인지에 대한 설계적 맥락 [3].
|
||||
- [[API 게이트웨이 (API Gateway)]]
|
||||
- 연결 이유: 클라이언트 요청을 중앙에서 받아 로깅, 인증, 라우팅을 처리하는 진입점이기 때문입니다 [6].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 외부 통신이 내부 시스템으로 들어올 때 로그가 최초로 생성되고 관리되는 위치와 게이트웨이 계층의 책임 [6].
|
||||
### 매 응용
|
||||
1. 매 SLO debugging: error logs + trace correlation → root cause.
|
||||
2. 매 audit trail: append-only, signed, retention 7y for finance.
|
||||
3. 매 anomaly detection: log pattern clustering (Drain3, LogPAI) → unknown unknowns.
|
||||
|
||||
### Deeper Research Questions
|
||||
- 중앙 집중식 로깅(Centralized Logging)은 마이크로서비스 아키텍처에서 서비스 간 통신의 가시성을 구체적으로 어떻게 향상시키는가?
|
||||
- 낯선 코드베이스를 분석할 때 추가적인 로깅 코드를 삽입하는 능동적 행위는 개발자의 멘탈 모델 형성에 어떤 인지적 도움을 주는가?
|
||||
- 런타임 흐름을 추적할 때, 로그 분석과 중단점(Breakpoints)을 활용한 디버깅은 각각 어떤 상황에서 최적의 효과를 발휘하는가?
|
||||
- API 게이트웨이에서 로깅 처리를 중앙화할 때 얻을 수 있는 아키텍처적 이점과 병목 현상 등 시스템 한계는 무엇인가?
|
||||
- 의도적으로 시스템에 잘못된 입력을 주어 발생하는 에러 메시지와 스택 트레이스 로그를 기반으로 코드베이스를 상향식(Bottom-Up)으로 파악하는 절차는 무엇인가?
|
||||
## 💻 패턴
|
||||
|
||||
### Practical Application Contexts
|
||||
- **Implementation:** 새로운 기능 구현이나 기존 코드를 파악할 때, 코드 내부에 디버그 출력이나 추가적인 로그를 임의로 작성해 코드 실행 결과와 흐름을 직접 테스트합니다 [5].
|
||||
- **System Design:** 분산 시스템이나 마이크로서비스 환경을 설계할 때, 개별 서비스의 로그를 모니터링하기 위해 중앙 집중식 로깅 계층을 구성하고 API 게이트웨이에 로깅 책임을 부여합니다 [3, 4, 6].
|
||||
- **Operation / Maintenance:** 운영 중인 시스템의 에러 로그와 스택 트레이스를 분석하여, 예측하지 못한 입력값에 대한 시스템의 동적인 처리 실패 원인을 진단하고 수정합니다 [1].
|
||||
- **Learning Path:** 복잡한 시스템에 합류한 신규 개발자가 정적 코드 분석의 한계를 느낄 때, 시스템의 동적 특성을 익히기 위한 다음 학습 단계로 로깅 확인 및 중단점 디버깅을 익힙니다 [2].
|
||||
- **My Project Relevance:** 방대하고 문서화가 부족한 레거시 코드베이스를 인수인계받아 읽어야 할 때, 우선적으로 시스템 에러 로그를 발생시켜 핵심 로직이 위치한 파일을 역추적하는 실전 가이드로 활용할 수 있습니다.
|
||||
### Structured logger (TypeScript pino)
|
||||
```typescript
|
||||
import pino from 'pino';
|
||||
|
||||
### Adjacent Topics
|
||||
- [[모니터링 (Monitoring)]]
|
||||
- 확장 방향: 로그 데이터와 결합하여 시스템의 가시성, 성능 지표, 아키텍처 상태를 종합적으로 추적하고 시각화하는 방법론으로 학습을 확장할 수 있습니다 [3, 4].
|
||||
- [[동적 분석 (Dynamic Analysis)]]
|
||||
- 확장 방향: 소스 코드를 읽는 '정적 분석'을 넘어, 실제 실행 중에 수집되는 로그, 런타임 프로파일링, 메모리 상태 등을 활용해 코드를 해독하는 포괄적인 분석 기법으로 시야를 넓힐 수 있습니다 [2].
|
||||
export const logger = pino({
|
||||
level: process.env.LOG_LEVEL ?? 'info',
|
||||
formatters: {
|
||||
level: (label) => ({ level: label }),
|
||||
bindings: () => ({ service: process.env.SERVICE_NAME, env: process.env.NODE_ENV }),
|
||||
},
|
||||
timestamp: pino.stdTimeFunctions.isoTime,
|
||||
redact: { paths: ['*.password', '*.token', '*.creditCard'], censor: '[REDACTED]' },
|
||||
});
|
||||
|
||||
---
|
||||
*Last updated: 2026-05-02*
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
|
||||
**추출된 패턴:**
|
||||
> *(TODO)*
|
||||
|
||||
**세부 내용:**
|
||||
- *(TODO)*
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
|
||||
- **정보 상태:** needs_review
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
|
||||
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
|
||||
- **처리 방식:** UPDATE (자동 정규화)
|
||||
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
|
||||
## 💻 코드 패턴 (Code Patterns)
|
||||
|
||||
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
|
||||
|
||||
```text
|
||||
# TODO
|
||||
// usage
|
||||
logger.info({ userId, orderId, amountCents }, 'order placed');
|
||||
logger.error({ err, requestId }, 'payment failed');
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준 (Decision Criteria)
|
||||
### Trace correlation (OpenTelemetry)
|
||||
```typescript
|
||||
import { trace, context } from '@opentelemetry/api';
|
||||
|
||||
**선택 A를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
function logWithTrace(msg: string, fields: object) {
|
||||
const span = trace.getSpan(context.active());
|
||||
const ctx = span?.spanContext();
|
||||
logger.info({
|
||||
...fields,
|
||||
trace_id: ctx?.traceId,
|
||||
span_id: ctx?.spanId,
|
||||
}, msg);
|
||||
}
|
||||
```
|
||||
|
||||
**선택 B를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
### Log sampling (high-volume endpoints)
|
||||
```typescript
|
||||
function sampledLog(level: 'info'|'debug', sampleRate: number, fields: object, msg: string) {
|
||||
if (Math.random() < sampleRate) {
|
||||
logger[level]({ ...fields, sampled: true, sample_rate: sampleRate }, msg);
|
||||
}
|
||||
}
|
||||
// e.g. health-check endpoint at 1% sampling
|
||||
```
|
||||
|
||||
**기본값:**
|
||||
> *(TODO)*
|
||||
### PII redaction middleware
|
||||
```typescript
|
||||
const PII_PATTERNS = [
|
||||
/\b\d{3}-\d{2}-\d{4}\b/g, // SSN
|
||||
/\b\d{4}-\d{4}-\d{4}-\d{4}\b/g, // credit card
|
||||
/\b[\w.+-]+@[\w-]+\.[\w.-]+\b/g, // email
|
||||
];
|
||||
|
||||
## ❌ 안티패턴 (Anti-Patterns)
|
||||
function redactPII(s: string): string {
|
||||
return PII_PATTERNS.reduce((acc, re) => acc.replace(re, '[REDACTED]'), s);
|
||||
}
|
||||
```
|
||||
|
||||
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
|
||||
### Append-only audit log
|
||||
```typescript
|
||||
interface AuditEvent {
|
||||
id: string; // ULID for time-ordering
|
||||
actor: string;
|
||||
action: string;
|
||||
resource: string;
|
||||
before?: unknown;
|
||||
after?: unknown;
|
||||
timestamp: string; // ISO8601
|
||||
hashChainPrev: string; // tamper-evident chain
|
||||
hashChainCurrent: string;
|
||||
}
|
||||
|
||||
function appendAudit(prev: AuditEvent | null, event: Omit<AuditEvent, 'hashChainCurrent'|'hashChainPrev'|'id'>) {
|
||||
const id = ulid();
|
||||
const prevHash = prev?.hashChainCurrent ?? '0'.repeat(64);
|
||||
const payload = JSON.stringify({ id, prevHash, ...event });
|
||||
const currentHash = sha256(payload);
|
||||
return { id, hashChainPrev: prevHash, hashChainCurrent: currentHash, ...event } as AuditEvent;
|
||||
}
|
||||
```
|
||||
|
||||
### Log aggregation pipeline
|
||||
```yaml
|
||||
# fluent-bit.conf
|
||||
[SERVICE]
|
||||
Flush 1
|
||||
Daemon off
|
||||
[INPUT]
|
||||
Name tail
|
||||
Path /var/log/app/*.log
|
||||
Parser json
|
||||
[FILTER]
|
||||
Name kubernetes
|
||||
Match *
|
||||
Merge_Log On
|
||||
[OUTPUT]
|
||||
Name loki
|
||||
Match *
|
||||
Url https://loki.example.com/loki/api/v1/push
|
||||
Labels {job="app", env="prod"}
|
||||
```
|
||||
|
||||
### Log-based alert (Loki LogQL)
|
||||
```logql
|
||||
sum by (service) (
|
||||
rate({env="prod", level="error"} | json | err_type != "ClientError" [5m])
|
||||
) > 1
|
||||
```
|
||||
|
||||
### Drain3 log clustering (anomaly detection)
|
||||
```python
|
||||
from drain3 import TemplateMiner
|
||||
miner = TemplateMiner()
|
||||
for line in stream:
|
||||
res = miner.add_log_message(line)
|
||||
# res['change_type'] in ['cluster_created','cluster_template_changed','none']
|
||||
if res['change_type'] == 'cluster_created':
|
||||
alert(f"new log pattern: {res['template_mined']}")
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 모든 service | Structured JSON + trace correlation |
|
||||
| 고볼륨 endpoint | Sampling (1-10% INFO/DEBUG) |
|
||||
| 금융/헬스케어 | Append-only audit + PII redaction + 7y retention |
|
||||
| Distributed system | OTel + centralized Loki/CloudWatch/Datadog |
|
||||
| Local dev | Pretty-printed + DEBUG level |
|
||||
|
||||
**기본값**: 매 JSON + ISO time + level + service + trace_id + message + structured fields.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Observability]] · [[Telemetry_(Telemetry)]]
|
||||
- 변형: [[Append-only log]] · [[Audit Log]] · [[Structured Logging]]
|
||||
- 응용: [[스택_트레이스(Stack_trace)]] · [[Logging_Diagnostics]] · [[Architecture Erosion (아키텍처 침식)]]
|
||||
- Adjacent: [[OpenTelemetry]] · [[Distributed Tracing]] · [[비기능 요구사항 (Non-functional Requirements)]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 log schema design, redaction rule draft, log-based alert query, log clustering for unknown patterns, postmortem timeline reconstruction.
|
||||
**언제 X**: 매 raw log content with PII (privacy), 매 customer-attributable narrative without aggregation.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **String concat logging**: 매 `"user " + id + " did " + x` → grep-only, no fields.
|
||||
- **Log everything DEBUG in prod**: 매 cost 폭증 + signal-to-noise 0.
|
||||
- **PII in logs**: 매 password/SSN/credit card untouched → instant breach.
|
||||
- **No retention policy**: 매 7-year retention for trivial DEBUG → storage runaway.
|
||||
- **Logs as primary metric**: 매 count error logs → use metrics; logs are narrative.
|
||||
- **Blocking sync logging**: 매 disk fsync per log → throughput 폭락. Use async batch.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (OpenTelemetry Logs spec v1.31, Google SRE Book Ch.6 "Monitoring Distributed Systems", RFC 5424).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — structured logging + OTel + audit + redaction patterns |
|
||||
|
||||
Reference in New Issue
Block a user