Payload processing
This page documents payload processing APIs.
Payload processing is split into two layers:
base abstractions
protocols that define what payload processing means
default implementation
the built-in processor and its configuration types
The base abstractions are independent from the default implementation. The default implementation uses them, but they are not the same API layer.
Base abstractions
The base payload-processing API contains two protocols:
LogPayloadProcessorProto
LogPayloadProvider
LogPayloadProcessorProto defines what a payload processor must provide.
LogPayloadProvider lets an object provide its own structured logging representation.
- class mvx.common.logger.LogPayloadProcessorProto(*args, **kwargs)
Protocol for payload processors.
A payload processor converts arbitrary payload values into log-ready structured data.
- normalize_payload(payload, *, unbounded=False)
Normalize a structured payload for logging.
- Parameters:
payload (
Mapping[str,Any]) – payload mapping to normalize.unbounded (
bool) – whether item-count limiting should be disabled while normalizing this payload.
- Return type:
dict[str,Any]- Returns:
normalized payload dictionary.
- normalize_value_for_log(value, *, unbounded=False)
Normalize a single value for inclusion in a log payload.
- Parameters:
value (
Any) – value to normalize.unbounded (
bool) – whether item-count limiting should be disabled for this value.
- Return type:
str|int|float|bool|bytes|dict[str,Any] |list[Any] |None- Returns:
normalized log-ready value.
- get_plain_verbosity_level()
Return the current verbosity level as a plain string.
This method is used by components such as log_invocation to evaluate verbosity-gated field specifications.
- Return type:
str|None- Returns:
plain verbosity level, or None if no verbosity level is available.
- class mvx.common.logger.LogPayloadProvider(*args, **kwargs)
Protocol for objects that provide their own logging payload.
When an object implements this protocol, its to_log_payload() result is used as the object’s logging representation.
The returned payload is expected to be log-ready. Implementers are responsible for keeping it reasonably sized and free of sensitive data.
This protocol takes precedence over type-based log adapters.
- to_log_payload()
Return this object’s structured logging payload.
- Return type:
dict[str,Any]- Returns:
log-ready payload dictionary.
Processor protocol
LogPayloadProcessorProto is the contract used by LogContext and logging components.
A processor must be able to normalize:
complete payload mappings
single values
It also exposes the current verbosity level as a plain string. Components such as log_invocation use that string for verbosity-gated field specifications.
The protocol does not require a specific implementation strategy. A custom processor may use any normalization rules as long as it returns log-ready values compatible with the protocol.
Payload provider protocol
LogPayloadProvider is an object-level escape hatch.
When an object implements this protocol, its to_log_payload() result is used as the object’s logging representation.
The returned payload is expected to be log-ready. The object that implements the protocol is responsible for keeping the payload reasonably sized and free of sensitive data.
In the default implementation, LogPayloadProvider takes precedence over type-based log adapters.
Default implementation
LogPayloadProcessor is the built-in payload processor.
It provides conservative default normalization for common Python values and extension points for domain objects.
- class mvx.common.logger.LogPayloadProcessor(*, verbosity_level=None, max_str_len=None, max_items=None, log_adapter_resolver=None)
Default implementation of payload normalization.
LogPayloadProcessor converts payload mappings and individual values into log-ready structured data.
The processor supports configurable verbosity, string length limiting, collection item limiting, explicit LogPayloadProvider objects, and optional type-based log adapters.
Create the default payload processor.
- Parameters:
verbosity_level (
LogVerbosityLevel|None) – optional verbosity level. If omitted, NORMAL is used.max_str_len (
int|None) – optional maximum string length. If omitted, DEFAULT_MAX_STR_LEN is used.max_items (
int|None) – optional maximum number of mapping or sequence items. If omitted, DEFAULT_MAX_ITEMS is used.log_adapter_resolver (
Optional[Callable[[Any],Optional[Callable[[Any,LogVerbosityLevel],dict[str,Any]]]]]) – optional callable used to resolve type-based log adapters.
- Raises:
TypeError – if an argument has an invalid type.
ValueError – if max_str_len or max_items is less than 1.
- property verbosity_level: LogVerbosityLevel
Return the effective verbosity level.
If no local verbosity level was configured, returns LogVerbosityLevel.NORMAL.
- Returns:
effective verbosity level.
- set_verbosity_level(verbosity_level)
Set the local verbosity level.
- Parameters:
verbosity_level (
LogVerbosityLevel) – verbosity level to use.- Return type:
None- Returns:
None.
- Raises:
TypeError – if verbosity_level is not a LogVerbosityLevel.
- reset_verbosity_level()
Reset the local verbosity level.
After reset, the processor uses LogVerbosityLevel.NORMAL.
- Return type:
None- Returns:
None.
- property max_str_len: int
Return the effective maximum string length.
If no local value was configured, returns DEFAULT_MAX_STR_LEN.
- Returns:
effective maximum string length.
- set_max_str_len(max_str_len)
Set the local maximum string length.
- Parameters:
max_str_len (
int) – maximum string length to use.- Return type:
None- Returns:
None.
- Raises:
TypeError – if max_str_len is not an integer.
ValueError – if max_str_len is less than 1.
- reset_max_str_len()
Reset the local maximum string length.
After reset, the processor uses DEFAULT_MAX_STR_LEN.
- Return type:
None- Returns:
None.
- property max_items: int
Return the effective maximum number of mapping or sequence items.
If no local value was configured, returns DEFAULT_MAX_ITEMS.
- Returns:
effective maximum item count.
- set_max_items(max_items)
Set the local maximum number of mapping or sequence items.
- Parameters:
max_items (
int) – maximum item count to use.- Return type:
None- Returns:
None.
- Raises:
TypeError – if max_items is not an integer.
ValueError – if max_items is less than 1.
- reset_max_items()
Reset the local maximum number of mapping or sequence items.
After reset, the processor uses DEFAULT_MAX_ITEMS.
- Return type:
None- Returns:
None.
- property log_adapter_resolver: Callable[[Any], Callable[[Any, LogVerbosityLevel], dict[str, Any]] | None] | None
Return the configured log adapter resolver.
- Returns:
log adapter resolver, or None if no resolver is configured.
- set_log_adapter_resolver(log_adapter_resolver)
Set the log adapter resolver.
- Parameters:
log_adapter_resolver (
Callable[[Any],Optional[Callable[[Any,LogVerbosityLevel],dict[str,Any]]]]) – callable used to resolve log adapters for custom values.- Return type:
None- Returns:
None.
- Raises:
TypeError – if log_adapter_resolver is not callable.
- reset_log_adapter_resolver()
Reset the log adapter resolver.
After reset, no type-based log adapter resolver is used.
- Return type:
None- Returns:
None.
- normalize_payload(payload, *, unbounded=False)
Normalize a structured payload mapping.
Mapping keys are converted to strings. Mapping values are normalized as individual log values. Item-count limiting is applied unless unbounded is True.
- Parameters:
payload (
Mapping[str,Any]) – payload mapping to normalize.unbounded (
bool) – whether item-count limiting should be disabled for this payload.
- Return type:
dict[str,Any]- Returns:
normalized payload dictionary.
- normalize_value_for_log(value, *, unbounded=False)
Normalize a single value for inclusion in a log payload.
The processor handles primitives, bytes-like values, enums, mappings, sequences, objects implementing LogPayloadProvider, and values supported by the configured log adapter resolver. Unsupported objects are represented by their type name.
- Parameters:
value (
Any) – value to normalize.unbounded (
bool) – whether item-count limiting should be disabled for this value.
- Return type:
str|int|float|bool|bytes|dict[str,Any] |list[Any] |None- Returns:
normalized log-ready value.
- get_plain_verbosity_level()
Return the effective verbosity level as a plain string.
This method is used by components that need string-based verbosity checks, such as verbosity-gated field specs in log_invocation.
- Return type:
str|None- Returns:
effective verbosity level name.
Default implementation behavior
The default processor normalizes values using a bounded, log-oriented representation.
It handles:
strings
bytes-like values
integers
floats
booleans
None
enums
mappings
lists and tuples
objects implementing LogPayloadProvider
objects handled by a configured log adapter
unsupported objects
Unsupported objects are represented by their type name.
For mappings, keys are converted to strings and values are normalized individually.
For lists and tuples, items are normalized individually.
String length and collection size are limited by the processor configuration unless item limiting is explicitly disabled for a normalization call.
Verbosity levels
LogVerbosityLevel is part of the default implementation.
It is not required by the base LogPayloadProcessorProto contract, but the built-in processor uses it as its verbosity setting.
- enum mvx.common.logger.LogVerbosityLevel(value)
Verbosity levels used by the default payload processor.
The level controls how much detail the default processor and related helpers may include when converting values to log payloads.
- Member Type:
str
Valid values are as follows:
- MINIMAL = <LogVerbosityLevel.MINIMAL: 'MINIMAL'>
Minimal payload detail.
- NORMAL = <LogVerbosityLevel.NORMAL: 'NORMAL'>
Default payload detail.
- MAXIMUM = <LogVerbosityLevel.MAXIMUM: 'MAXIMUM'>
Maximum payload detail.
Default limits
The default processor uses two built-in limits when no local values are configured.
DEFAULT_MAX_STR_LEN = 200
default maximum string length
DEFAULT_MAX_ITEMS = 10
default maximum number of mapping or sequence items
These constants belong to the default implementation.
Adapter types
The default processor can use type-based log adapters.
LogAdapter is the callable type used to convert a custom object into a log-ready payload dictionary.
LogAdapter = Callable[[Any, LogVerbosityLevel], dict[str, Any]]
The callable receives the value being normalized and the current verbosity level.
LogAdapterResolver is the callable type used to resolve an adapter for a value.
LogAdapterResolver = Callable[[Any], LogAdapter | None]
The resolver receives the value being normalized and returns an adapter for that value, or None if no adapter is available.
These aliases belong to the default implementation. They are not part of the base processor protocol.
Custom object normalization order
The default processor tries custom normalization before falling back to generic normalization.
The order is:
1. LogPayloadProvider.to_log_payload()
2. configured LogAdapterResolver and returned LogAdapter
3. built-in normalization rules
If a LogPayloadProvider returns a dictionary, that dictionary is used.
If provider handling fails or does not return a dictionary, the processor falls back to the next option.
If a resolver is configured and returns an adapter, the adapter is called with the value and the current verbosity level.
If adapter handling fails or does not return a dictionary, the processor falls back to built-in normalization rules.
Bounded normalization
The default processor limits output size by default.
max_str_len limits long strings and mapping keys.
max_items limits mapping entries and sequence items.
If a collection has more items than the effective limit, the processor adds a marker showing that more data exists.
The unbounded argument disables item-count limiting for that normalization call. It does not disable string length limiting.