From f592f221c4ef49019f9f595e5ed5722fd4e92d96 Mon Sep 17 00:00:00 2001 From: Mustafa Guney Date: Sat, 16 Jan 2021 23:11:24 +0300 Subject: [PATCH] Add Metricbeat extension (#567) Co-authored-by: Antoine Cotten --- .github/workflows/ci.yml | 19 +++++++ .../workflows/scripts/run-tests-metricbeat.sh | 52 +++++++++++++++++++ extensions/metricbeat/Dockerfile | 3 ++ extensions/metricbeat/README.md | 20 +++++++ extensions/metricbeat/config/metricbeat.yml | 44 ++++++++++++++++ extensions/metricbeat/metricbeat-compose.yml | 46 ++++++++++++++++ 6 files changed, 184 insertions(+) create mode 100755 .github/workflows/scripts/run-tests-metricbeat.sh create mode 100644 extensions/metricbeat/Dockerfile create mode 100644 extensions/metricbeat/README.md create mode 100644 extensions/metricbeat/config/metricbeat.yml create mode 100644 extensions/metricbeat/metricbeat-compose.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ff0107..865ee8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,7 @@ jobs: sed -i -e 's/\(elasticsearch.username:\) elastic/\1 kibana_system/g' -e 's/\(elasticsearch.password:\) changeme/\1 testpasswd/g' kibana/config/kibana.yml sed -i -e 's/\(elasticsearch.password:\) changeme/\1 testpasswd/g' -e 's/\(secret_management.encryption_keys:\)/\1 [test-encrypt]/g' extensions/enterprise-search/config/enterprise-search.yml sed -i 's/\(password:\) changeme/\1 testpasswd/g' extensions/apm-server/config/apm-server.yml + sed -i 's/\(password:\) changeme/\1 testpasswd/g' extensions/metricbeat/config/metricbeat.yml # Run Elasticsearch and wait for its availability @@ -174,6 +175,23 @@ jobs: # next steps don't need APM Server docker-compose -f docker-compose.yml -f extensions/apm-server/apm-server-compose.yml stop apm-server + # + # Metricbeat + # + + - name: Execute Metricbeat test suite + run: | + docker-compose -f docker-compose.yml -f extensions/metricbeat/metricbeat-compose.yml up -d metricbeat + .github/workflows/scripts/run-tests-metricbeat.sh + + - name: 'debug: Display state and logs (Metricbeat)' + if: always() + run: | + docker-compose -f docker-compose.yml -f extensions/metricbeat/metricbeat-compose.yml ps + docker-compose -f docker-compose.yml -f extensions/metricbeat/metricbeat-compose.yml logs metricbeat + # next steps don't need Metricbeat + docker-compose -f docker-compose.yml -f extensions/metricbeat/metricbeat-compose.yml stop metricbeat + ############## # # # Tear down. # @@ -188,6 +206,7 @@ jobs: -f extensions/logspout/logspout-compose.yml -f extensions/enterprise-search/enterprise-search-compose.yml -f extensions/apm-server/apm-server-compose.yml + -f extensions/metricbeat/metricbeat-compose.yml down -v test-swarm: diff --git a/.github/workflows/scripts/run-tests-metricbeat.sh b/.github/workflows/scripts/run-tests-metricbeat.sh new file mode 100755 index 0000000..6dc99c0 --- /dev/null +++ b/.github/workflows/scripts/run-tests-metricbeat.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +set -eu +set -o pipefail + + +source "$(dirname ${BASH_SOURCE[0]})/lib/testing.sh" + + +cid_es="$(container_id elasticsearch)" +cid_mb="$(container_id metricbeat)" + +ip_es="$(service_ip elasticsearch)" +ip_mb="$(service_ip metricbeat)" + +log 'Waiting for readiness of Elasticsearch' +poll_ready "$cid_es" "http://${ip_es}:9200/" -u 'elastic:testpasswd' + +log 'Waiting for readiness of Metricbeat' +poll_ready "$cid_mb" "http://${ip_mb}:5066/?pretty" + +# We expect to find one monitoring entry for the 'elasticsearch' Compose +# service using the following query: +# +# agent.type:"metricbeat" +# AND event.module:"docker" +# AND event.dataset:"docker.container" +# AND container.name:"docker-elk_elasticsearch_1" +# +log 'Searching a document generated by Metricbeat' + +declare response +declare -i count + +# retry for max 60s (30*2s) +for _ in $(seq 1 30); do + response="$(curl "http://${ip_es}:9200/metricbeat-*/_search?q=agent.type:%22metricbeat%22%20AND%20event.module:%22docker%22%20AND%20event.dataset:%22docker.container%22%20AND%20container.name:%22docker-elk_elasticsearch_1%22&pretty" -s -u elastic:testpasswd)" + count="$(jq -rn --argjson data "${response}" '$data.hits.total.value')" + if (( count > 0 )); then + break + fi + + echo -n 'x' >&2 + sleep 2 +done +echo -e '\n' >&2 + +echo "$response" +if (( count != 1 )); then + echo "Expected 1 document, got ${count}" + exit 1 +fi diff --git a/extensions/metricbeat/Dockerfile b/extensions/metricbeat/Dockerfile new file mode 100644 index 0000000..e55f625 --- /dev/null +++ b/extensions/metricbeat/Dockerfile @@ -0,0 +1,3 @@ +ARG ELK_VERSION + +FROM docker.elastic.co/beats/metricbeat:${ELK_VERSION} diff --git a/extensions/metricbeat/README.md b/extensions/metricbeat/README.md new file mode 100644 index 0000000..c36d0c2 --- /dev/null +++ b/extensions/metricbeat/README.md @@ -0,0 +1,20 @@ +# Metricbeat + +Metricbeat is a lightweight shipper that you can install on your servers to periodically collect metrics from the +operating system and from services running on the server. Metricbeat takes the metrics and statistics that it collects +and ships them to the output that you specify, such as Elasticsearch or Logstash. + +## Usage + +If you want to include the Metricbeat extension, run Docker Compose from the root of the repository with an additional +command line argument referencing the `metricbeat-compose.yml` file: + +```bash +$ docker-compose -f docker-compose.yml -f extensions/metricbeat/metricbeat-compose.yml up +``` + +## Documentation + +[Official Docs](https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-overview.html) +[Running on Docker](https://www.elastic.co/guide/en/beats/metricbeat/current/running-on-docker.html) +[Configuration reference](https://www.elastic.co/guide/en/beats/metricbeat/master/metricbeat-reference-yml.html) diff --git a/extensions/metricbeat/config/metricbeat.yml b/extensions/metricbeat/config/metricbeat.yml new file mode 100644 index 0000000..62f145b --- /dev/null +++ b/extensions/metricbeat/config/metricbeat.yml @@ -0,0 +1,44 @@ +## Metricbeat configuration +## https://github.com/elastic/beats/blob/master/deploy/docker/metricbeat.docker.yml +# + +metricbeat.config: + modules: + path: ${path.config}/modules.d/*.yml + # Reload module configs as they change: + reload.enabled: false + +metricbeat.autodiscover: + providers: + - type: docker + hints.enabled: true + +metricbeat.modules: +- module: docker + metricsets: + - container + - cpu + - diskio + - healthcheck + - info + #- image + - memory + - network + hosts: ['unix:///var/run/docker.sock'] + period: 10s + enabled: true + +processors: + - add_cloud_metadata: ~ + +output.elasticsearch: + hosts: ['http://elasticsearch:9200'] + username: elastic + password: changeme + +## HTTP endpoint for health checking +## https://www.elastic.co/guide/en/beats/metricbeat/master/http-endpoint.html +# + +http.enabled: true +http.host: 0.0.0.0 diff --git a/extensions/metricbeat/metricbeat-compose.yml b/extensions/metricbeat/metricbeat-compose.yml new file mode 100644 index 0000000..fa222b4 --- /dev/null +++ b/extensions/metricbeat/metricbeat-compose.yml @@ -0,0 +1,46 @@ +version: '3.2' + +services: + metricbeat: + build: + context: extensions/metricbeat/ + args: + ELK_VERSION: $ELK_VERSION + # Run as 'root' instead of 'metricbeat' (uid 1000) to allow reading + # 'docker.sock' and the host's filesystem. + user: root + command: + # Log to stderr. + - -e + # Disable config file permissions checks. Allows mounting + # 'config/metricbeat.yml' even if it's not owned by root. + # see: https://www.elastic.co/guide/en/beats/libbeat/master/config-file-permissions.html + - --strict.perms=false + # Mount point of the host’s filesystem. Required to monitor the host + # from within a container. + - --system.hostfs=/hostfs + volumes: + - type: bind + source: ./extensions/metricbeat/config/metricbeat.yml + target: /usr/share/metricbeat/metricbeat.yml + read_only: true + - type: bind + source: / + target: /hostfs + read_only: true + - type: bind + source: /sys/fs/cgroup + target: /hostfs/sys/fs/cgroup + read_only: true + - type: bind + source: /proc + target: /hostfs/proc + read_only: true + - type: bind + source: /var/run/docker.sock + target: /var/run/docker.sock + read_only: true + networks: + - elk + depends_on: + - elasticsearch