2024年1月29日月曜日

docker で gelf ドライバを使って logstash にログを送信してみる

docker で gelf ドライバを使って logstash にログを送信してみる

概要

過去に fluent-driver を使って fluentd にログを送信する方法を紹介しました
今回は gelf driver を使って logstash にログを送信してみました
なおコンテナは docker-compose で動作させます

環境

  • macOS 14.2.1
  • docker 24.0.7
  • docker-compose 2.23.3
  • logstash 8.12.0

docker-compose.yml

logstash と適当なアプリを起動します
ポイントはアプリ側の driver 指定で gelf を指定します
ここが logstash が起動するエンドポイントを指定する部分です

logstash は logger として docker-compose 内で指定します
12201:udp として起動します
logstash.conf はあとで紹介しますが今回は Elasticsearch などには連携せず受け取ったアプリからのログをそのまま標準出力するだけです

  • vim docker-compose.yml
version: '3.8'
services:
  logger:
    image: logstash:8.12.0
    volumes:
      - ./logstash:/etc/logstash
    command: logstash -f /etc/logstash/logstash.conf
    ports:
      - 12201:12201/udp
  web:
    image: nginx
    ports:
      - "80:80"
    logging:
      driver: gelf
      options:
        gelf-address: udp://192.168.1.23:12201
        tag: docker.web
    depends_on:
      - logger

logstash/logstash.conf

12201 で受け取ったログを標準出力します

  • vim logstash/logstash.conf
input {
  gelf {
    port => 12201
  }
}

output {
  stdout {}
}

動作確認

コンテナを起動します

  • docker-compose up -d

あとはログを確認しつつアプリにアクセスします
すると logstash 側に以下のようなログが出力されることが確認できます

  • docker-compose logs -f
  • curl localhost
logger-1  | {
logger-1  |               "host" => "docker-desktop",
logger-1  |           "image_id" => "sha256:6c7be49d2a11cfab9a87362ad27d447b45931e43dfa6919a8e1398ec09c1e353",
logger-1  |              "level" => 6,
logger-1  |            "version" => "1.1",
logger-1  |            "created" => "2024-01-24T00:28:59.739392089Z",
logger-1  |        "source_host" => "192.168.65.1",
logger-1  |           "@version" => "1",
logger-1  |     "container_name" => "docker-web-1",
logger-1  |         "@timestamp" => 2024-01-24T00:29:47.975Z,
logger-1  |         "image_name" => "nginx",
logger-1  |            "message" => "192.168.65.1 - - [24/Jan/2024:00:29:47 +0000] \"GET / HTTP/1.1\" 200 615 \"-\" \"curl/8.4.0\" \"-\"",
logger-1  |                "tag" => "docker.web",
logger-1  |            "command" => "/docker-entrypoint.sh nginx -g daemon off;",
logger-1  |       "container_id" => "2c997b2676e305f5fb7d29e49415c45a5cb9d7edcd6f73ad03d45124d158c246"
logger-1  | }

ElasticSearch に接続できないというエラーがずっと出る

以下のようなエラーがずっとログに出力されていました

logger-1  | [2024-01-24T00:35:42,235][ERROR][logstash.licensechecker.licensereader] Unable to retrieve Elasticsearch cluster info. {:message=>"No Available connections", :exception=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::NoConnectionAvailableError}
logger-1  | [2024-01-24T00:35:42,236][ERROR][logstash.licensechecker.licensereader] Unable to retrieve license information from license server {:message=>"No Available connections"}
logger-1  | [2024-01-24T00:35:42,752][INFO ][logstash.licensechecker.licensereader] Failed to perform request {:message=>"elasticsearch: Name or service not known", :exception=>Manticore::ResolutionFailure, :cause=>#<Java::JavaNet::UnknownHostException: elasticsearch: Name or service not known>}
logger-1  | [2024-01-24T00:35:42,753][WARN ][logstash.licensechecker.licensereader] Attempted to resurrect connection to dead ES instance, but got an error {:url=>"http://elasticsearch:9200/", :exception=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError, :message=>"Elasticsearch Unreachable: [http://elasticsearch:9200/
][Manticore::ResolutionFailure] elasticsearch: Name or service not known"}

おそらく logstash の output に ElasticSearch の設定がないからだと思います
今回のようにテスト用途で ES に接続しないのであれば XPACK_MONITORING_ENABLED=false という環境変数を logstash に設定してあげると自動で接続しにいかなくなります

version: '3.8'
services:
  logger:
    image: logstash:8.12.0
    volumes:
      - ./logstash:/etc/logstash
    command: logstash -f /etc/logstash/logstash.conf
    environment:
      - XPACK_MONITORING_ENABLED=false
    ports:
      - 12201:12201/udp
  web:
    image: nginx
    ports:
      - "80:80"
    logging:
      driver: gelf
      options:
        gelf-address: udp://192.168.1.23:12201
        tag: docker.web
    depends_on:
      - logger

最後に

docker + logstash を連携してみました
基本的にはこのあとログを ElasticSearch に格納することになります
fluentd ではなく logstash を使いたい場合には gelf ドライバを使いましょう

参考サイト

0 件のコメント:

コメントを投稿