Structured JSON logging: design a schema that lasts
Define meaningful fields, preserve data types, and evolve your event schema without breaking downstream readers.
Build structured logging around stable fields, explicit outcomes, and a delivery contract your team can explain.
{
"schema_version": "1.0",
"timestamp": "2026-09-21T09:41:02.184Z",
"severity": "INFO",
"event_id": "evt_demo_001",
"event_name": "request.completed",
"service": "checkout-api",
"attributes": {
"route": "/orders/{id}",
"status_code": 200,
"duration_ms": 42
}
}Keep field names, types, and units stable across producers.
Log approved attributes instead of serializing complete request objects.
Test older events when introducing a new schema version.
Begin with a compact field dictionary and fixtures for success, timeout, rejection, and duplicate delivery. Validate both shape and meaning. A duration represented as a number is useful only when readers know its unit and measurement boundary.
These fields illustrate a design pattern. Map them deliberately to your own schema, source, and destination.
| Field | What it means |
|---|---|
schema_version | The version of your own event contract. |
severity | An approved level—not a business outcome. |
message | A short, safe explanation for human readers. |
attributes | Allowlisted, typed context for this event. |
The examples here use a custom teaching schema. They do not define a hosted ingestion service or an official SDK.
Technical reference: JSON Schema object reference . Verify the version and settings used by your own implementation.
Define meaningful fields, preserve data types, and evolve your event schema without breaking downstream readers.
Understand logging libraries, ingestion endpoints, and query interfaces—and build an event contract that connects them.
Define delivery guarantees, bound your buffers, and make duplicate records and pipeline failures visible.
Start with a clear schema. Keep the context that matters.