aeat.core.logging module¶
Logging configuration entry point.
Provides get_logger() as the consistent logger factory to avoid scattered
bare logging instances, with configure_logging() installing the project
defaults. The installed log-record factory reads
aeat.core.observability.current_run_context() state indirectly through
contextvars, so every record automatically picks up the active run_id /
step_id while a run context is bound.
This module attaches the log-record secret scrubber. Every handler
attached through configure_logging() receives a
SecretScrubbingFilter so sensitive fields are redacted before
formatting. Shape-based NIF, URL, and bearer-token matching is delegated
to redact_for_log(); this module keeps only
logging-specific key-paired placeholders such as cookies, passphrases, and
certificate serial suffixes. Per-run JSONL handlers are attached with
attach_run_sink() so the same filter protects observability output.
Logging is a diagnostic channel, not the CLI result contract. Operator-facing
success payloads and typed Notice values are
rendered through the JSON/text output stack; this module only prepares redacted
log records and plaintext diagnostic log files rooted by settings.
- class SecretScrubbingFilter(name='')[source]¶
Bases:
FilterRedact sensitive fields from log records before formatting.
The filter mutates each
logging.LogRecordin place so handlers, stderr diagnostics, and JSONL run sinks see the same scrubbed record. It is deliberately narrower than CLI output redaction: structured command results still route throughaeat.core.output_renderingoraeat.core.json_contract, while this filter protects logging-only message text, %-format args, exception text, andextrafields.
- default_log_file_path()[source]¶
Return the file path for non-interactive project logs.
The diagnostic log is rooted under
aeat_log_dir, which theSettingsvalidator derives from<aeat_local_storage_root>/logswhen no explicitAEAT_LOG_DIRoverride is supplied — so the log stays isolated per workspace rather than mixing every session’s records into a single system-wide file.- Return type:
Path
- configure_logging()[source]¶
Configure the project-wide diagnostic logging defaults.
Installs settings-derived stderr/file handlers, the run-context record factory, and
SecretScrubbingFilteron the root logger plus every configured handler. The file handler writes redacted diagnostic plaintext underdefault_log_file_path(); this module does not encrypt logs or persist them through secure-object repositories.When the diagnostic log directory cannot be created (an inaccessible
AEAT_LOCAL_STORAGE_ROOT/AEAT_LOG_DIR), logging degrades to stderr-only and records an instructive diagnostic naming the likely remedy — it never crashes CLI startup with a raw traceback.The function is idempotent so early imports can safely call
get_logger()without duplicating handlers.- Return type:
- set_log_level(level, *, file_level=10)[source]¶
Apply
levelto the root logger and every attached handler.The root logger itself is always set to
logging.DEBUGso no record is discarded before reaching a handler; each handler then applies its own level gate.FileHandlerinstances receivefile_level(defaultDEBUG) to keep the diagnostic log comprehensive. All other handlers (typically the stderr stream handler) receivelevel.configure_logging()is called first so the dictConfig contract is in place before any level mutation.- Parameters:
level (
int) – The effective level for non-file handlers (e.g.logging.INFOfor verbose mode).file_level (
int) – The level applied tologging.FileHandlerinstances (defaultlogging.DEBUG).
- Return type:
- attach_run_sink(sink)[source]¶
Install
SecretScrubbingFilteronsinkthen attach it to root.Ensures every record flowing through the JSONL run sink is scrubbed before it reaches the serialiser, even when the root-logger filter has already scrubbed the shared record in-place. The filter is idempotent: a second call with the same sink is a no-op because the guard checks
root_logger.handlersfor an existing instance.- Parameters:
sink (
Handler) – Thelogging.Handler(typicallyaeat.core.observability._sink.JsonlRunSink) to attach to the root logger.- Return type:
The sink is a diagnostic observability target. It receives redacted log records, not CLI result payloads or secure-storage records.
- detach_run_sink(sink)[source]¶
Remove
sinkfrom the root logger and perform symmetric teardown.Reverses every side-effect of
attach_run_sink(): the handler is removed from the root logger, theSecretScrubbingFilterinstances thatattach_run_sink()installed on the sink are removed, and the sink is flushed so in-flight records reach their destination before the handle is released.The caller is responsible for closing the sink after detach; this function deliberately does not call
close()so a caller can flush output and inspect state before teardown.- Parameters:
sink (
Handler) – Thelogging.Handlerpreviously attached byattach_run_sink().- Return type:
- get_logger(name)[source]¶
Return a configured logger for the given module name.
Preferred over direct
logging.getLogger()in production modules because it ensures the project defaults are installed and attachesSecretScrubbingFilterdirectly to the returned logger. Startup modules that must use stdlib logging before settings load rely on later propagation through the configured root logger instead.