Skip to content

Commit 8c72f7a

Browse files
authored
Overview docs (#37)
1 parent 868cdfb commit 8c72f7a

File tree

6 files changed

+431
-0
lines changed

6 files changed

+431
-0
lines changed

docs/index.asciidoc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
include::{asciidoc-dir}/../../shared/versions/stack/current.asciidoc[]
2+
include::{asciidoc-dir}/../../shared/attributes.asciidoc[]
3+
4+
ifdef::env-github[]
5+
NOTE: For the best reading experience,
6+
please view this documentation at https://www.elastic.co/guide/en/ecs-logging/java/current/index.html[elastic.co]
7+
endif::[]
8+
9+
= ECS Logging Reference
10+
11+
ifndef::env-github[]
12+
include::./intro.asciidoc[Introduction]
13+
include::./setup.asciidoc[Set up]
14+
endif::[]

docs/intro.asciidoc

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
[[intro]]
2+
== Introduction
3+
4+
Centralized application logging with the Elastic stack made easy.
5+
6+
[role="screenshot"]
7+
image:https://user-images.githubusercontent.com/2163464/62682932-9cac3600-b9bd-11e9-9cc3-39e907280f8e.png[]
8+
9+
[float]
10+
=== What is ECS?
11+
12+
Elastic Common Schema (ECS) defines a common set of fields for ingesting data into Elasticsearch.
13+
For more information about ECS, visit the {ecs-ref}/ecs-reference.html[ECS Reference Documentation].
14+
15+
[float]
16+
=== What is ECS logging?
17+
18+
ECS loggers are plugins for your favorite logging library.
19+
They make it easy to format your logs into ECS-compatible JSON. For example:
20+
[source,json]
21+
----
22+
{"@timestamp":"2019-08-06T12:09:12.375Z", "log.level": "INFO", "message":"Tomcat started on port(s): 8080 (http) with context path ''", "service.name":"spring-petclinic","process.thread.name":"restartedMain","log.logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer"}
23+
{"@timestamp":"2019-08-06T12:09:12.379Z", "log.level": "INFO", "message":"Started PetClinicApplication in 7.095 seconds (JVM running for 9.082)", "service.name":"spring-petclinic","process.thread.name":"restartedMain","log.logger":"org.springframework.samples.petclinic.PetClinicApplication"}
24+
{"@timestamp":"2019-08-06T14:08:40.199Z", "log.level":"DEBUG", "message":"init find form", "service.name":"spring-petclinic","process.thread.name":"http-nio-8080-exec-8","log.logger":"org.springframework.samples.petclinic.owner.OwnerController","transaction.id":"28b7fb8d5aba51f1","trace.id":"2869b25b5469590610fea49ac04af7da"}
25+
----
26+
27+
[float]
28+
=== Why ECS logging?
29+
30+
*No parsing of the log file required*::
31+
+
32+
--
33+
ECS-compatible JSON doesn't require the use of Logstash or grok parsing via an ingest node pipeline.
34+
--
35+
36+
*Decently human-readable JSON structure*::
37+
+
38+
--
39+
The first three fields are always `@timestamp`, `log.level` and `message`.
40+
It's also possible to format stack traces so that each element is rendered in a new line.
41+
--
42+
43+
*Enjoy the benefits of a common schema*::
44+
+
45+
--
46+
Use the Kibana {observability-guide}/monitor-logs.html[Logs app] without additional configuration.
47+
48+
Using a common schema across different services and teams makes it possible create reusable dashboards and avoids {ref}/mapping.html#mapping-limit-settings[mapping explosions].
49+
--
50+
51+
*APM Log correlation*::
52+
+
53+
--
54+
If you are using an {apm-agents-ref}/index.html[Elastic APM agent],
55+
you can leverage the {apm-get-started-ref}/observability-integrations.html#apm-logging-integration[log correlation feature] without any additional configuration.
56+
This lets you jump from the {kibana-ref}/spans.html[Span timeline in the APM UI] to the {observability-guide}/monitor-logs.html[Logs app],
57+
showing only the logs which belong to the corresponding request.
58+
Vice versa, you can also jump from a log line in the Logs UI to the Span Timeline of the APM UI.
59+
--
60+
61+
*Broad support for languages and loggers*::
62+
+
63+
--
64+
We have loggers for https://github.com/elastic/ecs-dotnet[.NET],
65+
Go (https://github.com/elastic/ecs-logging-go-zap[zap]),
66+
https://www.elastic.co/guide/en/ecs-logging/java/current/intro.html[Java],
67+
https://github.com/elastic/ecs-logging-js[JavaScript],
68+
https://github.com/elastic/ecs-logging-php[PHP],
69+
https://github.com/elastic/ecs-logging-python[Python],
70+
and https://github.com/elastic/ecs-logging-ruby[Ruby].
71+
--
72+
73+
[float]
74+
==== Additional advantages when using in combination with Filebeat
75+
76+
We recommend shipping the logs with Filebeat.
77+
Depending on the way the application is deployed, you may log to a log file or to stdout (for example in Kubernetes).
78+
79+
Here are a few benefits to over directly sending logs from the application to Elasticsearch:
80+
81+
*Resilient in case of outages*::
82+
+
83+
--
84+
{filebeat-ref}/how-filebeat-works.html#at-least-once-delivery[Guaranteed at-least-once delivery]
85+
without buffering within the application, thus no risk of out of memory errors or lost events.
86+
There's also the option to use either the JSON logs or plain-text logs as a fallback.
87+
--
88+
89+
*Loose coupling*::
90+
+
91+
--
92+
The application does not need to know the details of the logging backend (URI, credentials, etc.).
93+
You can also leverage alternative {filebeat-ref}/configuring-output.html[Filebeat outputs],
94+
like Logstash, Kafka or Redis.
95+
--
96+
97+
*Index Lifecycle management*::
98+
+
99+
--
100+
Leverage Filebeat's default {filebeat-ref}/ilm.html[index lifecycle management settings].
101+
This is much more efficient than using daily indices.
102+
--
103+
104+
*Efficient Elasticsearch mappings*::
105+
+
106+
--
107+
Leverage Filebeat's default ECS-compatible {filebeat-ref}/configuration-template.html[index template].
108+
--

docs/setup.asciidoc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[[setup]]
2+
== Get Started
3+
4+
include::./tab-widgets/code.asciidoc[]
5+
6+
[float]
7+
[[setup-step-1]]
8+
=== Step 1: Configure application logging
9+
10+
Refer to the installation instructions of the individual loggers for
11+
https://github.com/elastic/ecs-dotnet#logging[.NET],
12+
Go (https://github.com/elastic/ecs-logging-go-zap[zap]),
13+
https://www.elastic.co/guide/en/ecs-logging/java/current/setup.html[Java],
14+
https://github.com/elastic/ecs-logging-js[JavaScript],
15+
https://github.com/elastic/ecs-logging-php[PHP],
16+
https://github.com/elastic/ecs-logging-python[Python],
17+
and https://github.com/elastic/ecs-logging-ruby[Ruby].
18+
19+
[float]
20+
[[setup-step-2]]
21+
=== Step 2: Enable APM log correlation (optional)
22+
If you are using an Elastic APM agent,
23+
enable {apm-get-started-ref}/observability-integrations.html#apm-logging-integration[log correlation].
24+
25+
[float]
26+
[[setup-step-3]]
27+
=== Step 3: Configure Filebeat
28+
29+
include::./tab-widgets/filebeat-widget.asciidoc[]
30+
31+
For more information, check the {filebeat-ref}/configuring-howto-filebeat.html[Filebeat documentation].
32+

docs/tab-widgets/code.asciidoc

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
// Defining styles and script here for simplicity.
2+
++++
3+
<style>
4+
.tabs {
5+
width: 100%;
6+
}
7+
[role="tablist"] {
8+
margin: 0 0 -0.1em;
9+
overflow: visible;
10+
}
11+
[role="tab"] {
12+
position: relative;
13+
padding: 0.3em 0.5em 0.4em;
14+
border: 1px solid hsl(219, 1%, 72%);
15+
border-radius: 0.2em 0.2em 0 0;
16+
overflow: visible;
17+
font-family: inherit;
18+
font-size: inherit;
19+
background: hsl(220, 20%, 94%);
20+
}
21+
[role="tab"]:hover::before,
22+
[role="tab"]:focus::before,
23+
[role="tab"][aria-selected="true"]::before {
24+
position: absolute;
25+
bottom: 100%;
26+
right: -1px;
27+
left: -1px;
28+
border-radius: 0.2em 0.2em 0 0;
29+
border-top: 3px solid hsl(219, 1%, 72%);
30+
content: '';
31+
}
32+
[role="tab"][aria-selected="true"] {
33+
border-radius: 0;
34+
background: hsl(220, 43%, 99%);
35+
outline: 0;
36+
}
37+
[role="tab"][aria-selected="true"]:not(:focus):not(:hover)::before {
38+
border-top: 5px solid hsl(218, 96%, 48%);
39+
}
40+
[role="tab"][aria-selected="true"]::after {
41+
position: absolute;
42+
z-index: 3;
43+
bottom: -1px;
44+
right: 0;
45+
left: 0;
46+
height: 0.3em;
47+
background: hsl(220, 43%, 99%);
48+
box-shadow: none;
49+
content: '';
50+
}
51+
[role="tab"]:hover,
52+
[role="tab"]:focus,
53+
[role="tab"]:active {
54+
outline: 0;
55+
border-radius: 0;
56+
color: inherit;
57+
}
58+
[role="tab"]:hover::before,
59+
[role="tab"]:focus::before {
60+
border-color: hsl(218, 96%, 48%);
61+
}
62+
[role="tabpanel"] {
63+
position: relative;
64+
z-index: 2;
65+
padding: 1em;
66+
border: 1px solid hsl(219, 1%, 72%);
67+
border-radius: 0 0.2em 0.2em 0.2em;
68+
box-shadow: 0 0 0.2em hsl(219, 1%, 72%);
69+
background: hsl(220, 43%, 99%);
70+
margin-bottom: 1em;
71+
}
72+
[role="tabpanel"] p {
73+
margin: 0;
74+
}
75+
[role="tabpanel"] * + p {
76+
margin-top: 1em;
77+
}
78+
</style>
79+
80+
<script>
81+
window.addEventListener("DOMContentLoaded", () => {
82+
const tabs = document.querySelectorAll('[role="tab"]');
83+
const tabList = document.querySelector('[role="tablist"]');
84+
// Add a click event handler to each tab
85+
tabs.forEach(tab => {
86+
tab.addEventListener("click", changeTabs);
87+
});
88+
// Enable arrow navigation between tabs in the tab list
89+
let tabFocus = 0;
90+
tabList.addEventListener("keydown", e => {
91+
// Move right
92+
if (e.keyCode === 39 || e.keyCode === 37) {
93+
tabs[tabFocus].setAttribute("tabindex", -1);
94+
if (e.keyCode === 39) {
95+
tabFocus++;
96+
// If we're at the end, go to the start
97+
if (tabFocus >= tabs.length) {
98+
tabFocus = 0;
99+
}
100+
// Move left
101+
} else if (e.keyCode === 37) {
102+
tabFocus--;
103+
// If we're at the start, move to the end
104+
if (tabFocus < 0) {
105+
tabFocus = tabs.length - 1;
106+
}
107+
}
108+
tabs[tabFocus].setAttribute("tabindex", 0);
109+
tabs[tabFocus].focus();
110+
}
111+
});
112+
});
113+
114+
function setActiveTab(target) {
115+
const parent = target.parentNode;
116+
const grandparent = parent.parentNode;
117+
// console.log(grandparent);
118+
// Remove all current selected tabs
119+
parent
120+
.querySelectorAll('[aria-selected="true"]')
121+
.forEach(t => t.setAttribute("aria-selected", false));
122+
// Set this tab as selected
123+
target.setAttribute("aria-selected", true);
124+
// Hide all tab panels
125+
grandparent
126+
.querySelectorAll('[role="tabpanel"]')
127+
.forEach(p => p.setAttribute("hidden", true));
128+
// Show the selected panel
129+
grandparent.parentNode
130+
.querySelector(`#${target.getAttribute("aria-controls")}`)
131+
.removeAttribute("hidden");
132+
}
133+
134+
function changeTabs(e) {
135+
// get the containing list of the tab that was just clicked
136+
const tabList = e.target.parentNode;
137+
138+
// get all of the sibling tabs
139+
const buttons = Array.apply(null, tabList.querySelectorAll('button'));
140+
141+
// loop over the siblings to discover which index thje clicked one was
142+
const { index } = buttons.reduce(({ found, index }, button) => {
143+
if (!found && buttons[index] === e.target) {
144+
return { found: true, index };
145+
} else if (!found) {
146+
return { found, index: index + 1 };
147+
} else {
148+
return { found, index };
149+
}
150+
}, { found: false, index: 0 });
151+
152+
// get the tab container
153+
const container = tabList.parentNode;
154+
// read the data-tab-group value from the container, e.g. "os"
155+
const { tabGroup } = container.dataset;
156+
// get a list of all the tab groups that match this value on the page
157+
const groups = document.querySelectorAll('[data-tab-group=' + tabGroup + ']');
158+
159+
// for each of the found tab groups, find the tab button at the previously discovered index and select it for each group
160+
groups.forEach((group) => {
161+
const target = group.querySelectorAll('button')[index];
162+
setActiveTab(target);
163+
});
164+
}
165+
</script>
166+
++++
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
++++
2+
<div class="tabs" data-tab-group="os">
3+
<div role="tablist" aria-label="filebeat">
4+
<button role="tab"
5+
aria-selected="true"
6+
aria-controls="logs-tab-install"
7+
id="logs-install">
8+
Log file
9+
</button>
10+
<button role="tab"
11+
aria-selected="false"
12+
aria-controls="kubernetes-tab-install"
13+
id="kubernetes-install">
14+
Kubernetes
15+
</button>
16+
<button role="tab"
17+
aria-selected="false"
18+
aria-controls="docker-tab-install"
19+
id="docker-install">
20+
Docker
21+
</button>
22+
</div>
23+
<div tabindex="0"
24+
role="tabpanel"
25+
id="logs-tab-install"
26+
aria-labelledby="logs-install">
27+
++++
28+
29+
include::filebeat.asciidoc[tag=logs]
30+
31+
++++
32+
</div>
33+
<div tabindex="0"
34+
role="tabpanel"
35+
id="kubernetes-tab-install"
36+
aria-labelledby="kubernetes-install"
37+
hidden="">
38+
++++
39+
40+
include::filebeat.asciidoc[tag=kubernetes]
41+
42+
++++
43+
</div>
44+
<div tabindex="0"
45+
role="tabpanel"
46+
id="docker-tab-install"
47+
aria-labelledby="docker-install"
48+
hidden="">
49+
++++
50+
51+
include::filebeat.asciidoc[tag=docker]
52+
53+
++++
54+
</div>
55+
</div>
56+
++++

0 commit comments

Comments
 (0)