# ログを4つのログに分割してElasticsearchに送る

**URL:** <https://discuss.elastic.co/t/4-elasticsearch/206889>\
**Category:** 日本語による質問・議論はこちら\
**Created:** [November 7, 2019, 4:49am UTC](https://discuss.elastic.co/t/4-elasticsearch/206889 "2019-11-07T04:49:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![keikei12](https://avatars.discourse-cdn.com/v4/letter/k/b5a626/32.png) [@keikei12](https://discuss.elastic.co/u/keikei12)\
**Post date:** [November 7, 2019, 4:49am UTC](https://discuss.elastic.co/t/4-elasticsearch/206889/1 "2019-11-07T04:49:33Z")

</div>

下記のようなログをlogstashで整形してElasticSearchに送りたいのですが可能でしょうか？  
＜ログのフォーマット＞  
日付:ログ種別△ログ1△△ログ2△△ログ3△△ログ4  
※△はタブです。

ログ1、ログ2、ログ3、ログ4とそれぞれ別のログとして  
elasticsearchに送りたいです。

---

<div class="post-metadata">

**Author:** ![tsgkdt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tsgkdt/32/39151_2.png) [@tsgkdt](https://discuss.elastic.co/u/tsgkdt)\
**Post date:** [November 7, 2019, 6:39am UTC](https://discuss.elastic.co/t/4-elasticsearch/206889/2 "2019-11-07T06:39:26Z")

</div>

こんにちわ。

LogstashのGrokとMutateとSplitのフィルターを組み合わせるとできるのではと思います。

- [https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html](https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html)
- [https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html#plugins-filters-mutate-split](https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html#plugins-filters-mutate-split)
- [https://www.elastic.co/guide/en/logstash/current/plugins-filters-split.html](https://www.elastic.co/guide/en/logstash/current/plugins-filters-split.html)

これを確認するために、簡易に標準入力に文字列を入れて確認してみる設定ファイルを以下に示します。

```ruby
input {
    stdin{}
}

filter {
   
    grok {
        # 日付:ログ種別△ログ1△△ログ2△△ログ3△△ログ4
        # △はタブとのこと
        match => { 
            # 文字列からログ１～４の部分をmultilogとして取り出す
            "message" => "%{TIMESTAMP_ISO8601:log.date}:%{WORD:log.type} %{GREEDYDATA:multilog}\r" 
        }
    }

    mutate {
        # 取得したログ１～４の部分を、arrayにする
        split => { "multilog" => " " }
    }
   # arrayにしたログ１～４をそれぞれ違うログとなるように分割する
    split {
        field => "multilog"
    }
}
 
output {
    stdout {}
}

```

標準入力で以下の文字列を入力します。

```auto
2019-09-16 13:20:10:hogelog aaa bbb ccc ddd

```

とすると、標準出力で以下のように出ます。  
1行の標準入力に対して、4つの出力がされていること、  
multilogのところをみると、aaa, bbb, ccc, dddとそれぞれの値が設定されていることが確認できるかと思います。

```auto
{
      "log.date" => "2019-09-16 13:20:10",
          "host" => "XXX-YYY-ZZZZZ",
      "log.type" => "hogelog",
       "message" => "2019-09-16 13:20:10:hogelog aaa bbb ccc ddd\r",
      "multilog" => "aaa",
    "@timestamp" => 2019-11-07T06:37:12.259Z,
      "@version" => "1"
}
{
      "log.date" => "2019-09-16 13:20:10",
          "host" => "XXX-YYY-ZZZZZ",
      "log.type" => "hogelog",
       "message" => "2019-09-16 13:20:10:hogelog aaa bbb ccc ddd\r",
      "multilog" => "bbb",
    "@timestamp" => 2019-11-07T06:37:12.259Z,
      "@version" => "1"
}
{
      "log.date" => "2019-09-16 13:20:10",
          "host" => "XXX-YYY-ZZZZZ",
      "log.type" => "hogelog",
       "message" => "2019-09-16 13:20:10:hogelog aaa bbb ccc ddd\r",
      "multilog" => "ccc",
    "@timestamp" => 2019-11-07T06:37:12.259Z,
      "@version" => "1"
}
{
      "log.date" => "2019-09-16 13:20:10",
          "host" => "XXX-YYY-ZZZZZ",
      "log.type" => "hogelog",
       "message" => "2019-09-16 13:20:10:hogelog aaa bbb ccc ddd\r",
      "multilog" => "ddd",
    "@timestamp" => 2019-11-07T06:37:12.259Z,
      "@version" => "1"
}

```

お試しください。

---

<div class="post-metadata">

**Author:** ![keikei12](https://avatars.discourse-cdn.com/v4/letter/k/b5a626/32.png) [@keikei12](https://discuss.elastic.co/u/keikei12)\
**Post date:** [November 8, 2019, 1:50am UTC](https://discuss.elastic.co/t/4-elasticsearch/206889/3 "2019-11-08T01:50:37Z")

</div>

ご回答ありがとうございました。  
確かにこの方法だとログを分割することはできそうです。

追加で質問となり申し訳ないのですが、この分割したログの中身をさらにフィルタしたいのですが、可能なのでしょうか？  
例えば、ログ１は「a△a△a」ログ2は「b△b△b」のような内容でタブ区切りになっています。これをフィルタしたいと考えています。  
いろいろ試してみているのですが、具体的な方法がわからないのが現状です。

---

<div class="post-metadata">

**Author:** ![tsgkdt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tsgkdt/32/39151_2.png) [@tsgkdt](https://discuss.elastic.co/u/tsgkdt)\
**Post date:** [November 8, 2019, 5:53am UTC](https://discuss.elastic.co/t/4-elasticsearch/206889/4 "2019-11-08T05:53:17Z")

</div>

どこまで試されたのか書かれていないので、既にお試しの方法かもしれません・・・

「a△a△a」のような文字をフィルタしてみたい、とのことですが、どのような結果になることを望んでいらっしゃいますか？  
この部分がないため、的外れになるかもしれませんがご容赦ください。

["a1", "a2", "a3"]のような配列にしたいのでしょうか？  
であれば、再度splitすることで対応できそうです。

```ruby
    #－－－－－－－－－－－－－－－－－－－中略－－－－－－－－
    mutate {
        split => { "multilog" => " " }
    }
    split {
        field => "multilog"
    }

    mutate {
        split => { "multilog" => " " } # ←今度はタブ１つ分で区切り文字としておく
    }

```

あるいは、「a△a△a」が「aaa△123△456789」のような場合、次のようにしたいのでしょうか？

```json
    "log_contents" : {
         "first_log" : "aaa",
        "second_log" : "123",
         "thrid_log" :"4566789"
    }

```

このような場合であっても、Splitのあとに同様にGrokを書いていただければ実現できるかと思います。

```ruby
    mutate {
        split => { "multilog" => " " }
    }
    split {
        field => "multilog"
    }

    grok {
        match => { "multilog" => "%{WORD:[log_contents][first_log]} %{WORD:[log_contents][second_log]} %{WORD:[log_contents][thrid_log]}" }
    }

```

grokフィルターの場合は、文字列の形式が不定である場合は困難があります。  
（上の例でいえば、タブ区切りで３つの要素という形式に限定されていますね）

ご参考になれば幸いです。

---

<div class="post-metadata">

**Author:** ![keikei12](https://avatars.discourse-cdn.com/v4/letter/k/b5a626/32.png) [@keikei12](https://discuss.elastic.co/u/keikei12)\
**Post date:** [November 8, 2019, 8:30am UTC](https://discuss.elastic.co/t/4-elasticsearch/206889/5 "2019-11-08T08:30:18Z")

</div>

ありがとうございます。  
ご指摘の通り。

- 

```
"log_contents" : {

```

- 

```
     "first_log" : "aaa",

```

- 

```
    "second_log" : "123",

```

- 

```
     "thrid_log" :"4566789"

```

- 

```
}

```

のように実現したかったです。  
ご指摘頂いたSplitのあとにGrokを書く方法を試していたのですが、  
想定した結果にならず、"\_grokparsefailure"と表示されてしまいました。

ログは下記になります。  
2019-09-16T13:20:22.789Z:hogelog△△a△a△a△△b△b△b△△c△c△c

---

<div class="post-metadata">

**Author:** ![tsgkdt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tsgkdt/32/39151_2.png) [@tsgkdt](https://discuss.elastic.co/u/tsgkdt)\
**Post date:** [November 11, 2019, 2:14am UTC](https://discuss.elastic.co/t/4-elasticsearch/206889/6 "2019-11-11T02:14:36Z")

</div>

grokparsefailureが出るとのことですが、Grokの書式があっているかどうか確認いただくのが良いと思います。

そのときには、KibanaのDevTools以下にあるGrok Debuggerや、[こちら](https://grokdebug.herokuapp.com/)が役立つかと思います。

Grok Patternのところには、タブ区切りで３つの要素が並んでいる形式を想定して以下のように書いています。

```auto
%{WORD:[log_contents][first_log]}\t%{WORD:[log_contents][second_log]}\t%{WORD:[log_contents][thrid_log]}

```

Simulateボタンを押すと、結果がペインに表示されます。（マッチしない場合はProvided Grok patterns do not match data in the inputというエラーが出る）

 ![image](https://us1.discourse-cdn.com/elastic/original/3X/3/5/354b2bbd58acc0a5fa3f5d1acdc8646f1c69e0bc.png)

今回はGrokパターンとして１つだけ、タブ区切りで３つに分けられる文字列があったとき、というものしか指定していません。  
このパターンにマッチしない場合は、grokparsefailureになります。  
他にもパターンがあるかどうか、もあわせて確認いただければと思います。

---

<div class="post-metadata">

**Author:** ![keikei12](https://avatars.discourse-cdn.com/v4/letter/k/b5a626/32.png) [@keikei12](https://discuss.elastic.co/u/keikei12)\
**Post date:** [November 15, 2019, 1:46am UTC](https://discuss.elastic.co/t/4-elasticsearch/206889/7 "2019-11-15T01:46:57Z")

</div>

ツールで確認したところパターンの記述が誤っていました。  
大変参考になりました。ありがとうございました。

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [December 13, 2019, 1:52am UTC](https://discuss.elastic.co/t/4-elasticsearch/206889/8 "2019-12-13T01:52:28Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
