Files
2nd/10_Wiki/Topic_Programming/Architecture/Logging_Diagnostics.md
T
Antigravity Agent 9148c358d0 docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를
Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류.

- 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로
  자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거,
  동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거.
- 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming,
  Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business,
  Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로,
  나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는
  title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백).
  원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지.
- 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서.
- 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는
  지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지.
- Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경.
- 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
2026-07-05 00:33:48 +09:00

7.0 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-logging-diagnostics Logging Diagnostics 10_Wiki/Topics verified self
Logging
Application Logging
Diagnostic Logging
none A 0.9 applied
observability
logging
diagnostics
sre
2026-05-10 pending
language framework
typescript pino

Logging Diagnostics

매 한 줄

"매 structured event 의 production runtime 의 X-ray". Application logging 은 매 incident 의 forensic record + 매 system behavior 의 narrative. 2026 best practice: structured JSON logs + OpenTelemetry semantic conventions + sampling at scale + cardinality discipline. Plain text logs 는 매 deprecated; loggers 는 매 trace context 와 correlation.

매 핵심

매 3 pillars (observability)

  • Logs: discrete events, high cardinality, narrative.
  • Metrics: aggregated time-series, low cardinality, dashboards/alerts.
  • Traces: causal chain across services.
  • 매 modern unified backbone: OpenTelemetry → Loki/Tempo/Prometheus 또는 Datadog/Honeycomb.

매 log levels

  • TRACE: 매 fine-grained internal state (off in prod).
  • DEBUG: 매 development diagnostics (sampled or off in prod).
  • INFO: 매 business event, lifecycle (default level).
  • WARN: 매 degraded but recoverable.
  • ERROR: 매 actionable failure — page-worthy candidate.
  • FATAL: 매 process-terminating.

매 structured logging principles

  1. JSON output (or logfmt).
  2. 매 fixed schema: timestamp, level, service, trace_id, span_id, message, ...attrs.
  3. Correlation IDs propagated (W3C Trace Context).
  4. 매 PII redaction at source.
  5. Sampling for high-volume paths.
  6. 매 cardinality discipline — no unbounded values in indexed fields.

매 응용

  1. Incident investigation (search by trace_id).
  2. Audit trail (compliance — separate stream).
  3. Business event analytics (BI pipeline ingestion).
  4. SLO error budget calculation.
  5. Anomaly detection input.

💻 패턴

1. Pino (Node.js, fast structured logging)

import pino from "pino";

export const logger = pino({
  level: process.env.LOG_LEVEL ?? "info",
  redact: ["password", "*.authorization", "creditCard"],
  formatters: {
    level: (label) => ({ level: label }),
  },
  base: {
    service: "checkout",
    env: process.env.NODE_ENV,
    version: process.env.GIT_SHA,
  },
});

logger.info({ userId, orderId, amount }, "order placed");
// {"level":"info","time":1710000000,"service":"checkout","userId":"u1",...}

2. OpenTelemetry log correlation

import { trace } from "@opentelemetry/api";
import pino from "pino";

const baseLogger = pino();

export function getLogger() {
  const span = trace.getActiveSpan();
  const ctx = span?.spanContext();
  return baseLogger.child({
    trace_id: ctx?.traceId,
    span_id: ctx?.spanId,
  });
}

// Usage
getLogger().error({ err }, "payment failed");
// Now searchable by trace_id across services.

3. Python structlog

import structlog

structlog.configure(
    processors=[
        structlog.contextvars.merge_contextvars,
        structlog.processors.add_log_level,
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.processors.JSONRenderer(),
    ],
)

log = structlog.get_logger()

structlog.contextvars.bind_contextvars(request_id=req_id, user_id=uid)
log.info("checkout_started", cart_size=len(cart))

4. Sampling (head + tail)

// Head sampling: decide at request entry
function shouldLog(req: Request): boolean {
  if (req.url.startsWith("/health")) return false;       // drop healthchecks
  if (req.headers["x-debug"]) return true;               // force on
  return Math.random() < 0.01;                           // 1% sample for /api/*
}

// Tail sampling (in OTel collector): keep all errors + slow + 1% baseline

5. Error logging with stack + cause

try {
  await chargeCard(order);
} catch (err) {
  logger.error({
    err: { message: err.message, stack: err.stack, cause: err.cause },
    orderId: order.id,
    customerId: order.customerId,
  }, "charge failed");
  throw err;
}

6. Redaction (PII safety)

const SENSITIVE = /(\b\d{16}\b|\b\d{3}-\d{2}-\d{4}\b)/g;  // CC, SSN

function sanitize(obj: any): any {
  const json = JSON.stringify(obj);
  return JSON.parse(json.replace(SENSITIVE, "[REDACTED]"));
}

logger.info(sanitize(payload), "received webhook");

7. Audit log (separate stream)

const audit = pino({
  level: "info",
  base: { stream: "audit" },
  // separate transport → tamper-evident store (S3 + object lock)
});

audit.info({
  actor: user.id,
  action: "user.delete",
  target: targetId,
  ip: req.ip,
  outcome: "success",
}, "audit");

8. Go slog (stdlib, 1.21+)

import "log/slog"

logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
    Level: slog.LevelInfo,
}))
slog.SetDefault(logger)

slog.Info("order placed",
    "user_id", userID,
    "order_id", orderID,
    "amount", amount,
)

매 결정 기준

상황 Approach
새 service Structured JSON + OTel correlation.
High-volume path (>1k rps) Head sampling + tail sampling.
Compliance / audit Separate audit stream + immutable store.
Legacy plain-text logs Parse → enrich → forward (Vector, Fluent Bit).
Edge / IoT Compact binary (CBOR) + batched upload.
Real-time alerting on log content Stream → Loki/ELK with regex rules.

기본값: 2026 의 새 서비스는 매 OTel logs + structured JSON + Pino/structlog/slog. 매 plain text 의 X.

🔗 Graph

🤖 LLM 활용

언제: log schema design, sampling strategy, log-to-trace correlation, redaction policy review. 언제 X: 매 metric/trace 만 필요한 경우 (logs 의 cost > value), 매 single-developer side project (basic console.log 충분).

안티패턴

  • String interpolation logs: log.info("user " + id + " did " + action) — 매 unparseable, 매 search 불가. 매 structured fields 사용.
  • PII leak: 매 redaction 부재 → 매 GDPR breach.
  • Unbounded cardinality: 매 user_email 을 indexed field 로 → 매 storage explosion.
  • Logging in tight loop: 매 hot path 의 매 iter 마다 log → 매 IO bottleneck.
  • Catch and silent log: } catch (e) { logger.error(e); } 에서 매 context 부재 — orderId/userId 같이 add.
  • Plain text in 2026: 매 grep-only logs — search/correlation 매 painful.
  • No trace correlation: 매 service 마다 isolated logs — 매 incident 시 매 cross-service narrative 의 manual 재구성.

🧪 검증 / 중복

  • Verified (OpenTelemetry Logs spec, Google SRE Book Ch.6, Pino/structlog official docs).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — structured logging + OTel correlation + sampling/redaction patterns