Files
project-auth-server/docs/examples/observability/log-message-format.md
T

2.6 KiB

Log Message Format 예시

좋은 예시

예시 1. 사건 설명 + key-value 필드를 함께 남긴다

log.info("Created user. actorId={} userId={} requestPath={}",
        actorId, userId, requestPath);

좋은 이유:

  • 사건이 짧게 드러난다
  • 검색 가능한 핵심 키가 있다
  • free text만으로 끝나지 않는다

예시 2. 실패 메시지에 운영 키를 먼저 담고 예외를 붙인다

log.error("Failed external auth request. provider={} actorId={} durationMs={}",
        provider, actorId, durationMs, ex);

좋은 이유:

  • 메시지 자체만 봐도 무엇이 실패했는지 알 수 있다
  • stack trace는 추가 정보로 붙는다
  • 운영 키가 빠지지 않는다

예시 3. 재시도/대체 경로도 명시적 사건으로 남긴다

log.warn("Applied external auth fallback. provider={} actorId={} fallback={} durationMs={}",
        provider, actorId, "cached-public-key", durationMs);

좋은 이유:

  • fallback 발생 사실이 바로 드러난다
  • 이후 검색과 집계가 쉽다

예시 4. structured logging 전환을 고려한 키 이름을 쓴다

log.info("Completed session cleanup. job={} deletedCount={} durationMs={}",
        "expired-session-cleanup", deletedCount, durationMs);

좋은 이유:

  • 텍스트 로그에서도 구조가 보인다
  • JSON 로그로 전환해도 의미가 유지된다

나쁜 예시

예시 1. 설명만 길고 검색 키가 없다

log.info("The user registration process was completed successfully after all checks had been passed");

나쁜 이유:

  • 누가, 어떤 요청에서, 어떤 리소스가 생성됐는지 알 수 없다
  • 검색/집계가 어렵다

예시 2. 예외 메시지를 그대로 제목으로 쓴다

log.error(ex.getMessage(), ex);

나쁜 이유:

  • 사건 맥락이 없다
  • 운영 키가 없다
  • 예외 메시지 품질에 로그 제목이 종속된다

예시 3. 민감정보를 그대로 남긴다

log.debug("Login request. email={} password={} accessToken={}",
        request.email(), request.password(), accessToken);

나쁜 이유:

  • 민감정보가 원문으로 노출된다
  • 디버그 로그라도 허용되지 않는다

예시 4. 같은 의미를 제각각 다른 키 이름으로 쓴다

log.info("Created user. uid={} path={} timeMs={}", userId, requestPath, durationMs);
log.info("Deleted user. userId={} requestUri={} duration={}", userId, requestPath, durationMs);

나쁜 이유:

  • 같은 의미의 키 이름이 섞인다
  • 검색/집계/알람 규칙이 복잡해진다