blog-post-1

Logging transport with Docker Swarm

Logshipper is a side-bar container that tail logs files and sends logs to external centralize logs storage.

The main reason to use it to that application doesn't need to bother with the transportation of logs. The backed app just writes logs to console (or file sometimes) and the logshipper takes care of getting it in logs storage.

The system consist of 3 main parts:

Logshipper

Examples: Filebeat, Logspout

Logshipper is hosted on each node. It is listening to logs file or docker log driver and then handles the transportation to log buffer.

Buffer

Examples: Logstash, Telegraf

The buffer is converting logs from transport format(Elastic beats, Syslog) and inserts data into a storage. It also can store logs while a timetime-series database is not available. Since nowadays most logs are shipped in JSON it is important that either logshipper or buffer could transform them into key-value format.

Storage

Examples: Elastic Search, InfluxDb

Log storage. In 95% cases, it is a time-series database which can store logs, events, metrics.

There are a сouple of different options for each of the 3 components. Each has pros and cons. This post will not cover it but will cover how to setup Filebeat - Logstash to work ElasticSearch and Logspout - telegraph to InfluxDb.

Here is simple config example:

Filebeat

First is necessary to create a config file for filebeat. Here is an example

filebeat.inputs:
- type: docker
combine_partial: true
containers:
path: "/usr/share/dockerlogs/data"
stream: "stdout"
ids:
- "*"
ignore_older: 1h
processors:
- add_docker_metadata:
host: "unix:///var/run/docker.sock"
- drop_event:
when:
not:
equals:
container.labels.filebeat: "on" #filebeat will listen only to containers that has flag filebeat=on
# setup filebeat to send output to logstash
output.logstash:
hosts: '${LS_HOSTS}' # Address will be set via Env var
logging.level: error
logging.to_files: false
logging.to_syslog: false
view raw filebeat.yml hosted with ❤ by GitHub

Logstash

input {
beats {
port => 5044
type => "beats"
client_inactivity_timeout => 3000
}
}
filter {
mutate {
## remove dumb fields
remove_field => [ "ecs.version", "[agent]", "[log]", "stream" , "[input]" ]
}
}
output {
elasticsearch {
hosts => "elasticsearch:9200"
index => "%{[container][labels][app_name]}-%{+YYYY.MM.dd}"
}
}
view raw logstash.conf hosted with ❤ by GitHub

The elk docker compose example

version: '2'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
mem_limit: 1g
volumes:
- ./data/elasticsearch:/usr/share/elasticsearch/data
logstash:
image: docker.elastic.co/logstash/logstash:7.6.2
container_name: logstash_docker
environment:
- "LS_JAVA_OPTS=-Xmx256m -Xms256m"
volumes:
- ./logstash.conf:/usr/share/pipeline/logstash.conf:ro
- logstasha: /usr/share/logstash/data
mem_limit: 1g
depends_on:
- elasticsearch
filebeat:
image: docker.elastic.co/beats/filebeat:7.6.2
user: root
volumes:
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- LS_HOSTS="logstash:5044"
volumes:
elasticsearch:
logstash:

That is a simple example of how ELK stack logs can be structured. For json parsing: https://www.elastic.co/guide/en/logstash/current/plugins-filters-json.html 

Comments (0)

Leave a Comment