API Reference
Logging
- logstruct.getLogger(name)[source]
Retrieve or get a StructuredLogger instance.
getLogger(None)will produce a StructuredLogger delegating to the root logger.- Parameters:
name (str | None)
- Return type:
- class logstruct.StructuredLogger(name)[source]
A structured logger forwarding log calls to an underlying stdlib logger with the same name.
The core difference over the stdlib is passing kwargs as the
extradict. It isn’t necessary to use this class to make use of the structured formatter.Not all methods are proxied. Use the
StructuredLogger.loggerattribute to reach the stdlib logger.- Parameters:
name (str | None)
- __init__(name)[source]
Initialise the underlying stdlib logger.
- Parameters:
name (str | None) – Underlying stdlib logger name,
Nonemeans the root logger.- Return type:
None
- setLevel(level)[source]
Set log level of the underlying logger.
- Parameters:
level (int)
- Return type:
None
- debug(msg, *args, exc_info=None, stack_info=False, stacklevel=1, extra=None, **kwargs)[source]
Delegate a debug call to the underlying logger, merging leftover kwargs into
extra.- Parameters:
msg (object)
args (object)
exc_info (None | bool | tuple[type[BaseException], BaseException, TracebackType | None] | tuple[None, None, None] | BaseException)
stack_info (bool)
stacklevel (int)
kwargs (object)
- Return type:
None
- info(msg, *args, exc_info=None, stack_info=False, stacklevel=1, extra=None, **kwargs)[source]
Delegate a info call to the underlying logger, merging leftover kwargs into
extra.- Parameters:
msg (object)
args (object)
exc_info (None | bool | tuple[type[BaseException], BaseException, TracebackType | None] | tuple[None, None, None] | BaseException)
stack_info (bool)
stacklevel (int)
kwargs (object)
- Return type:
None
- warning(msg, *args, exc_info=None, stack_info=False, stacklevel=1, extra=None, **kwargs)[source]
Delegate a warning call to the underlying logger, merging leftover kwargs into
extra.- Parameters:
msg (object)
args (object)
exc_info (None | bool | tuple[type[BaseException], BaseException, TracebackType | None] | tuple[None, None, None] | BaseException)
stack_info (bool)
stacklevel (int)
kwargs (object)
- Return type:
None
- error(msg, *args, exc_info=None, stack_info=False, stacklevel=1, extra=None, **kwargs)[source]
Delegate an error call to the underlying logger, merging leftover kwargs into
extra.- Parameters:
msg (object)
args (object)
exc_info (None | bool | tuple[type[BaseException], BaseException, TracebackType | None] | tuple[None, None, None] | BaseException)
stack_info (bool)
stacklevel (int)
kwargs (object)
- Return type:
None
- exception(msg, *args, exc_info=True, stack_info=False, stacklevel=1, extra=None, **kwargs)[source]
Call
errorwith exc_info=True.- Parameters:
msg (object)
args (object)
exc_info (None | bool | tuple[type[BaseException], BaseException, TracebackType | None] | tuple[None, None, None] | BaseException)
stack_info (bool)
stacklevel (int)
kwargs (object)
- Return type:
None
- critical(msg, *args, exc_info=None, stack_info=False, stacklevel=1, extra=None, **kwargs)[source]
Delegate a critical call to the underlying logger, merging leftover kwargs into
extra.- Parameters:
msg (object)
args (object)
exc_info (None | bool | tuple[type[BaseException], BaseException, TracebackType | None] | tuple[None, None, None] | BaseException)
stack_info (bool)
stacklevel (int)
kwargs (object)
- Return type:
None
- log(level, msg, *args, exc_info=None, stack_info=False, stacklevel=1, extra=None, **kwargs)[source]
Delegate a log call to the underlying logger, merging leftover kwargs into
extra.- Parameters:
level (int)
msg (object)
args (object)
exc_info (None | bool | tuple[type[BaseException], BaseException, TracebackType | None] | tuple[None, None, None] | BaseException)
stack_info (bool)
stacklevel (int)
kwargs (object)
- Return type:
None
Context
- logstruct.context_scope(**kwargs)[source]
Push variables to the context on enter, restore context on exit.
>>> from logstruct import context_scope, get_context >>> with context_scope(a=11, b=22): ... print(get_context()) ... ... with context_scope(a=222, c=33): ... print(get_context()) ... print(get_context()) {'a': 11, 'b': 22} {'a': 222, 'c': 33, 'b': 22} {'a': 11, 'b': 22}
- logstruct.add_context(**kwargs)[source]
Associate context key-value pairs with the current scope.
If running without a scope, key-value pairs will be associated with the global scope. They will remain there until cleared.
- Parameters:
kwargs (object)
- Return type:
None
- logstruct.remove_context(*keys)[source]
Disassociate keys from the current scope, leaving other scopes unaffected.
- Parameters:
keys (str)
- Return type:
None
Formatting
- class logstruct.StructuredFormatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None, structured_formatter_config=None, **kwargs)[source]
A logging formatter that turns LogRecords into structured data.
- Parameters:
- usesTime()[source]
Check if “asctime” should be assigned to the incoming log record.
Unlike
logging.Formatter.formatTime, which checks if “asctime” is used in the line format string,StructuredFormatterdoesn’t use format strings, soStructuredFormatterConfig.uses_timeis returned.- Return type:
- format(record)[source]
Format the specified record according to the config.
Key-value pairs are discovered in the log record, the context (unless disabled), and the extra dict passed to the log call. They are merged into a single dict with precedence: extras, context, record.
Mostly a clone of
logging.Formatter.formatbut writes structured data. Theself.formatMessage, method, which normally produces a log line prefix, is not called since record attributes are included as data instead. The message itself is still formatted by callingrecord.getMessage()if enabled by the config.The reason for mutating the record is compatibility with
logging.Formatterwhich does the same thing.
- class logstruct.StructuredFormatterConfig(format_message=True, uses_time=True, log_fields=(LogField(source='asctime', dest='time', condition=<class 'bool'>), LogField(source='name', dest='logger', condition=None), LogField(source='levelname', dest='level', condition=None), LogField(source='funcName', dest='func', condition=None), LogField(source='lineno', dest='line', condition=None), LogField(source='message', dest='message', condition=None), LogField(source='exc_text', dest='exc_text', condition=<class 'bool'>), LogField(source='stack_info', dest='stack_info', condition=<class 'bool'>)), get_context_fn=<function get_context>, dumps_fn=functools.partial(<function dumps>, default=<built-in function repr>))[source]
Config struct defining all logstruct-specific
StructuredFormatterconfiguration.It allows to control stdlib conventions:
format_message: whether log message formatting should take placeuses_time: whether current time should be assigned toLogRecord.asctime
It defines the way the structured log message is built:
log_fields: howLogRecordattributes are mapped to produced key-vals.get_context_fn: the function to pull context variables from, which get merged with produced key-vals.dumps_fn: function to serialise produced key-vals into a string
There is no way to prevent
StructuredLogger.logcall keyword args from being merged into the produced key-vals.- Parameters:
- format_message: bool = True
If True, take the message from
record.getMessage()otherwiserecord.msg(unformatted).
- uses_time: bool = True
If True, current time will be assigned to
LogRecord.asctime. Inlogging, this depends on the attached “Formatter style” (e.g.logging.PercentStyle), which isn’t useful in structured logging, and is therefore ignored.
- log_fields: Sequence[LogField] = (LogField(source='asctime', dest='time', condition=<class 'bool'>), LogField(source='name', dest='logger', condition=None), LogField(source='levelname', dest='level', condition=None), LogField(source='funcName', dest='func', condition=None), LogField(source='lineno', dest='line', condition=None), LogField(source='message', dest='message', condition=None), LogField(source='exc_text', dest='exc_text', condition=<class 'bool'>), LogField(source='stack_info', dest='stack_info', condition=<class 'bool'>))
log_fieldsconfigure howlogging.LogRecordattributes map to the produced key-vals.A major difference from structlog is that by default the log message goes to the “message” key rather than “event”.
For example, this configuration:
( LogField("asctime", "time", bool), LogField(lambda log_record: f"{log_record.pathname}:{log_record.lineno}", "loc"), LogField("message", "message"), )
produces logs that look like (excluding formatting):
{ "time": "2025-02-09 19:03:56", "loc": "/path/to/file.py:30", "message": "A message" }
- dumps_fn(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=<built-in function repr>, sort_keys=False, **kw)
By default
dumps_fnisjson.dumps()which will applyrepr()to otherwise unserialisable objects, however any serialiser func can be used.
- class logstruct.LogField(source: str | Callable[[LogRecord], Any] | None, dest: str | None, condition: Callable[[Any], bool] | None = None)[source]
- class logstruct.LogField(*, log_record_attr: str | Callable[[LogRecord], Any], struct_key: str, condition: Callable[[Any], bool] | None = None)
- class logstruct.LogField(source: str | Callable[[LogRecord], Any], *, struct_key: str, condition: Callable[[Any], bool] | None = None)
A mapping of a single
logging.LogRecordattribute or callable to its corresponding output dict key.Warning
log_record_attris deprecated in favour ofsourcestruct_keyis deprecated in favour ofdest
Please use
sourceanddestnames if creating LogFields from kwargs. The deprecated keyword args will remain supported till 1.0.May contain an optional inclusion
condition.- Parameters:
- logstruct.make_friendly_dump_fn(level_key='level', logger_name_key='logger', line_key='line', time_key='time', func_key='func', message_key='message', exc_text_key='exc_text', stack_info_key='stack_info', dumps_fn=functools.partial(<function dumps>, default=<built-in function repr>), colours=False)[source]
Build a function serialising structured data in a developer-friendly way.
Default values for
*_keyparameters correspond to default formatter config.A typical message looks like:
2024-08-07 23:10:06,605 INFO __main__:<module>:35 A message {"key": "val"}
This is not meant to be the only way to serialise logged data in development. Users can supply their own friendly dump function.
- logstruct.CONFIG_FORMATTED_MESSAGE
Default configuration that includes most relevant LogRecord fields in produced “structured”
logs.
logstruct.StructuredFormatterConfig(
format_message=True,
uses_time=True,
log_fields=(
logstruct.LogField(source="asctime", dest="time", condition=bool),
logstruct.LogField(source="name", dest="logger", condition=None),
logstruct.LogField(source="levelname", dest="level", condition=None),
logstruct.LogField(source="funcName", dest="func", condition=None),
logstruct.LogField(source="lineno", dest="line", condition=None),
logstruct.LogField(source="message", dest="message", condition=None),
logstruct.LogField(source="exc_text", dest="exc_text", condition=bool),
logstruct.LogField(source="stack_info", dest="stack_info", condition=bool),
),
get_context_fn=logstruct.get_context,
dumps_fn=functools.partial(json.dumps, default=repr),
)
- logstruct.CONFIG_RAW_MESSAGE
A variant of the default config that preserves the raw message and adds an extra
"positional_args" key.
logstruct.StructuredFormatterConfig(
format_message=False,
uses_time=True,
log_fields=(
logstruct.LogField(source="asctime", dest="time", condition=bool),
logstruct.LogField(source="name", dest="logger", condition=None),
logstruct.LogField(source="levelname", dest="level", condition=None),
logstruct.LogField(source="funcName", dest="func", condition=None),
logstruct.LogField(source="lineno", dest="line", condition=None),
logstruct.LogField(source="message", dest="message", condition=None),
logstruct.LogField(source="exc_text", dest="exc_text", condition=bool),
logstruct.LogField(source="stack_info", dest="stack_info", condition=bool),
logstruct.LogField(source="args", dest="positional_args", condition=bool),
),
get_context_fn=logstruct.get_context,
dumps_fn=functools.partial(json.dumps, default=repr),
)
- logstruct.DEFAULT_DUMPS_FN
functools.partial(json.dumps, default=repr)
- logstruct.DEFAULT_LOG_FIELDS
log_fields used in CONFIG_FORMATTED_MESSAGE.
(
logstruct.LogField(source="asctime", dest="time", condition=bool),
logstruct.LogField(source="name", dest="logger", condition=None),
logstruct.LogField(source="levelname", dest="level", condition=None),
logstruct.LogField(source="funcName", dest="func", condition=None),
logstruct.LogField(source="lineno", dest="line", condition=None),
logstruct.LogField(source="message", dest="message", condition=None),
logstruct.LogField(source="exc_text", dest="exc_text", condition=bool),
logstruct.LogField(source="stack_info", dest="stack_info", condition=bool),
)