Skip to content

feat(logging): add Logger interface and default logger (2/6)#723

Open
kamcheungting-db wants to merge 3 commits into
apache:mainfrom
kamcheungting-db:logging-block2-interface
Open

feat(logging): add Logger interface and default logger (2/6)#723
kamcheungting-db wants to merge 3 commits into
apache:mainfrom
kamcheungting-db:logging-block2-interface

Conversation

@kamcheungting-db

Copy link
Copy Markdown

What

Second of the logging stack.

Adds the abstract Logger interface (ShouldLog/Log/SetLevel/level/Flush/Noop), the owned LogMessage record (formatted text + source location + reserved attributes), and the process-wide default logger: a lock-free atomic level gate for the disabled path and a thread-local generation cache for the enabled path (no lock/refcount in steady state), swapped under a mutex via SetDefaultLogger/SetDefaultLevel. Seed default is the no-op logger; CerrLogger and spdlog come in later PRs.

Also adds the .cc-only generated config.h used later for backend selection.

Testing

compiled and run with clang++ -std=c++23 -stdlib=libc++ (clang 18) — Noop singleton, seed default, set/get, generation-cache swaps, gate seeding,
SetDefaultLevel sync, and nullptr→Noop all pass.

Full ctest/spdlog-ON build needs a C++23 toolchain + network (gtest/spdlog) in CI.

Re-add spdlog as a build dependency to serve as the foundation for the
logging system. Adapted to current structure: spdlog joins the core
iceberg lib interface lists (roaring has since moved to iceberg_data).

Co-authored-by: Isaac
This is the first of six small PRs that together add a logging system to
iceberg-cpp. It introduces LogLevel, the severity scale everything else builds
on: trace, debug, info, warn, error, critical, fatal, plus an `off` sentinel for
turning logging off entirely.

Levels are ordered from most to least verbose, so deciding whether something
should be logged is a plain `level >= threshold` comparison. Two helpers come
with it: ToString to print a level, and LogLevelFromString to parse one
(case-insensitive, returning a Result for unrecognized input). Both follow the
same shape as CounterUnit in metrics/counter.h.

There is no implementation behind the header yet, so this PR only adds the
header, wires the new src/iceberg/logging directory into the build, and adds a
test covering the round-trip, ordering, and parsing.

Co-authored-by: Isaac
@kamcheungting-db kamcheungting-db changed the title [Iceberg Logger] [Part-2] Logger Interface feat: [Iceberg Logger] [Part-2] Logger Interface Jun 10, 2026
@kamcheungting-db kamcheungting-db changed the title feat: [Iceberg Logger] [Part-2] Logger Interface feat(logging): add Logger interface and default logger Jun 11, 2026
@kamcheungting-db kamcheungting-db changed the title feat(logging): add Logger interface and default logger feat(logging): add Logger interface and default logger (2/6) Jun 11, 2026
Second of the logging stack. This defines what a logger is and where the rest of
the code finds one, with no concrete backend yet.

Logger is a small abstract interface: ShouldLog to test a level, Log to emit an
already-formatted record, SetLevel/level, Flush, and a shared no-op instance.
Records are passed as LogMessage, which owns its formatted text (so a sink may
safely hold onto it) and carries the source location plus a reserved slot for
structured key/values we may add later. The interface spells out two rules for
implementations: never call back into logging from inside Log/Flush, and keep
level() a true lower bound for ShouldLog.

There is also one default logger per process, designed to be cheap to reach on
the logging path: a lock-free atomic level check drops disabled messages
outright, and when a message does need logging the current logger comes from a
thread-local cache that only refreshes when the default actually changes, so the
steady state has no lock or reference-count traffic. SetDefaultLogger and
SetDefaultLevel swap it safely under a mutex. The seed default is the no-op
logger; CerrLogger and the spdlog backend arrive in later PRs.

Also adds the build-generated, .cc-only config header used later to pick the
backend, and tests for the interface and the default-logger lifecycle.

Co-authored-by: Isaac
@kamcheungting-db kamcheungting-db force-pushed the logging-block2-interface branch from b4721af to f1e8530 Compare June 11, 2026 04:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant