Reference: https://www.elastic.co/docs/reference/ecs
ECS is Elastic's open specification for field names and types in logs, metrics and security events. If every source writes the client IP to source.ip rather than src_ip, client_addr or remote, then one query, dashboard or detection rule works across all of them. ECS is also being merged into OpenTelemetry semantic conventions, so the names carry over.
Field sets you'll use most¶
| Field set | Examples | Meaning |
|---|---|---|
| Base | @timestamp, message, tags, labels |
Present on every event |
event.* |
event.kind, event.category, event.action, event.outcome |
What happened |
source.* / destination.* |
.ip, .port, .address, .domain |
Network endpoints |
network.* |
network.transport, network.direction |
Protocol details |
host.* |
host.name, host.hostname, host.ip |
Host the event is about |
observer.* |
observer.hostname, observer.type, observer.ingress.interface.name |
Device that observed the event (firewalls, IDS) |
log.* |
log.level, log.syslog.severity.name, log.syslog.appname |
Logging metadata |
process.* |
process.name, process.pid |
Emitting process |
rule.* |
rule.id, rule.name |
Firewall/IDS rule that matched |
Rules of thumb¶
- Use the ECS field if one fits, even when the name feels awkward.
- Put custom fields under your own namespace (
opnsense.*,labels.*) instead of inventing top-level names. Then a future ECS release can't collide with them. - Keep ECS types:
ipfor addresses,keywordfor identifiers,longfor ports,datefor timestamps. - Recent stack versions ship an
ecs@mappingscomponent template. A custom index template can compose it in instead of re-declaring every field.
Example: OPNsense syslog to ECS¶
| Raw / ad-hoc name | ECS field |
|---|---|
| syslog hostname (the firewall) | observer.hostname |
| program | process.name |
| severity | log.syslog.severity.name |
src_ip / dst_ip |
source.ip / destination.ip |
src_port / dst_port |
source.port / destination.port |
protocol |
network.transport |
interface (igb0, vtnet1) |
observer.ingress.interface.name |
| pass / block | event.action |
These names are used in the ingest pipeline and index template examples.