Standardized logging context, observation, masking and Kafka schema events for Mobius Python (FastAPI) services.
Project description
Mobius Logging for Python
Python port of the Java Mobius logging library. It standardizes logging context
for Mobius FastAPI / Starlette services: a contextvars-based context store
(the analog of SLF4J MDC), a request middleware, an @observed method
decorator, sensitive-data masking, OpenTelemetry trace sync, JSON logging, and
a Kafka schema-event producer.
The Kafka topic, schema id and tenant id come with preconfigured defaults
(overridable in setup_logging), so events from Python services land in the
same pipeline as the rest of the platform.
Requires Python 3.10+.
Install
pip install mobius-logging-py
# or directly from git
pip install "mobius-logging-py @ git+https://<your-git-host>/mobius-logging-py.git@v1.0.0"
The import package is mobius_logging (e.g. from mobius_logging import setup_logging).
Optional extras: mobius-logging-py[otel] (OpenTelemetry trace sync),
mobius-logging-py[fastapi] (Starlette middleware).
Quick start
from fastapi import FastAPI
from mobius_logging import setup_logging, observed, LogType
from py_kafka_producer_client import Producer # your internal client
app = FastAPI()
setup_logging(
app,
service_name="orders-service",
profile="prod", # json logs for staging/prod/production
sensitive_keys=["session_id", "refresh_token"],
kafka_producer=Producer(...), # wrapped in PyKafkaProducerClientSender
)
@app.post("/orders")
@observed(event_type="order.create", log_type=LogType.AUDIT, resource_type="order")
async def create_order(order_id: str):
...
setup_logging is the one-call equivalent of Java's Spring auto-configuration
(Python has no auto-config, so wiring is explicit). It configures logging,
registers custom sensitive keys, builds the schema producer, and adds the
request middleware.
Java → Python mapping
| Java Mobius logging library | Python (mobius_logging) |
|---|---|
SLF4J MDC |
contextvars.ContextVar (context.py) |
PlatformLogContext |
mobius_logging.context functions |
PlatformLogFields |
mobius_logging.fields |
LogType enum |
LogType enum |
PlatformLoggingFilter (servlet) |
PlatformLoggingMiddleware (ASGI) |
@PlatformObserved + AOP aspect |
@observed decorator |
KafkaLogProducer (KafkaTemplate) |
KafkaLogProducer + LogEventSender |
PlatformKafka*Context |
producer_headers / apply_consumer_record |
SensitiveDataMasker |
mobius_logging.masking |
LogbackConfigurator |
configure_platform_logging |
| Spring auto-config classes | setup_logging (explicit) |
Out of scope for v1 (present in Java): JDBC/JPA, MongoDB, and Camunda logging.
Context API
from mobius_logging import context, LogType
context.init() # sets schema_version
context.tenant_id("tenant-123")
context.log_type(LogType.AUDIT)
context.resource_type("order")
context.resource_id("order-789")
context.field("custom_key", "value")
context.ensure_correlation_id() # generates one if missing
context.sync_trace_from_opentelemetry()
snap = context.snapshot()
try:
context.put("event_type", "order.approved")
finally:
context.restore(snap)
Note: Java's
ensureCorrelationId()has an inverted condition and only regenerates when one already exists. This port fixes that — it generates a correlation id when none is present.
@observed
Works on sync and async functions. Adds log_type, event_type,
resource_type, class_name, method_name, outcome, method_duration_ms,
and exception_type/exception_message on failure. After completion it ships
the context to the schema producer (if one is registered), then restores the
pre-call context snapshot (Java clears MDC instead).
@observed(event_type="order.create", resource_type="order")
def create_order(order_id: str): ...
Kafka
Schema event producer
The producer depends only on a small protocol, so the library has no hard Kafka
dependency. It matches the py-kafka-producer-client (>=0.1.7) signature — the
event is a dict and topic is keyword-only:
class LogEventSender(Protocol):
def send(self, value: dict, *, topic: str) -> Any: ...
For the internal py-kafka-producer-client, pass the client to
setup_logging(kafka_producer=...) or wrap it directly:
from mobius_logging import KafkaLogProducer, PyKafkaProducerClientSender, set_log_producer
producer = KafkaLogProducer(PyKafkaProducerClientSender(client), "orders-service")
set_log_producer(producer)
PyKafkaProducerClientSender calls client.send(value, topic=...), passing the
DataIngestionOperation envelope as a dict (the client serializes it). To use a
different client, pass any object exposing send(value, *, topic) as
kafka_sender=.
Sending runs on a background thread pool (best-effort, never raises, never
blocks the request) — the analog of the Java @Async method.
Context propagation
from mobius_logging import producer_headers, apply_consumer_record
# producer side
client.send(topic, value, headers=producer_headers())
# consumer side
apply_consumer_record(record.headers(), topic=record.topic(),
partition=record.partition(), offset=record.offset())
Propagated header fields: trace_id, span_id, correlation_id,
causation_id, tenant_id. Consumer also sets kafka_topic,
kafka_partition, kafka_offset.
Logging output
configure_platform_logging(service_name, profile) installs a root handler that
injects the current context onto every record. Profiles staging/prod/
production emit JSON; others use a readable text pattern. A daily-rotating
file handler writes to logs/<service>.log (30 days retained).
In JSON mode every context field is included automatically. For the text
pattern, txn_id, tenant_id, and trace_id are surfaced inline.
Sensitive data masking
from mobius_logging import mask, mask_map, init_custom_keys
init_custom_keys(["session_id", "refresh_token"])
mask("authorization", token) # masked
mask_map(context.copy()) # masks all sensitive keys in a dict
Default sensitive keys: password, token, secret, authorization,
cookie, apikey, privatekey, kubeconfig. Matching is case-insensitive.
Masking keeps the last 4 characters of generic values and partially masks
emails — identical behaviour to the Java masker.
Development
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mobius_logging_py-1.0.2.tar.gz.
File metadata
- Download URL: mobius_logging_py-1.0.2.tar.gz
- Upload date:
- Size: 19.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b12a8667613f1042fa41da7a99ce983faf0457b183b0501c95c9ce1c71e0fc3d
|
|
| MD5 |
e46ed6418df3a1cb88cce99a47f9652a
|
|
| BLAKE2b-256 |
a52697602d7ce5479cc30e569623f8aa68de814dcd2b12c55a73d9052eab0197
|
File details
Details for the file mobius_logging_py-1.0.2-py3-none-any.whl.
File metadata
- Download URL: mobius_logging_py-1.0.2-py3-none-any.whl
- Upload date:
- Size: 19.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f366162edda750201dd3f49dbebc8ec697f680fcc59bc5f6e488d907a3fc937
|
|
| MD5 |
e19e84c1087d3087314fa4e950be3ad9
|
|
| BLAKE2b-256 |
5b3a981bae57206bbeb51a69bf4ca6251274454000a2c177301316345b3fc740
|