Glossary
Glossary

What Is Structured Logging?

By Sazabi Team

Last verified on Nov 8, 2026.

Structured logging means writing every log event as a set of named fields instead of a free-text sentence. JSON is the usual format. The payoff is that a tool can answer "show me payment failures over 400 ms for one provider" by filtering on fields, with no regular expression to maintain.

Unstructured Versus Structured

The same event, twice:

2026-11-08 06:44:27 ERROR checkout payment failed for order ord_8123 via stripe after 412 ms
{
  "time": "2026-11-08T06:44:27Z",
  "level": "ERROR",
  "logger": "checkout",
  "message": "payment failed",
  "order_id": "ord_8123",
  "provider": "stripe",
  "duration_ms": 412
}

The first line is easy to read and hard to query. Syslog content is the classic example: NIST notes it has no standard fields, is intended to be human-readable, and so makes automated analysis very challenging when a source uses many formats. The second form is the one a machine can count, group, and chart. You still need log parsing for the text you do not control.

A Python Example

The Python logging cookbook describes serializing events as JSON so they can be parsed "without needing complex regular expressions." This formatter does that and uses the extra argument to carry the fields:

import json
import logging
import sys


class JsonFormatter(logging.Formatter):
    def format(self, record):
        event = {
            "time": self.formatTime(record, "%Y-%m-%dT%H:%M:%S%z"),
            "level": record.levelname,
            "logger": record.name,
            "message": record.getMessage(),
        }
        event.update(getattr(record, "fields", {}))
        if record.exc_info:
            event["exception"] = self.formatException(record.exc_info)
        return json.dumps(event)


handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(JsonFormatter())
log = logging.getLogger("checkout")
log.addHandler(handler)
log.setLevel(logging.INFO)

log.info("payment failed", extra={"fields": {"order_id": "ord_8123", "provider": "stripe", "duration_ms": 412}})

It prints one JSON object per line. For production setups, see the JSON logging guide and the Python logging guide.

Field Rules That Hold Up

  • Record when, where, who, and what for each event. OWASP says application logs must record when, where, who, and what for each event.
  • Keep one event per line, with values escaped by the serializer. OWASP warns that unstructured text is open to log entry injection through CR and LF characters, and recommends JSON instead.
  • Use the same field name for the same thing in every service. user_id in one service and uid in another breaks cross-service search.
  • Include a trace ID so a log line joins its request. See correlation ID for the non-tracing version.
  • Never log secrets. See secrets in logs.
  • Keep log levels as a field of their own, not part of the message text.

The OpenTelemetry Shape

The OpenTelemetry log data model gives structured logs a standard record. It has Timestamp, TraceId, SpanId, SeverityText, SeverityNumber, Body, Resource, and Attributes. Your JSON fields usually become Attributes, and the human message becomes the Body. See the OpenTelemetry logs guide and the OpenTelemetry integration.

Structured Logs in Sazabi

Sazabi, an AI-native observability and security platform, stores incoming records and searches them with full-text search plus structured filtering by attributes, per its storage docs. Fields you log as attributes stay filterable during an investigation. For ideas on what to look for, see field drift detection.

Frequently Asked Questions

What is structured logging in simple terms?

It means each log event is written as named fields, such as level, order_id, and duration_ms, instead of one sentence. Tools can then filter and count by field without parsing text.

Is structured logging the same as JSON logging?

JSON is the most common structured format, but the idea is the fields, not the syntax. Other formats such as logfmt also carry named key-value pairs.

Why does OWASP recommend structured logs?

In plain text formats an attacker can inject carriage return or line feed characters to forge extra log entries. A structured format such as JSON escapes values and keeps each event as one record.

Should I still write a human-readable message?

Yes. Keep a short message field that says what happened, and put the variable details in separate fields so they stay searchable.

Sources

  1. Structured messages can be serialized as JSON so a program can parse them without complex regular expressions (accessed Nov 8, 2026)
  2. OWASP advises structured formats such as JSON because unstructured text is open to CR/LF log entry injection; events should record when, where, who, and what (accessed Nov 8, 2026)
  3. Syslog message content has no standard fields and is human-readable, which makes automated analysis challenging (accessed Nov 8, 2026)
  4. The OpenTelemetry log record has Timestamp, TraceId, SpanId, SeverityText, SeverityNumber, Body, Resource, and Attributes fields (accessed Nov 8, 2026)
  5. The extra argument on logging calls adds custom attributes to the log record (accessed Nov 8, 2026)
  6. Sazabi agent searches stored records with full-text search and structured filtering by attributes (accessed Nov 8, 2026)