Skip to content

Commit de8d5f1

Browse files
authored
El-shippy-article-update (#67)
* intro update * article completed * grammarlied
1 parent 2210d55 commit de8d5f1

File tree

1 file changed

+43
-11
lines changed

1 file changed

+43
-11
lines changed

observe/examples/el-shippy/article.md

+43-11
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ status: complete
55

66
# Advanced Docker Logs with Filebeat and Elasticsearch
77

8-
Elastic stack is one of the most robust observability systems out there. Application logs are most likely to be handled by docker. The most intuitive way to connect them I've found is Filebeat. So in this article, we will try to fire up a complete stack, that allows the export of logs from docker to elasticsearch in a manner that will lay a simple yet powerful foundation of an observability solution. So, start the beat!
8+
If we want to track what is going on in a system we will probably start by connecting application logs to an observability stack. Our application logs most likely already reside in docker and if we aim for the most robust technology we'll probably go with elastic stack. The challenge then is to connect those two. I suggest we'll use Filebeat for that.
9+
10+
So in this article, we will fire up a complete stack, exporting logs from docker to elasticsearch, building a simple yet powerful foundation of an observability solution. So, start the beat!
911

1012
![AI-generated log-lover ready to play a beat](thumb.png)
1113

1214
## Firing up the foundations
1315

14-
Deploying and connecting all the basic components is a twisted task even in the most basic setup. Therefore, in my [previous article]() I've talked in depth about the basic setup. This time we'll start from what we got there. If something in the setup wouldn't make sense, feel free to refer to the [old piece](). Anyway, here's the initial setup we got:
16+
We'll start with a basic setup, firing up `elasticsearch`, `kibana`, and `filebeat`, configured in a separate file `filebeat.yml`. Check the configuration below and if something doesn't make sense please refer to [the previous article](https://medium.com/p/ebe75fd13041), explaining the basics. I'll meet you here.
1517

1618
`compose.yaml`
1719

@@ -38,7 +40,7 @@ services:
3840
- /var/run/docker.sock:/var/run/docker.sock
3941
```
4042
41-
`filebeat.yaml`
43+
`filebeat.yml`
4244

4345
```yaml
4446
filebeat.inputs:
@@ -56,7 +58,7 @@ output.elasticsearch:
5658
- index: "docker-logs"
5759
```
5860

59-
Which produces logs looking something like this:
61+
This setup produces logs looking something like this:
6062

6163
```json
6264
{
@@ -151,7 +153,7 @@ Which produces logs looking something like this:
151153

152154
## Indexing the logs right
153155

154-
There are a few unsatisfying things about the current log. First of all, logs from all containers end up in a single elasticsearch "index" - which is roughly analogous to a table in a relational database. This prevents us from using an index pattern for really anything useful. Let's fix this! Here are some ideas of what we may want to know from the index names:
156+
There are a few unsatisfying things about the log above. First of all, logs from all containers end up in a single elasticsearch "index" - which is roughly analogous to a table in a relational database. This prevents us from using indexes for really anything useful. Let's fix this! Here are some ideas of what we may want to know from the index names:
155157

156158
- **Service that produced the log**. So that we can see logs produced by a particular service. `container.name` seems to suit the purpose the best. It does append an instance index (`-1`), but we just need to keep that in mind when creating an index pattern.
157159
- **Type/Family of service that produced the log**. Let's say we have a few services that produce similar logs e.g. HTTP API services. If we want to get a holistic view of their performance we would need to be able to filter them by some common index pattern. We can use docker labels to identify such services. Let's call the label `family`
@@ -186,9 +188,9 @@ Let's also give a family to just one of our containers. Let's for example give `
186188
- 5601:5601
187189
```
188190

189-
With that, we'll be able to see all `ui` family logs using `docker-logs-ui-*` pattern, all `elasticsearch` service logs using `*-elasticsearch-*`, and so on.
191+
With that, we'll be able to see all `ui` family logs using `docker-logs-ui-*` index pattern, all `elasticsearch` service logs using `*-elasticsearch-*`, and so on.
190192

191-
## Getting the important stuff
193+
## Getting Only the Important Stuff
192194

193195
You may notice, that all our deployed services produce not just text logs, but JSON. This is probably the most powerful ability of our stack: structured logging. What that means is that we can extract fields from the message JSON and use them for almost any analytics we can think of. This is enabled by the processor, called `decode_json_fields`. We'll decode JSON from the `message` field into the document root (`""`) for simplicity's sake. Here's the configuration snippet:
194196

@@ -213,9 +215,7 @@ The regular expression for that will be `container\.labels\..*_.*`. Agent inform
213215
ignore_missing: true
214216
```
215217

216-
## Let's wrap it up!
217-
218-
Here's an example of the log we get now:
218+
Giving us logs looking like this:
219219

220220
```json
221221
{
@@ -266,7 +266,9 @@ Here's an example of the log we get now:
266266
}
267267
```
268268

269-
Although the record is huge now it contains supposedly useful data from the actual log message, instead of mostly pointless docker metadata. Here's how `compose.yaml` and `filebeat.yml` look after the changes we made:
269+
## Wrapping It Up!
270+
271+
Although the record is still pretty big now it contains supposedly useful data from the actual log message, instead of mostly pointless docker metadata. Here's how `compose.yaml` and `filebeat.yml` look after the changes we made:
270272

271273
```yaml
272274
services:
@@ -323,4 +325,34 @@ output.elasticsearch:
323325

324326
With that setup we export structured logs to Elasticsearch, allowing the creation of any metric we could possibly imagine from the supplied logs. Beyond that, we can now create various index patterns for a bunch of possible use cases. As the cherry on top, we cleaned up our logs from useless metadata.
325327

328+
## Or simply...
329+
330+
If you don't want to carry the `filebeat.yml` around I have one more thing for you! I've made a docker image, which includes a [similar configuration file]() just with some additional perks. I called the image `el-shof` (`shippy` as it ships logs and connected to docker i.e. ship and `el` from `elastic`). Here's the `compose.yml` file that will solely deploy about the same stack as the two files above:
331+
332+
```yaml
333+
services:
334+
elasticsearch:
335+
image: elasticsearch:7.17.3
336+
environment:
337+
- discovery.type=single-node
338+
339+
kibana:
340+
image: kibana:7.17.3
341+
labels:
342+
- family=ui
343+
environment:
344+
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
345+
ports:
346+
- 5601:5601
347+
348+
shipper:
349+
image: vosarat/el-shippy
350+
user: root
351+
environment:
352+
- ES_HOSTS=elasticsearch:9200
353+
volumes:
354+
- /var/lib/docker:/var/lib/docker:ro
355+
- /var/run/docker.sock:/var/run/docker.sock
356+
```
357+
326358
Thank you for reading! By the way... claps are appreciated 👉👈

0 commit comments

Comments
 (0)