basicConfig
- Accepts
level, filename, stream (sys.stdout or sys.stderr), force,
and handlers (an iterable of handler objects) either via keyword arguments
or the BasicConfig dataclass.
filename and stream are mutually exclusive and cannot be combined with
the handlers argument.
- Passing
force=True clears existing handlers on the root logger before
installing the new one.
- Formatting parameters (
format, datefmt, and friends) are intentionally
unsupported until formatter customization lands.
ConfigBuilder (imperative API)
from femtologging import (
ConfigBuilder,
LoggerConfigBuilder,
StreamHandlerBuilder,
FileHandlerBuilder,
OverflowPolicy,
LevelFilterBuilder,
PythonCallbackFilterBuilder,
)
def add_request_id(record):
record.request_id = "req-123"
return True
builder = (
ConfigBuilder()
.with_handler("console", StreamHandlerBuilder.stderr())
.with_handler(
"audit",
FileHandlerBuilder("/var/log/app.log").with_overflow_policy(
OverflowPolicy.block()
),
)
.with_filter(
"request_context",
PythonCallbackFilterBuilder(add_request_id),
)
.with_filter("info_only", LevelFilterBuilder().with_max_level("INFO"))
.with_logger(
"app.audit",
LoggerConfigBuilder()
.with_level("INFO")
.with_handlers(["audit"])
.with_filters(["request_context", "info_only"])
.with_propagate(False),
)
.with_root_logger(
LoggerConfigBuilder().with_level("WARNING").with_handlers(["console"])
)
)
builder.build_and_init()
with_default_level(level) sets a fallback for loggers that omit explicit
levels. with_disable_existing_loggers(True) clears handlers and filters on
previously created loggers that are not part of the new configuration (their
ancestors are preserved automatically).
- Available filter builders are
LevelFilterBuilder,
NameFilterBuilder, and PythonCallbackFilterBuilder. Callback filters run
on the producer thread and may either return a truthy/falsy value directly or
expose a stdlib-style filter(record) method. Filters are applied in the
order they are declared in each LoggerConfigBuilder.
- Formatter registration (
with_formatter(id, FormatterBuilder)) is currently
a placeholder. Registered formatters are stored in the serialized config, but
handlers still treat any string other than "default" as unknown and raise
HandlerConfigError.
dictConfig (restricted compatibility layer)
- Supported handler classes:
logging.StreamHandler,
femtologging.StreamHandler, logging.FileHandler,
femtologging.FileHandler, logging.handlers.RotatingFileHandler,
logging.handlers.TimedRotatingFileHandler, and
logging.handlers.SocketHandler (plus their femtologging equivalents).
- Handler
args are evaluated with ast.literal_eval, matching the stdlib
behaviour for simple tuples. For socket handlers you can pass either
(host, port) or a single Unix socket path; keyword arguments mirror the
builder API (host, port, unix_path, capacity, connect_timeout_ms,
write_timeout_ms, max_frame_size, tls, tls_domain, tls_insecure,
backoff_* aliases).
- Top-level
filters sections are supported. Declarative mappings still use
exactly one of level or name, while factory mappings use stdlib-style
"()" syntax such as {"()": "pkg.module.FilterFactory", "prefix": "svc"}.
The factory target may be a dotted path or a direct callable, and is
instantiated with the remaining keys as keyword arguments. Mixing "()" with
level or name is rejected. Loggers and the root logger accept a filters
list of filter IDs.
- Unsupported stdlib features raise
ValueError: incremental updates,
handler level, handler filters, and handler formatters. Although the
schema accepts a formatters section, referencing a formatter from a handler
currently results in ValueError("unknown formatter id").
- A
root section is mandatory. Named loggers support level,
handlers, filters, and propagate (bool).
fileConfig (INI compatibility)
fileConfig(path, defaults=None, disable_existing_loggers=True, encoding=None)
parses CPython-style INI files via the Rust extension and translates them to
the restricted dictConfig schema.
- Default substitutions (
%(foo)s) work across the INI file and any mapping
you pass via defaults.
- Formatters and handler-level overrides are not supported. Including
[formatter_*] sections or specifying level/formatter inside
[handler_*] entries raises ValueError.