Structured logging is the practice of treating application logs as first-class, typed data rather than arbitrary strings. In modern distributed systems, narrative logs (plain text) are technical debt; they require expensive, brittle regex parsing at search time and fail to provide the correlation required for complex debugging.
The industry standard for structured logging is JSON Lines (JSONL). Each log event is a self-contained JSON object on a single line. This format allows for efficient stream processing by tools like Vector, Fluentd, or Logstash without the need for multi-line buffering.
Ad-hoc JSON logging leads to "field sprawl" where different services use user_id, uid, and user.id for the same entity. To solve this, organizations must adopt a standardized schema like the Elastic Common Schema (ECS).
Example ECS-compliant log entry:
{
"@timestamp": "2024-05-16T14:30:15.123Z",
"log.level": "error",
"message": "database connection timeout",
"service.name": "order-service",
"event.dataset": "db.pool",
"user.id": "u_99823",
"trace.id": "5318625901235",
"db.instance": "postgres-primary",
"error.code": "ETIMEDOUT"
}
High-cardinality attributes—fields with a vast number of unique values such as request_id, session_token, or user_id—pose a significant challenge for log storage engines.
In engines like Elasticsearch or OpenSearch, every unique field name creates a mapping entry. If an application logs dynamic keys (e.g., {"metadata_key_123": "value"}), it can trigger a Mapping Explosion, crashing the cluster's master node.
Mandate: Always use a stable set of keys. Use a nested labels or tags object for user-defined metadata to prevent top-level field sprawl.
For high-cardinality identifiers, the choice of index type is critical:
index: false for raw payloads that are only needed for display in the UI but never for filtering.Logs arriving from the application boundary often require transformation before they are searchable.
Deeply nested JSON structures can be difficult to query. Pipelines should flatten critical fields to a predictable depth.
{"error": {"context": {"id": 123}}}error.context.id: 123The pipeline (e.g., Logstash or Vector) should enrich logs with data the application may not have:
geo.country_name based on a client.ip field.host.environment (prod/staging) or host.owner based on the hostname.trace.id. This is the single most important factor in multi-service debugging.Structured logging transforms logs from a cost center (storage only) into a strategic asset for real-time analytics and incident response.