社内se × プログラマ × ビッグデータ

プログラミングなどITに興味があります。

Docker で filebeat も試す

公式に filebeat 用の Docker Image が提供されているので、簡単に試すことが可能です。
filebeat からデータを投入する elasticsearch については、以下の記事で作成したイメージを使っていきます。
blueskyarea.hatenablog.com

ディレクトリ構造

上記の記事では、logstash なども用意していますが、本記事内では必要最低限の分だけ記載します。

├── docker-compose.yml
├── elasticsearch
│   ├── config
│   │   └── elasticsearch.yml
│   └── Dockerfile
├── filebeat
│   ├── config
│   │   └── filebeat.docker.yml
│   ├── Dockerfile
│   └── logs
│       └── sample.log
├── kibana
│   ├── config
│   │   └── kibana.xml
│   ├── Dockerfile
filebeat/Dockerfile

元になるのは、公式の Docker イメージです。
それを元にこちらで用意した filebeat.yml を適用した Docker イメージを作成します。

FROM docker.elastic.co/beats/filebeat:7.6.2
LABEL maintainer blueskyarea

COPY config/filebeat.docker.yml /usr/share/filebeat/filebeat.yml
USER root
RUN chown root:filebeat /usr/share/filebeat/filebeat.yml
USER filebeat
filebeat/config/filebeat.docker.yml

このファイルには input 元と output 先を定義します。
input 元として、単純なテキストファイル (/usr/share/filebeat/logs/sample.log) を指定しています。
このファイルパスはコンテナ内のパスを意味していますが、ホストマシン上のファイルをバインドします。

output 先として、elasticsearch を指定しています。
hosts には、elasticsearch のコンテナのホスト名やIPアドレスを指定します。
index には、作成したいインデックス名を指定します。
その場合、setup.template.name: と setup.template.pattern: の指定が必須になります。

filebeat.inputs:
- type: log
  paths:
    - /usr/share/filebeat/logs/sample.log

setup.template.name: "filebeat"
setup.template.pattern: "filebeat-*"

output.elasticsearch:
  hosts: ["http://doc-elastic101:9200"]
  index: "filebeat-%{[agent.version]}-%{+yyyy.MM.dd}"
filebeat/logs/sample.log

とりあえず、空のファイルを作成しておきます。

docker-compose.yml

elasticsearch と kibana の Dockerfile や config ファイル等については、以下を参照。
Docker で ELK stack (version 7.6.2) - 社内se × プログラマ × ビッグデータ

この中で filebeat のコンテナ内とホストマシンのファイル(sample.log)をバインドしています。

version: '3.2'
services:
    elasticsearch:
        build:
            context: elasticsearch/
        hostname: doc-elastic101
        container_name: elastic1
        ports:
            - "9200:9200/tcp"
            - "9300:9300/tcp"
        networks:
            elk_nw:
                ipv4_address: 172.60.0.2
        volumes:
          - type: bind
            source: ./elasticsearch/config/elasticsearch.yml
            target: /usr/share/elasticsearch/config/elasticsearch.yml
            read_only: true
          - type: volume
            source: elasticsearch-data
            target: /usr/share/elasticsearch/data
        extra_hosts:
            - "doc-kibana101:172.60.0.4"

    kibana:
        build:
            context: kibana/
        hostname: doc-kibana101
        container_name: kibana1
        ports:
            - "5601:5601/tcp"
        networks:
            elk_nw:
                ipv4_address: 172.60.0.4
        volumes:
            - type: bind
              source: ./kibana/config/kibana.xml
              target: /usr/share/kibana/config/kibana.yml
              read_only: true
        extra_hosts:
            - "doc-elastic101:172.60.0.2"
        depends_on:
            - elasticsearch

    filebeat:
        build:
            context: filebeat/
        hostname: doc-filebeat101
        container_name: filebeat1
        networks:
            elk_nw:
                ipv4_address: 172.60.0.6
        volumes:
          - type: bind
            source: ./filebeat/logs
            target: /usr/share/filebeat/logs
        extra_hosts:
            - "doc-elastic101:172.60.0.2"
            - "doc-kibana101:172.60.0.4"
        depends_on:
            - elasticsearch

volumes:
    elasticsearch-data:
        driver: local

networks:
    elk_nw:
        driver: bridge
        ipam:
            driver: default
            config:
                - subnet: 172.60.0.0/16
実行

1 コマンドで elasticsearch, kibana, filebeat のコンテナが起動できます。

$ docker-compose up --build -d
...
Starting kibana1
Starting logstash1 ... 
Starting logstash1
Starting kibana1 ... done
動作確認

以下のコマンドで filebeat のログを監視します。
デフォルトでは30秒に一回、対象のファイル(sample.log)に更新がないかをチェックしています。

$ docker logs -f filebeat1
2020-05-ddT14:40:07.188Z	INFO	[monitoring]	log/log.go:145	Non-zero metrics in the last 30s	{"monitoring": {"metrics": {"beat":{"cpu":{"system":{"ticks":5020,"time":{"ms":10}},"total":{"ticks":14050,"time":{"ms":19},"value":14050},"user":{"ticks":9030,"time":{"ms":9}}},"handles":{"limit":{"hard":1048576,"soft":1048576},"open":7},"info":{"ephemeral_id":"26e68c53-d595-4ca1-8d27-da253e98ec90","uptime":{"ms":16470312}},"memstats":{"gc_next":8735968,"memory_alloc":4375280,"memory_total":181891640},"runtime":{"goroutines":22}},"filebeat":{"harvester":{"open_files":0,"running":0}},"libbeat":{"config":{"module":{"running":0}},"pipeline":{"clients":1,"events":{"active":0}}},"registrar":{"states":{"current":1}},"system":{"load":{"1":0.13,"15":0.17,"5":0.15,"norm":{"1":0.065,"15":0.085,"5":0.075}}}}}}

sample.log を更新してみます。
たとえば echo コマンドで追記します。

$ echo "INFO {"This is sample log"}" >> ./filebeat/logs/sample.log

kibana で確認してみると、以下のようにデータが投入され、index が作成されているのが確認できました。
f:id:blueskyarea:20200513235350p:plain

補足事項

filebeat が監視しているファイルを vim で更新して保存した場合、たとえ最後の1行しか更新していないとしても、全ての行が読み込まれ、elasticsearch に転送されます。
echo コマンドで追記した場合、その追記した行のみが elasticsearch に転送されます。