~~NOCACHE~~ ~~DISCUSSION~~ ## 12.ディレクトリに置いたファイルを自動登録する 以下の流れで実現しています。 BeatsもLogstashも自動登録はバイナリファイル向きじゃないですね。 [[Aws:ElasticSearch:AutomaticallyRegisterFilesPlacedDirectory#失敗事例|バイナリファイル向きじゃない理由]] ### 成功事例 ■処理の流れ ファイル配置→Logstash→ShellScript→ElasticSearch ■処理イメージ図 {{:Aws:ElasticSearch:pasted:20210728-091947.png?direct 800x0}} #### Logstash.conf ・input:読み込んだバイナリファイルが改行して複数messageとして扱われないようにmultilineで1つの処理につながるようにしています。 ・filter:outputでmessageが出るのを防ぐため、messageを削除しています。 ・output:読み込んだファイルパスをShellScriptに渡しています。 ※inputセクションの[close_older => 5]はとても大事で、読み込んだファイルがcloseしていないと後工程に進みません!!・・・デフォ値の1時間たてば進むか。。。 input { # stdin{} file{ path => "/tmp/filebeat/*" close_older => 5 #mode => "read" #file_completed_actionとセットで、読み込んだファイルを削除できますが、 #file_completed_action => "delete" #消えるタイミングがoutput処理前なのでコメントアウト start_position => "beginning" #sincedb_clean_after => "1 seconds" sincedb_path => "/dev/sincedb" codec => multiline { pattern => "^\s,^\S" #どんな行が来ても結合する正規表現らしい max_lines => 100000000000 #指定した行まで1つのmessageとする negate => true what => "previous" # charset => "BINARY" } } } filter { mutate { remove_field => [ "message" ] } urldecode { field => "path" } } output { exec { command => "bash /tmp/logstash.sh %{path}" } stdout{} } #### /tmp/logstash.sh [[Aws:ElasticSearch:RegisterJapaneseFile#投入データの加工、登録|Aws/ElasticSearch/11.日本語ファイルを登録する]]の処理をそのまま流用 #! /bin/bash file_path=$1 file=$(base64 $file_path | perl -pe 's/\n//g') echo -e "{ \"index\" : { \"_index\" : \"{インデックス名}\", \"_type\" : \"_doc\", \"_id\" : \"{ID}\", \"pipeline\": \"{pipeline名}\" }\n{ \"@timestamp\" : \"`date +'%Y-%m-%dT%H:%M:%S.%NZ'`\", \"data\" : \"$file\" }" > input.json curl -X POST -H 'Content-Type: application/json' '{Elasticsearchエンドポイント}/_bulk?pretty' --data-binary @input.json #### Template、Pipeline TemplateとPipelineは下記を参考に設定願います。 [[Aws:ElasticSearch:Template|Aws/ElasticSearch/3.Template]] [[Aws:ElasticSearch:Pipeline|Aws/ElasticSearch/4.Pipeline]] ### 失敗事例 #### その1 Logstashが受け取ったmessageをfilterセクションでbase64に変換して、outputでESに登録する。 ■ボツ理由 ・色々コーデックを試したが、正しいコーデックどれかわからなかった。 ・バイナリファイルをmultilineで繋げるとデータが壊れるらしい?どこかのサイトに書いてあった。 input { # stdin{} file{ path => "/tmp/filebeat/*" close_older => 5 #mode => "read" #file_completed_action => "delete" start_position => "beginning" #sincedb_clean_after => "1 seconds" sincedb_path => "/dev/sincedb" codec => multiline { pattern => "^\s,^\S" max_lines => 100000000000 negate => true what => "previous" charset => "BINARY" } } } filter { ruby { code => 'event.set("message", Base64.encode64(event.get("message")))' } mutate { gsub => ["message", "\r\n|\r|\n", ""] } } output { elasticsearch { hosts => ["{Elasticsearchエンドポイント}:443"] index => "{インデックス名}" document_type => "_doc" pipeline => "{pipeline名}" ilm_enabled => false } stdout { } } #### その2 [[Aws:ElasticSearch:AutomaticallyRegisterFilesPlacedDirectory#成功事例|成功事例]]の、outputセクションのexecでLogstashを呼び出す。 ■ボツ理由 ・テスト用端末のせいか、JAVAのエラーがでた。※もちろんpipelines.ymlは設定してあるぞ。 ・失敗事例その1でも書いたが、そもそもバイナリファイルをmultilineで繋げるとデータが壊れるらしい? input { # stdin{} file{ path => "/tmp/filebeat/*" close_older => 5 #mode => "read" #file_completed_action => "delete" start_position => "beginning" #sincedb_clean_after => "1 seconds" sincedb_path => "/dev/sincedb" codec => multiline { pattern => "^\s,^\S" max_lines => 100000000000 negate => true what => "previous" # charset => "BINARY" } } } filter { mutate { remove_field => [ "message" ] } urldecode { field => "path" } } output { exec { command => "bash base64 %{path} | perl -pe 's/\n//g' | grep ^ | /usr/share/logstash/bin/logstash -f logstash.conf" } stdout{} } {{tag>AWS Elasticsearch}}