Skip to content

Commit f9d27f9

Browse files
authored
Merge pull request #18 from elastic/spec
[DISCUSS] Draft of Spec
2 parents 7bb4345 + 9db2d40 commit f9d27f9

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

spec/README.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Specification
2+
3+
The specification aims to keep uniformity accross the libraries and to provide a human digestible output while producing a structured format.
4+
5+
The ordering of the next three keys must be respected in every ecs-logging library:
6+
7+
1. `@timestamp`, base field
8+
2. `log.level`, log field
9+
3. `message`, base field
10+
11+
With the fourth key, `ecs.version` ([core](https://www.elastic.co/guide/en/ecs/current/ecs-ecs.html) field) in the [ND-JSON](https://github.com/ndjson/ndjson-spec) output, we define the *minimum viable product* (MVP) for a log line.
12+
`ecs.version` must be present in case of appenders that are not adding the `ecs.version` automatically.
13+
14+
All other keys are not subjected to an order until decided differently and can hence be appended to the event.
15+
16+
## Examples
17+
18+
### Minimum Viable Product
19+
20+
The following example highlights the minimum set of keys in a ND-JSON output.
21+
22+
```json
23+
{
24+
"@timestamp": "2016-05-23T08:05:34.853Z",
25+
"log.level": "NOTICE",
26+
"message": "Hi, I am the spec for the ECS logging libraries.",
27+
"ecs.version": "1.4.0"
28+
}
29+
```
30+
31+
### A richer Event Context
32+
33+
The following example describes a richer set of fields in an event that has not an error context (see [here](#example-error-event)). The mapping can of the example is taken from `ecs-logging-java` and can be found [here](https://github.com/elastic/ecs-logging-java#mapping).
34+
35+
36+
```json
37+
{
38+
"@timestamp": "2016-05-23T08:05:36.789Z",
39+
"log.level": "NOTICE",
40+
"message": "This is an event with a more elaborate context",
41+
"ecs.version": "1.4.0",
42+
"log": {
43+
"logger": "MyLogger",
44+
"origin": {
45+
"file": {
46+
"name": "App.java",
47+
"line": 42,
48+
},
49+
"function": "methodName"
50+
}
51+
},
52+
"process": {
53+
"thread": {
54+
"name": "my-thread-name-001"
55+
}
56+
},
57+
"labels": {
58+
"app_version": "1.0.42",
59+
"app_region": "europe-02",
60+
"app_uptime": "2016-05-15T14:03:12.345Z"
61+
},
62+
"tags": ["production", "env001"],
63+
}
64+
```
65+
66+
### [Error Event with richer Context](#example-error-event)
67+
68+
This example adds the [error](https://www.elastic.co/guide/en/ecs/current/ecs-error.html) fields to the event.
69+
70+
```json
71+
{
72+
"@timestamp": "2016-05-23T08:05:37.123Z",
73+
"log.level": "ERROR",
74+
"message": "An error happened!",
75+
"ecs.version": "1.4.0",
76+
"log": {
77+
"logger": "MyLogger",
78+
"origin": {
79+
"file": {
80+
"name": "App.java",
81+
"line": 42,
82+
},
83+
"function": "methodName"
84+
}
85+
},
86+
"process": {
87+
"thread": {
88+
"name": "my-thread-name-042"
89+
}
90+
},
91+
"error": {
92+
"type": "java.lang.NullPointerException",
93+
"message": "The argument cannot be null"
94+
},
95+
"labels": {
96+
"app_version": "1.0.42",
97+
"app_region": "europe-02",
98+
"app_uptime": "2016-05-15T14:03:12.345Z"
99+
},
100+
"tags": ["production", "env042"],
101+
}
102+
```
103+
104+
## De-Dot'ing/Sanitize of Keys in Labels
105+
All keys in `labels` must not contain `.`, `*` and `\`; as Elasticsearch will handle theses keys as nested and that violates the purpose `labels` ([ref](https://www.elastic.co/guide/en/ecs/current/ecs-base.html)).
106+
The substitution character must be `_`, yielding a [snake cased](https://en.wikipedia.org/wiki/Snake_case) string.
107+
108+
## References
109+
* [ECS base fields](https://www.elastic.co/guide/en/ecs/current/ecs-base.html)
110+
* [ECS log fields](https://www.elastic.co/guide/en/ecs/current/ecs-log.html)

spec/spec.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"version": 1.0,
3+
"url": "https://www.elastic.co/guide/en/ecs/current/index.html",
4+
"ecs": {
5+
"version": "1.x"
6+
},
7+
"fields": {
8+
"@timestamp": {
9+
"type": "datetime",
10+
"required": true,
11+
"index": 0,
12+
"url": "https://www.elastic.co/guide/en/ecs/current/ecs-base.html"
13+
},
14+
"log.level": {
15+
"type": "string",
16+
"required": true,
17+
"index": 1,
18+
"url": "https://www.elastic.co/guide/en/ecs/current/ecs-log.html"
19+
},
20+
"message": {
21+
"type": "string",
22+
"required": true,
23+
"index": 2,
24+
"url": "https://www.elastic.co/guide/en/ecs/current/ecs-base.html"
25+
},
26+
"ecs.version": {
27+
"type": "string",
28+
"required": true,
29+
"url": "https://www.elastic.co/guide/en/ecs/current/ecs-ecs.html"
30+
},
31+
"labels": {
32+
"type": "object",
33+
"required": false,
34+
"url": "https://www.elastic.co/guide/en/ecs/current/ecs-base.html",
35+
"sanitization": {
36+
"key": {
37+
"replacements": [".", "*", "\\"],
38+
"substitute": "_"
39+
}
40+
}
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)