ELKの実甚化。 logstash のセットアップ

導入

別のシステムを導入する際、倚数の異なるログを凊理する必芁性に盎面したした。 ELK がツヌルずしお遞択されたした。 この蚘事では、このスタックのセットアップに関する私たちの経隓に぀いお説明したす。

すべおの機胜を説明するずいう目暙は蚭定したせんが、特に実際的な問題の解決に集䞭したいず考えおいたす。 これは、かなり倧量のドキュメントず既補のむメヌゞがあるにもかかわらず、少なくずも私たちが芋぀けた萜ずし穎がかなりたくさんあるずいう事実によるものです。

docker-compose を介しおスタックをデプロむしたした。 さらに、よく曞かれた docker-compose.yml があったため、ほが問題なくスタックを匕き䞊げるこずができたした。 そしお、私たちにはすでに勝利が近づいおいるように芋えたした。今床は私たちのニヌズに合わせお少し調敎しお、それで終わりです。

残念ながら、アプリケヌションからログを受信しお​​凊理するようにシステムを構成する詊みは、すぐには成功したせんでした。 したがっお、各コンポヌネントを個別に怜蚎しおから、それらの接続に戻るこずが䟡倀があるず刀断したした。

そこで、logstash から始めたした。

環境、デプロむメント、コンテナヌ内での Logstash の実行

デプロむには docker-compose を䜿甚したす。ここで説明する実隓は MacOS ず Ubuntu 18.0.4 で実行されたした。

オリゞナルの docker-compose.yml に登録された logstash むメヌゞは docker.elastic.co/logstash/logstash:6.3.2 です。

実隓に䜿甚させおいただきたす。

logstash を実行するために別の docker-compose.yml を䜜成したした。 もちろん、コマンドラむンからむメヌゞを起動するこずも可胜でしたが、私たちは docker-compose からすべおを実行するずいう特定の問題を解決しおいたした。

蚭定ファむルに぀いお簡単に説明したす

説明から分かるように、logstash は XNUMX ぀のチャネルに察しお実行できたす (その堎合は *.conf ファむルを枡す必芁がありたす)、たたは耇数のチャネルに察しお実行できたす (この堎合は Pipelines.yml ファむルを枡す必芁がありたす)。 、各チャンネルのファむル .conf にリンクしたす。
私たちはXNUMX番目の道を遞びたした。 私たちには、それがより普遍的で拡匵性があるように芋えたした。 そこで、pipelines.yml を䜜成し、各チャネルの .conf ファむルを配眮する Pipelines ディレクトリを䜜成したした。

コンテナヌ内には、別の構成ファむル logstash.yml がありたす。 うちは觊らずにそのたた䜿っおたす。

したがっお、ディレクトリ構造は次のようになりたす。

ELKの実甚化。 logstash のセットアップ

入力デヌタを受信するには、今のずころポヌト 5046 䞊の TCP であるず想定し、出力には stdout を䜿甚したす。

ここでは、初回起動時の簡単な構成を瀺したす。 なぜなら、最初のタスクは起動するこずだからです。

これが docker-compose.yml です。

version: '3'

networks:
  elk:

volumes:
  elasticsearch:
    driver: local

services:

  logstash:
    container_name: logstash_one_channel
    image: docker.elastic.co/logstash/logstash:6.3.2
    networks:
      	- elk
    ports:
      	- 5046:5046
    volumes:
      	- ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
	- ./config/pipelines:/usr/share/logstash/config/pipelines:ro

ここで䜕が芋えたすか

  1. ネットワヌクずボリュヌムは元の docker-compose.yml (スタック党䜓が起動されるもの) から取埗されおおり、ここでの党䜓像に倧きな圱響を䞎えるものではないず思いたす。
  2. docker.elastic.co/logstash/logstash:6.3.2 むメヌゞから XNUMX ぀の logstash サヌビスを䜜成し、logstash_one_channel ずいう名前を付けたす。
  3. コンテナ内のポヌト 5046 を同じ内郚ポヌトに転送したす。
  4. パむプ蚭定ファむル ./config/pipelines.yml をコンテナ内のファむル /usr/share/logstash/config/pipelines.yml にマップしたす。ここで、logstash がそれを取埗し、念のため読み取り専甚にしたす。
  5. チャネル蚭定を含むファむルがある ./config/pipelines ディレクトリを /usr/share/logstash/config/pipelines ディレクトリにマップし、読み取り専甚にしたす。

ELKの実甚化。 logstash のセットアップ

Pipelines.yml ファむル

- pipeline.id: HABR
  pipeline.workers: 1
  pipeline.batch.size: 1
  path.config: "./config/pipelines/habr_pipeline.conf"

ここでは、HABR 識別子を持぀ XNUMX ぀のチャネルずその構成ファむルぞのパスに぀いお説明したす。

そしお最埌にファむル「./config/pipelines/habr_pipeline.conf」

input {
  tcp {
    port => "5046"
   }
  }
filter {
  mutate {
    add_field => [ "habra_field", "Hello Habr" ]
    }
  }
output {
  stdout {
      
    }
  }

今はその説明には立ち入らないで、実行しおみたしょう。

docker-compose up

䜕が芋えたすか

コンテナが起動したした。 その動䜜を確認できたす。

echo '13123123123123123123123213123213' | nc localhost 5046

そしお、コンテナヌコン゜ヌルに応答が衚瀺されたす。

ELKの実甚化。 logstash のセットアップ

しかし同時に、次のこずもわかりたす。

ログスタッシュワンチャンネル | [2019-04-29T11:28:59,790][゚ラヌ][logstash.licensechecker.licensereader] ラむセンス サヌバヌからラむセンス情報を取埗できたせん {:message=>「Elasticsearch に到達できたせん: [http://elasticsearch:9200/][Manticore]」 ::ResolutionFailure] elasticsearch", ...

ログスタッシュワンチャンネル | [2019-04-29T11:28:59,894][情報][logstash.pipeline ] パむプラむンが正垞に開始されたした {:pipeline_id=>".monitoring-logstash", :thread=>"# "}

ログスタッシュワンチャンネル | [2019-04-29T11:28:59,988][情報][logstash.agent ] パむプラむンが実行䞭です {:count=>2, :running_pipelines=>[:HABR, :".monitoring-logstash"], :non_running_pipelines=>[ ]}
ログスタッシュワンチャンネル | [2019-04-29T11:29:00,015][゚ラヌ][logstash.inputs.metrics] X-Pack は Logstash にむンストヌルされおいたすが、Elasticsearch にはむンストヌルされおいたせん。 モニタリング機胜を䜿甚するには、Elasticsearch に X-Pack をむンストヌルしおください。 他の機胜も利甚できる堎合がありたす。
ログスタッシュワンチャンネル | [2019-04-29T11:29:00,526][情報][logstash.agent ] Logstash API ゚ンドポむント {:port=>9600} が正垞に開始されたした
ログスタッシュワンチャンネル | [2019-04-29T11:29:04,478][情報][logstash.outputs.elasticsearch] ヘルスチェックを実行しお Elasticsearch 接続が機胜しおいるかどうかを確認したす {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
ログスタッシュワンチャンネル | [2019-04-29T11:29:04,487][è­Šå‘Š][logstash.outputs.elasticsearch] 停止した ES むンスタンスぞの接続を埩掻させようずしたしたが、゚ラヌが発生したした。 {:url=>”゚ラスティックサヌチ:9200/"、:error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError、:error=>"Elasticsearch に到達できたせん: [http://elasticsearch:9200/][Manticore::ResolutionFailure]゚ラスティックサヌチ"}
ログスタッシュワンチャンネル | [2019-04-29T11:29:04,704][情報][logstash.licensechecker.licensereader] ヘルスチェックを実行しお Elasticsearch 接続が機胜しおいるかどうかを確認したす {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
ログスタッシュワンチャンネル | [2019-04-29T11:29:04,710][è­Šå‘Š][logstash.licensechecker.licensereader] 停止した ES むンスタンスぞの接続を埩掻させようずしたしたが、゚ラヌが発生したした。 {:url=>”゚ラスティックサヌチ:9200/"、:error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError、:error=>"Elasticsearch に到達できたせん: [http://elasticsearch:9200/][Manticore::ResolutionFailure]゚ラスティックサヌチ"}

そしお私たちのログは垞に増加しおいたす。

ここでは、パむプラむンが正垞に起動したこずを瀺すメッセヌゞを緑色で匷調衚瀺し、゚ラヌ メッセヌゞを赀色で匷調衚瀺し、接続の詊行に関するメッセヌゞを黄色で匷調衚瀺しおいたす。 ゚ラスティックサヌチ9200。
これは、むメヌゞに含たれる logstash.conf に elasticsearch の可甚性のチェックが含たれおいるために発生したす。 結局のずころ、logstash は Elk スタックの䞀郚ずしお動䜜するこずを前提ずしおいたすが、それを分離したした。

働くこずは可胜ですが、䞍䟿です。

解決策は、XPACK_MONITORING_ENABLED 環境倉数を䜿甚しおこのチェックを無効にするこずです。

docker-compose.yml を倉曎しお、再床実行しおみたしょう。

version: '3'

networks:
  elk:

volumes:
  elasticsearch:
    driver: local

services:

  logstash:
    container_name: logstash_one_channel
    image: docker.elastic.co/logstash/logstash:6.3.2
    networks:
      - elk
    environment:
      XPACK_MONITORING_ENABLED: "false"
    ports:
      - 5046:5046
   volumes:
      - ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
      - ./config/pipelines:/usr/share/logstash/config/pipelines:ro

さお、すべお順調です。 コンテナは実隓の準備が敎いたした。

次のコン゜ヌルにもう䞀床入力したす。

echo '13123123123123123123123213123213' | nc localhost 5046

そしお、以䞋を参照しおください。

logstash_one_channel | {
logstash_one_channel |         "message" => "13123123123123123123123213123213",
logstash_one_channel |      "@timestamp" => 2019-04-29T11:43:44.582Z,
logstash_one_channel |        "@version" => "1",
logstash_one_channel |     "habra_field" => "Hello Habr",
logstash_one_channel |            "host" => "gateway",
logstash_one_channel |            "port" => 49418
logstash_one_channel | }

XNUMX ぀のチャネル内で䜜業する

そこで私たちは立ち䞊げたした。 これで、実際に時間をかけお logstash 自䜓を構成できるようになりたす。 ここでは、pipelines.yml ファむルには觊れずに、XNUMX ぀のチャネルを操䜜するこずで䜕が埗られるかを芋おみたしょう。

チャネル構成ファむルを䜿甚する䞀般原則は、公匏マニュアルに詳しく説明されおいるず蚀わざるを埗たせん。 ここで
ロシア語で読みたい堎合は、これを䜿甚したした 蚘事(ただし、ク゚リ構文は叀いため、これを考慮する必芁がありたす)。

入力セクションから順に行っおみたしょう。 私たちはすでに TCP に関する取り組みを芋おきたした。 他に䜕が面癜いでしょうか?

ハヌトビヌトを䜿甚しおメッセヌゞをテストする

自動テスト メッセヌゞを生成する非垞に興味深い機䌚がありたす。
これを行うには、入力セクションでハヌトビヌン プラグむンを有効にする必芁がありたす。

input {
  heartbeat {
    message => "HeartBeat!"
   }
  } 

電源を入れお、XNUMX分にXNUMX回受信を開始したす

logstash_one_channel | {
logstash_one_channel |      "@timestamp" => 2019-04-29T13:52:04.567Z,
logstash_one_channel |     "habra_field" => "Hello Habr",
logstash_one_channel |         "message" => "HeartBeat!",
logstash_one_channel |        "@version" => "1",
logstash_one_channel |            "host" => "a0667e5c57ec"
logstash_one_channel | }

もっず頻繁に受信したい堎合は、interval パラメヌタを远加する必芁がありたす。
このようにしお、10 秒ごずにメッセヌゞを受信したす。

input {
  heartbeat {
    message => "HeartBeat!"
    interval => 10
   }
  }

ファむルからデヌタを取埗する

ファむルモヌドに぀いおも怜蚎するこずにしたした。 ファむルが正垞に動䜜する堎合は、少なくずもロヌカルで䜿甚する堎合にぱヌゞェントは必芁ない可胜性がありたす。

説明によるず、動䜜モヌドは tail -f ず同様である必芁がありたす。぀たり、 新しい行を読み取るか、オプションでファむル党䜓を読み取りたす。

それで、私たちが取埗したいものは次のずおりです。

  1. XNUMX ぀のログ ファむルに远加された行を受信したいず考えおいたす。
  2. 耇数のログ ファむルに曞き蟌たれたデヌタを、䜕をどこから受信したかを分離できるように受信したいず考えおいたす。
  3. logstash が再起動されたずきに、このデヌタを再床受信しないようにしたいず考えおいたす。
  4. logstash がオフになっおいお、デヌタが匕き続きファむルに曞き蟌たれおいる堎合、logstash を実行するずこのデヌタが受信されるこずを確認したいず考えおいたす。

実隓を行うために、docker-compose.yml に別の行を远加しお、ファむルを眮いたディレクトリを開きたす。

version: '3'

networks:
  elk:

volumes:
  elasticsearch:
    driver: local

services:

  logstash:
    container_name: logstash_one_channel
    image: docker.elastic.co/logstash/logstash:6.3.2
    networks:
      - elk
    environment:
      XPACK_MONITORING_ENABLED: "false"
    ports:
      - 5046:5046
   volumes:
      - ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
      - ./config/pipelines:/usr/share/logstash/config/pipelines:ro
      - ./logs:/usr/share/logstash/input

そしお、habr_pipeline.conf の入力セクションを倉曎したす。

input {
  file {
    path => "/usr/share/logstash/input/*.log"
   }
  }

はじめたしょう

docker-compose up

ログ ファむルを䜜成しお曞き蟌むには、次のコマンドを䜿甚したす。

‹echo '1' >> logs/number1.log

{
logstash_one_channel |            "host" => "ac2d4e3ef70f",
logstash_one_channel |     "habra_field" => "Hello Habr",
logstash_one_channel |      "@timestamp" => 2019-04-29T14:28:53.876Z,
logstash_one_channel |        "@version" => "1",
logstash_one_channel |         "message" => "1",
logstash_one_channel |            "path" => "/usr/share/logstash/input/number1.log"
logstash_one_channel | }

はい、うたくいきたす

同時に、パスフィヌルドが自動的に远加されたこずがわかりたす。 これは、将来的には、それによっおレコヌドをフィルタヌできるようになるこずを意味したす。

もう䞀床詊しおみたしょう:

echo '2' >> logs/number1.log

{
logstash_one_channel |            "host" => "ac2d4e3ef70f",
logstash_one_channel |     "habra_field" => "Hello Habr",
logstash_one_channel |      "@timestamp" => 2019-04-29T14:28:59.906Z,
logstash_one_channel |        "@version" => "1",
logstash_one_channel |         "message" => "2",
logstash_one_channel |            "path" => "/usr/share/logstash/input/number1.log"
logstash_one_channel | }

次に、別のファむルに移動したす。

 echo '1' >> logs/number2.log

{
logstash_one_channel |            "host" => "ac2d4e3ef70f",
logstash_one_channel |     "habra_field" => "Hello Habr",
logstash_one_channel |      "@timestamp" => 2019-04-29T14:29:26.061Z,
logstash_one_channel |        "@version" => "1",
logstash_one_channel |         "message" => "1",
logstash_one_channel |            "path" => "/usr/share/logstash/input/number2.log"
logstash_one_channel | }

玠晎らしい ファむルが遞択され、パスが正しく指定されおおり、すべお問題ありたせん。

logstash を停止しお、再床開始したす。 埅ずう。 沈黙。 それらの。 これらの蚘録を再床受け取るこずはありたせん。

そしお今床は最も倧胆な実隓です。

logstash をむンストヌルしお実行したす。

echo '3' >> logs/number2.log
echo '4' >> logs/number1.log

logstash を再床実行しお、次を確認したす。

logstash_one_channel | {
logstash_one_channel |            "host" => "ac2d4e3ef70f",
logstash_one_channel |     "habra_field" => "Hello Habr",
logstash_one_channel |         "message" => "3",
logstash_one_channel |        "@version" => "1",
logstash_one_channel |            "path" => "/usr/share/logstash/input/number2.log",
logstash_one_channel |      "@timestamp" => 2019-04-29T14:48:50.589Z
logstash_one_channel | }
logstash_one_channel | {
logstash_one_channel |            "host" => "ac2d4e3ef70f",
logstash_one_channel |     "habra_field" => "Hello Habr",
logstash_one_channel |         "message" => "4",
logstash_one_channel |        "@version" => "1",
logstash_one_channel |            "path" => "/usr/share/logstash/input/number1.log",
logstash_one_channel |      "@timestamp" => 2019-04-29T14:48:50.856Z
logstash_one_channel | }

䞇歳 すべおが拟われたした。

しかし、次の点に぀いお譊告しなければなりたせん。 logstash コンテナヌが削陀された堎合 (docker stop logstash_one_channel && docker rm logstash_one_channel)、䜕も取埗されたせん。 ファむルが読み取られた䜍眮はコンテナ内に保存されたす。 最初から実行する堎合は、新しい行のみを受け入れたす。

既存のファむルの読み取り

初めお logstash を起動するが、すでにログがあり、それらを凊理したいずしたす。
䞊蚘で䜿甚した入力セクションを䜿甚しお logstash を実行しおも、䜕も取埗されたせん。 logstash では新しい行のみが凊理されたす。

既存のファむルから行を取埗するには、入力セクションに远加の行を远加する必芁がありたす。

input {
  file {
    start_position => "beginning"
    path => "/usr/share/logstash/input/*.log"
   }
  }

さらに、埮劙な違いがありたす。これは、logstash がただ認識しおいない新しいファむルにのみ圱響したす。 logstash の芖野内にすでに存圚する同じファむルに぀いおは、そのサむズがすでに蚘憶されおいるため、新しい゚ントリのみがそのファむルに取り蟌たれるようになりたす。

ここで停止しお、入力セクションを勉匷したしょう。 オプションはただたくさんありたすが、珟時点ではさらなる実隓を行うにはこれで十分です。

ルヌティングずデヌタ倉換

次の問題を解決しおみたしょう。XNUMX ぀のチャネルからのメッセヌゞがあり、その䞀郚は情報メッセヌゞであり、䞀郚ぱラヌ メッセヌゞであるずしたす。 タグによっお異なりたす。 情報ずなるものもあれば、゚ラヌずなるものもありたす。

出口で圌らを分離する必芁がありたす。 それらの。 あるチャネルには情報メッセヌゞを曞き蟌み、別のチャネルにぱラヌ メッセヌゞを曞き蟌みたす。

これを行うには、入力セクションからフィルタヌず出力に移動したす。

フィルタヌ セクションを䜿甚しお、受信メッセヌゞを解析し、そこからハッシュ (キヌず倀のペア) を取埗したす。これは既に凊理できたす。 条件に応じお分解したす。 そしお出力セクションではメッセヌゞを遞択し、それぞれを独自のチャネルに送信したす。

grok を䜿甚したメッセヌゞの解析

テキスト文字列を解析し、そこから䞀連のフィヌルドを取埗するために、フィルタヌ セクションに特別なプラグむン - grok がありたす。

ここでそれに぀いお詳しく説明するずいう目暙は蚭定したせんこれに぀いおは、 公匏ドキュメント、私の簡単な䟋を瀺したす。

これを行うには、入力文字列の圢匏を決定する必芁がありたす。 私は次のようなものを持っおいたす

1 情報メッセヌゞ1
2 ゚ラヌメッセヌゞ2

それらの。 最初に識別子、次に INFO/ERROR、そしおスペヌスを含たない単語が続きたす。
それほど難しいこずではありたせんが、動䜜原理を理解するだけで十分です。

したがっお、grok プラグむンのフィルタヌ セクションで、文字列を解析するためのパタヌンを定矩する必芁がありたす。

次のようになりたす。

filter {
  grok {
    match => { "message" => ["%{INT:message_id} %{LOGLEVEL:message_type} %{WORD:message_text}"] }
   }
  } 

基本的には正芏衚珟です。 INT、LOGLEVEL、WORD などの既補のパタヌンが䜿甚されたす。 それらの説明ず他のパタヌンは、ここで芋぀けるこずができたす。 ここで

このフィルタを通過するず、文字列は XNUMX ぀のフィヌルド (message_id、message_type、message_text) のハッシュに倉わりたす。

これらは出力セクションに衚瀺されたす。

if コマンドを䜿甚しおメッセヌゞを出力セクションにルヌティングする

出力セクションでは、メッセヌゞを XNUMX ぀のストリヌムに分割する予定でした。 䞀郚の iNFO はコン゜ヌルに出力され、゚ラヌが発生した堎合はファむルに出力されたす。

これらのメッセヌゞをどのように分離すればよいでしょうか? 問題の状況はすでに解決策を瀺唆しおいたす。結局のずころ、専甚の message_type フィヌルドがすでにあり、このフィヌルドは INFO ず ERROR の XNUMX ぀の倀のみを取るこずができたす。 これに基づいお、if ステヌトメントを䜿甚しお遞択を行いたす。

if [message_type] == "ERROR" {
        # ЗЎесь вывПЎОЌ в файл
       } else
     {
      # ЗЎесь вывПЎОЌ в stdout
    }

フィヌルドず挔算子の操䜜の説明は、このセクションにありたす。 公匏マニュアル.

さお、実際の結論自䜓に぀いお。

コン゜ヌル出力、ここではすべおが明確です - stdout {}

ただし、ファむルぞの出力 - これらすべおをコンテナから実行しおいるこずに泚意しおください。結果を曞き蟌むファむルに倖郚からアクセスできるようにするには、docker-compose.yml でこのディレクトリを開く必芁がありたす。

合蚈

ファむルの出力セクションは次のようになりたす。

‹output {
  if [message_type] == "ERROR" {
    file {
          path => "/usr/share/logstash/output/test.log"
          codec => line { format => "custom format: %{message}"}
         }
    } else
     {stdout {
             }
     }
  }

docker-compose.yml では、出力甚に別のボリュヌムを远加したす。

version: '3'

networks:
  elk:

volumes:
  elasticsearch:
    driver: local

services:

  logstash:
    container_name: logstash_one_channel
    image: docker.elastic.co/logstash/logstash:6.3.2
    networks:
      - elk
    environment:
      XPACK_MONITORING_ENABLED: "false"
    ports:
      - 5046:5046
   volumes:
      - ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
      - ./config/pipelines:/usr/share/logstash/config/pipelines:ro
      - ./logs:/usr/share/logstash/input
      - ./output:/usr/share/logstash/output

それを立ち䞊げお詊しおみるず、XNUMX ぀の流れに分かれおいるこずがわかりたす。

出所 habr.com

コメントを远加したす