Abseil LogEntry·structured logging
#LogEntry — Sink가 보는 인터페이스
LogSink::Send가 받는 absl::LogEntry는 한 로그 호출의 모든 메타데이터를 노출한다.
class LogEntry {public: absl::LogSeverity log_severity() const; int verbosity() const; // VLOG 레벨, LOG는 kNoVerbosityLevel absl::Time timestamp() const; absl::LogEntry::tid_t tid() const; // thread id absl::string_view source_filename() const; absl::string_view source_basename() const; int source_line() const; bool prefix() const; // 헤더 포함 여부
absl::string_view text_message() const; // 본문만 absl::string_view text_message_with_prefix() const; // "Iyyyymmdd ..." 포함
// 구조화 (future-friendly) bool is_perror() const; absl::string_view text_message_with_prefix_and_newline() const;};이걸 활용해 다음을 자동 추출한다.
severity로 alert 라우팅source_filename + line으로 검색 키timestamp로 시계열 인덱스tid로 thread별 trace
#JSON 변환 예
class JsonSink : public absl::LogSink {public: void Send(const absl::LogEntry& entry) override { absl::flat_hash_map<std::string, std::string> kv = { {"severity", absl::LogSeverityName(entry.log_severity())}, {"ts", absl::FormatTime(absl::RFC3339_full, entry.timestamp(), absl::UTCTimeZone())}, {"file", std::string(entry.source_basename())}, {"line", absl::StrCat(entry.source_line())}, {"tid", absl::StrCat(entry.tid())}, {"msg", std::string(entry.text_message())}, }; std::cerr << ToJson(kv) << "\n"; }};ELK·Loki·CloudWatch 등 JSON 한 줄 입력을 받는 시스템에 그대로 송신 가능.
#구조화 로깅의 진짜 의미
전통적 텍스트 로그:
I20260525 13:00:00 12345 user.cc:42] user 123 logged in from 10.0.0.5이 한 줄에서 user_id, ip를 정규식으로 파싱 해야 한다. 메시지 형식이 바뀌면 파서가 깨진다.
구조화 로깅은 key-value를 처음부터 분리.
{"severity":"INFO","ts":"2026-05-25T13:00:00Z","file":"user.cc","line":42, "msg":"user logged in","user_id":123,"ip":"10.0.0.5"}Abseil의 LogEntry는 기본 metadata만 분리한다. 사용자 페이로드의 key-value는 직접 인코딩해야 한다.
#커스텀 field 추가 — 메시지에 인코딩
가장 단순한 방법은 메시지 본문에 구조화 토큰을 박는 것.
LOG(INFO) << "user_login user_id=" << user.id << " ip=" << client_ip;sink에서 메시지를 파싱(absl::StrSplit)해 KV 추출. 표준화가 안 된 만큼 팀 컨벤션 이 중요.
더 형식적인 접근은 absl::Cord나 protobuf 페이로드를 직렬화해 메시지에 담는 것. 하지만 Abseil은 직접적인 structured 필드 API를 아직 노출하지 않는다.
#코드 리뷰 패턴
// 회피 — 문자열 보간으로 KVLOG(INFO) << "user " << id << " from " << ip << " action " << action;// 파싱이 어려움 (key가 명시 안 됨)
// Good — key=value 형식 통일LOG(INFO) << "user_login user_id=" << id << " ip=" << ip << " action=" << action;// 회피 — 메시지를 동적으로 만들어 검색이 어려움LOG(INFO) << absl::StrCat("user ", id, " ", action_string);
// Good — 고정 prefix + 동적 부분 분리LOG(INFO) << "audit event=" << action_string << " user_id=" << id;prefix가 grep 가능한 고정 토큰 이어야 운영 중 검색이 쉽다.
#logging 레벨 활용
LogEntry::log_severity()를 보고 destination을 나눈다.
void Send(const absl::LogEntry& entry) override { switch (entry.log_severity()) { case absl::LogSeverity::kError: case absl::LogSeverity::kFatal: SendToAlerts(entry); break; default: SendToLogs(entry); }}ERROR 이상만 PagerDuty, 나머지는 일반 로그 시스템.
#source location 활용
void Send(const absl::LogEntry& entry) override { // file:line을 자동 태그로 std::string tag = absl::StrCat(entry.source_basename(), ":", entry.source_line()); metrics->Increment("log_count", {{"location", tag}});}자주 발생하는 ERROR의 위치 가 자동으로 metric label이 된다. 운영 중 hotspot 발견에 유용.
#시간 정밀도
entry.timestamp()는 absl::Time. 나노초 정밀도지만 RFC3339_full 출력 시 ns까지 포함된다. 분산 trace 상관관계에 충분.
absl::FormatTime(absl::RFC3339_full, entry.timestamp(), absl::UTCTimeZone());// "2026-05-25T13:00:00.123456789+00:00"#작은 예시 — Loki/Cloud-friendly JSON sink
class LokiSink : public absl::LogSink {public: LokiSink(std::string service, std::string env) : service_(std::move(service)), env_(std::move(env)) {}
void Send(const absl::LogEntry& entry) override { absl::Time ts = entry.timestamp(); std::string line = absl::StrCat( "{\"ts\":\"", absl::FormatTime(absl::RFC3339_full, ts, absl::UTCTimeZone()), "\",", "\"service\":\"", service_, "\",", "\"env\":\"", env_, "\",", "\"severity\":\"", absl::LogSeverityName(entry.log_severity()), "\",", "\"file\":\"", entry.source_basename(), ":", entry.source_line(), "\",", "\"tid\":", entry.tid(), ",", "\"msg\":\"", EscapeJson(entry.text_message()), "\"}\n");
queue_.Push(std::move(line)); // 비동기 worker가 HTTP POST }
void Flush() override { queue_.Drain(); }
private: std::string service_; std::string env_; AsyncQueue queue_;};
// 등록LokiSink loki("user-svc", "prod");absl::AddLogSink(&loki);#정리
LogEntry는 한 로그 호출의 모든 메타데이터(severity, ts, file/line, tid, msg) 노출.- JSON·protobuf 직렬화로 구조화 로깅 가능. 사용자 KV는 메시지에 직접 인코딩.
severity로 destination 분기,source_basename:line으로 자동 metric label.- 시간은 ns 정밀도 — RFC3339_full로 분산 trace 상관 가능.
- 검색 친화적 prefix(
audit event=...형식) 컨벤션이 중요.
#다음 장 예고
Part 11-04: Stack trace / failure_signal_handler — crash 진단.
#관련 항목
- Part 11-01: LOG, VLOG, CHECK
- Part 11-02: LogSink
- Part 7-02: Format / Parse — RFC3339 timestamp
- 원문 — LogEntry
Abseil Code Review · 62 of 79
- 1 Abseil Code Review — Google production-grade C++ 라이브러리 분석
- 2 Abseil 개요 — Google이 std를 보완한 이유
- 3 Abseil 설계 철학 — std 호환과 추가 기능의 균형
- 4 Abseil 빌드와 의존성 — Bazel vs CMake
- 5 Abseil LTS vs HEAD 릴리스 모델 분석
- 6 Abseil Versioning과 ABI 호환성 정책
- 7 Abseil 매크로 — ABSL_HAVE_*·ABSL_ATTRIBUTE_*
- 8 Abseil ABSL_PREDICT_TRUE/FALSE — branch hint
- 9 absl::LogSeverity — 로그 레벨 타입
- 10 Abseil type_traits — negation·conjunction·void_t
- 11 Abseil Conformance·Policy 분석
- 12 Abseil Memory utilities 분석
- 13 Abseil raw_logging — heap-free 로깅
- 14 Abseil thread_annotations — clang TSA 통합
- 15 absl::Status — exception-free error handling
- 16 absl::StatusOr<T> — 값 또는 에러
- 17 absl status_macros — ASSIGN_OR_RETURN·RETURN_IF_ERROR
- 18 absl::Status payload — 구조화된 에러 컨텍스트
- 19 absl::Status ↔ exception 변환 패턴
- 20 absl::string_view — non-owning 문자열 참조
- 21 absl::string_view 함정 — dangling·c_str·임시 객체
- 22 absl::StrCat — 가변 인자 문자열 연결과 AlphaNum
- 23 absl::StrSplit — Delimiter·Predicate·컨테이너 변환
- 24 absl::StrJoin — 컨테이너 결합과 Formatter
- 25 absl::StrFormat — type-safe printf·FormatSpec
- 26 Abseil ASCII 함수 — locale-free 분류·대소문자 변환
- 27 Abseil Escape — CEscape·HexEscape·Base64
- 28 absl::flat_hash_map — Swiss Table 기반 hash map
- 29 absl::flat_hash_set — set 버전 Swiss Table
- 30 absl::node_hash_map — stable pointer가 필요할 때
- 31 absl::btree_map — sorted·cache-friendly B-tree
- 32 absl::FixedArray — 런타임 크기 stack 배열
- 33 absl::InlinedVector — small buffer optimization
- 34 Abseil Swiss Table internals — control byte·SIMD probing
- 35 absl::Mutex — reader-writer·fairness·deadlock 검출
- 36 absl::Mutex Conditional Critical Section — Await로 cv 없애기
- 37 absl::Notification — once-only signal
- 38 absl::BlockingCounter·Barrier — 다중 thread 조율
- 39 absl::Mutex annotations — clang thread-safety로 race를 컴파일 타임에
- 40 absl::Time·Duration 분석 — 단단한 type
- 41 absl::Time Format·Parse
- 42 absl::CivilTime 분석
- 43 absl::time_zone 분석
- 44 absl::Time mocking — 테스트 친화 시간
- 45 absl::BitGen — 모던 난수 생성기
- 46 Abseil Random Distributions — Uniform·Exponential
- 47 Abseil Mocking Random — 테스트 결정성
- 48 Abseil Random Seeding·Entropy
- 49 absl::int128·uint128 분석
- 50 absl::bits — popcount·countl_zero
- 51 absl::optional vs std::optional
- 52 absl::variant 분석
- 53 absl::span 분석
- 54 absl::any 분석
- 55 absl::compare — three-way 비교
- 56 Abseil utility — apply·in_place
- 57 Abseil AbslHashValue 분석
- 58 Abseil HashState chaining
- 59 Abseil Custom hashable 구현
- 60 Abseil LOG·VLOG·CHECK 분석
- 61 Abseil LogSink 분석
- 62 Abseil LogEntry·structured logging
- 63 Abseil Stack trace·failure_signal_handler
- 64 ABSL_FLAG 정의 분석
- 65 Abseil ParseCommandLine 동작
- 66 Abseil Flag introspection·validation
- 67 Google 스타일의 Abseil 사용 패턴
- 68 Abseil 자주 보는 anti-pattern
- 69 std → absl 마이그레이션 전략
- 70 absl::Cleanup — 함수 종료 시 실행 보장
- 71 Abseil algorithm container 확장 — c_sort·c_find_if·c_count_if
- 72 absl::function_ref와 any_invocable — 함수 객체 전달의 두 축
- 73 absl::bind_front와 Overload — 함수 객체 보조 도구
- 74 absl::Cord — 분산 시스템용 대용량 문자열
- 75 absl::from_chars·SimpleAtoi — 빠른 숫자 변환
- 76 absl::Cord vs std::string — 선택 기준과 메모리 프로파일
- 77 absl::GetStackTrace와 Symbolize — crash 시 readable stack
- 78 absl::ComputeCrc32c — 하드웨어 가속 체크섬
- 79 absl::PeriodicSampler — 적응형 샘플링·jitter 회피
관련 글
Abseil Stack trace·failure_signal_handler
absl::Symbolize, GetStackTrace, InstallFailureSignalHandler — crash 시점에 stack을 찍어 남기는 진단 인프라.
같은 시리즈에서 이어 읽기
Abseil LogSink 분석
absl::LogSink — 출력 destination 커스터마이징. 파일·syslog·원격 collector·테스트 캡처.
같은 시리즈에서 이어 읽기
Abseil LOG·VLOG·CHECK 분석
Abseil logging 기본 매크로 — severity, verbose level, fatal check. glog의 후속이자 Google 표준.
같은 시리즈에서 이어 읽기