Compare the three built-in structured logging formats in Spring Boot 3.4 (ecs, logstash, gelf). When would you pick each?
answer
- ecs=Elastic dotted fields, log.level/service.name
- logstash=flat @timestamp/@version/level, old encoder shape
- gelf=Graylog, epoch-seconds ts + numeric level + _ fields
- match the sink's native schema
- per-format service metadata properties
basics
~20 secs = Elastic Common Schema (for Elasticsearch/Kibana), logstash = the Logstash JSON layout, gelf = Graylog Extended Log Format (for Graylog). Pick the one your log backend understands natively so fields map without extra transformation.
solid answer
~40 sBoot 3.4 ships three format values. **`ecs`** emits Elastic Common Schema JSON — dotted field names like `@timestamp`, `log.level`, `log.logger`, `service.name`, `error.stack_trace` — ideal when your sink is Elasticsearch/Kibana or anything ECS-aware. **`logstash`** emits the Logstash JSON event format (`@timestamp`, `@version`, `level`, `logger_name`, `stack_trace`, MDC flattened to top level), matching the long-standing logstash-logback-encoder shape for existing Logstash/ELK pipelines. **`gelf`** emits Graylog Extended Log Format (`version`, `host`, `short_message`, `timestamp` as epoch seconds, numeric `level` mapped to syslog severity, `_`-prefixed custom fields), for Graylog. The choice is driven purely by which schema your aggregation backend indexes natively: matching it avoids reprocessing/field-remapping in the pipeline. Each format also exposes service-metadata properties (e.g. `logging.structured.ecs.service.name`, `logging.structured.gelf.host`).
go deeper
Just name the three: ecs, logstash, gelf, and that each targets a specific backend.
Know the field-naming and timestamp/level differences and the match-your-sink rule.
Discuss dashboard/query coupling to field names and service-metadata mapping per format.
Weigh format-at-source vs normalize-at-collector (OTel/Vector) tradeoffs across a fleet.
Spring Boot 3.4 defines three named structured formats. They differ in field names, timestamp representation, and how they encode severity and metadata — each mirrors a specific downstream ecosystem's conventions. **`ecs` — Elastic Common Schema.** ECS is Elastic's cross-source field naming standard. Output uses dotted, namespaced keys: `@timestamp` (ISO-8601), `log.level`, `log.logger`, `process.thread.name`, `message`, `ecs.version`, and for exceptions `error.type` / `error.message` / `error.stack_trace`. Service metadata maps to `service.name`, `service.version`, `service.environment`, `service.node.name`. Choose ECS when logs land in Elasticsearch/Kibana (or OpenSearch, Elastic Cloud) — fields index straight into ECS dashboards with no remapping. Configure via `logging.structured.ecs.service.name`, `.version`, `.environment`, `.node-name`. **`logstash` — Logstash JSON event format.** This matches the format historically produced by the `logstash-logback-encoder` `LogstashEncoder`. Keys are flat: `@timestamp`, `@version`, `message`, `logger_name`, `thread_name`, `level`, `level_value`, and `stack_trace` for exceptions. MDC entries and structured key-values are promoted to top-level fields. Choose it when you already run a Logstash/ELK pipeline expecting this shape, or to drop-in-replace the old encoder without changing downstream Logstash filters. **`gelf` — Graylog Extended Log Format.** GELF is Graylog's native format. Output includes `version` ("1.1"), `host`, `short_message`, `full_message` (for stack traces), `timestamp` as a Unix epoch **in seconds** (with millisecond fraction), and `level` as a **numeric syslog severity** (not the word INFO). Custom/MDC fields are emitted with a leading underscore (`_traceId`, etc.) per the GELF spec. Choose it when shipping to Graylog. Configure via `logging.structured.gelf.host` and `logging.structured.gelf.service.version`. **Key practical differences to remember:** - **Timestamp:** ECS and Logstash use ISO-8601 strings; GELF uses epoch seconds. - **Level encoding:** ECS/Logstash keep the word (`INFO`); GELF uses a numeric syslog level. - **Field naming:** ECS is dotted/namespaced; Logstash is flat; GELF prefixes custom fields with `_`. - **Stack traces:** ECS `error.stack_trace`, Logstash `stack_trace`, GELF `full_message`. **Decision rule:** don't pick on aesthetics — pick the schema your sink understands natively. Elasticsearch/Kibana → `ecs`; existing Logstash filters → `logstash`; Graylog → `gelf`. If your collector normalizes anyway (Vector, OTel Collector), any is fine, but matching still reduces transform config. If none fit, implement a custom `StructuredLogFormatter`. **Gotcha:** switching formats changes field *names*, so any Kibana/Grafana dashboards or alert queries keyed on specific fields (e.g. `level` vs `log.level`) will break — treat the format as a contract with your dashboards.
- Why does the GELF format encode the level as a number while ECS keeps 'INFO'?GELF follows the Graylog spec, which uses numeric syslog severity levels (0-7). ECS follows Elastic Common Schema, which stores the textual `log.level`. It's a schema convention, not a Boot choice.
- How do you attach a service name and version to the emitted records?Use the format-specific metadata properties, e.g. `logging.structured.ecs.service.name`/`.version`/`.environment`/`.node-name`, or `logging.structured.gelf.host`/`.service.version`. They map to that format's service fields.
saying these in an interview costs you the question
- Saying all three formats produce identical field names
- Thinking GELF uses ISO-8601 timestamps (it uses epoch seconds)
- Believing you can freely switch formats without breaking dashboards keyed on field names
- Claiming the format choice affects application code (it never does)