Logging

Logging related utils

File: klea_utils/plogging.py

Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>

klea_utils.plogging.KLEA_LOG_LEVEL_ENV = 'KLEA_LOG_LEVEL'

Environment variable that selects the console logging level across all Klea CLIs (see resolve_log_level()). Read from the process environment only – the app env files (e.g. klea_agent.env) are loaded after logging is configured, so this var cannot be set there.

klea_utils.plogging.KLEA_LOG_NAMESPACES = ('klea_utils', 'klea_rag', 'klea_agent', 'neuroml_mcp')

Klea logger namespaces that are turned up to DEBUG by setup_root_logger. Everything else (third-party libraries) inherits the root logger’s INFO level, so their DEBUG output is filtered at the source without having to enumerate them.

class klea_utils.plogging.LoggerInfoFilter(name='')[source]

Bases: Filter

Allow only INFO messages

filter(record)[source]

Determine if the specified record is to be logged.

Returns True if the record should be logged, or False otherwise. If deemed appropriate, the record may be modified in-place.

class klea_utils.plogging.LoggerNotInfoFilter(name='')[source]

Bases: Filter

Allow only non INFO messages

filter(record)[source]

Determine if the specified record is to be logged.

Returns True if the record should be logged, or False otherwise. If deemed appropriate, the record may be modified in-place.

klea_utils.plogging.enable_debug_logging() None[source]

Set KLEA_LOG_LEVEL_ENV to debug in this process.

Called by a --debug flag on a CLI that spawns child processes (a client starting a server, a serve command) so the child resolves DEBUG via resolve_log_level() – environment variables are inherited across the subprocess boundary.

klea_utils.plogging.logger_formatter_info = <colorlog.formatter.ColoredFormatter object>

Console formatters colorize each line by level (whole-line color via the %(log_color)s prefix). The file formatter stays plain so ANSI escape codes never end up in log files.

klea_utils.plogging.mask_sensitive(data: dict[str, Any], sensitive_keys: set[str] | None = None) dict[str, Any][source]

Return a copy with sensitive values masked for logging.

Shows only the last 4 characters of each matching value to prevent secrets (API keys, tokens) from appearing in plaintext in log output. Recurses into nested dicts, so e.g. {"model_overrides": {"chat": {"api_key": ...}}} is sanitized too.

Parameters:
  • data – The dict to sanitize.

  • sensitive_keys – Keys whose values should be masked. Defaults to {"api_key"}.

Returns:

New dict with masked values.

klea_utils.plogging.resolve_log_level(debug: bool = False) int[source]

Return the console logging level for the current process.

Precedence, highest first:

  1. --debug (the debug flag) – always DEBUG

  2. the KLEA_LOG_LEVEL_ENV environment variable – accepted as a case-insensitive level name (debug/info/warning/error/ critical) or a numeric level

  3. INFO

An unknown KLEA_LOG_LEVEL_ENV value is logged as a warning and falls back to INFO. Intended to be shared by every Klea CLI so the --debug flag and env var behave consistently across them.

Parameters:

debugTrue when the --debug flag was given

Returns:

A logging level constant

klea_utils.plogging.setup_root_logger(app_name: str, stderr_level: int = 20, log_dir: str | Path | None = None) Logger[source]

Configure the root logger once per process.

Idempotent: if the root logger already has handlers, this is a no-op and the existing configuration is returned unchanged.

Adds, on the root logger:

  • a stdout handler for INFO messages (simple format)

  • a stderr handler for all other levels at stderr_level (format includes the function name)

  • an optional RotatingFileHandler at {log_dir}/{app_name}.log logging all levels at DEBUG when log_dir is provided

The root logger is set to INFO. The Klea logger namespaces (see KLEA_LOG_NAMESPACES) and the application logger (app_name) are raised to DEBUG so our own logs are captured in full. Because module loggers propagate to the root logger by default, a single call from each application entry point routes all Klea logs (library modules, graph nodes, API routers) through the same console and file handlers. Third-party libraries inherit the root’s INFO level, so their DEBUG output is filtered at the source without enumerating them.

The console default is INFO (progress on stdout, warnings and errors on stderr) – end users see no debug noise. Pass stderr_level=logging.DEBUG (e.g. from resolve_log_level() when --debug / KLEA_LOG_LEVEL request it) to surface full detail on the console. The rotating log file always captures DEBUG regardless, so verbose logs remain available for diagnostics.

Parameters:
  • app_name – Application name, used as the log file name to keep per-app logs separate (e.g. "klea-rag").

  • stderr_level – Level for the stderr handler (default INFO)

  • log_dir – Directory for the log file. None disables file logging.

Returns:

The configured root logger