Filebeatの再起動を伴わずにinput定義を追加したい

filebeatで再起動を伴わずにinput定義を追加する方法があるかどうかご教示ください。

<やりたいこと>
ログAをinputとして起動して、運用中に新しくログBを追加する際、サービス停止(filebeatの再起動)を伴わずに定義を追加したい。

下記のymlの設定でいうと、もともとログAの定義のみ設定されている状態で、filebeat再起動無しでログBの設定を追加したいです。

filebeat.inputs:

- type: log
  enabled: true
  paths:
    - /var/tmp/metatest.log   ※ログA
    - /var/tmp/filebeat/*.log ※ログB

filebeat.ymlは動的にリロード出来ない認識なのですが、実現する方法はありますでしょうか?
(モジュールを別に作成するような方法でしょうか)

ご認識の通り filebeat.yml自体のリロードはありませんが、input.configであれば設定ファイルを別に切り出すことで、実現可能かと思います。

https://www.elastic.co/guide/en/beats/filebeat/current/_live_reloading.html

上のサイトにあるように、filebeat.ymlを設定します。filebeat.ymlの中では type: logの設定は書きません。

pathには、リロードさせたい設定ファイルを書きます。ここではconfigフォルダの下にある*.ymlとしました。

#=========================== Filebeat inputs =============================

filebeat.config.inputs:
  enabled: true
  path: config/*.yml
  reload.enabled: true
  reload.period: 10s

次に config/log.ymlを作成します。さきほどpathで指定した対象となる設定ファイルです。

- type: log
  enabled: true
  paths:
    - C:\elastic\logs\1\*

(参考)
https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-configuration-reloading.html

このようにして、filebeatを実行すると、config/log.ymlの中身も評価されて実行されます。

そして、filebeat起動中に以下のように新しいInput先を追加して保存しても、リロードされて追加した先のファイルも取得対象になります。

- type: log
  enabled: true
  paths:
    - C:\elastic\logs\1\*
    - C:\elastic\logs\2_added\*

手元で動かしてみたところ、おっしゃるような内容は満たされるように思いました。
ご参考になれば幸いです。

ご回答ありがとうございます。ご教示頂いた方法で試したところ、想定通り実現できました。ありがとうございます。

追加で質問なのですが、マニュアルを見たところ、外部ファイルとして切り出せるのはinputの定義のみであるように思えます。

例えば、上記の例で、ログAはインデックスAに登録しており、後から追加したログBはインデックスBに登録したいという場合、外部ファイルでインデックス名の定義は可能でしょうか?
インデックス名の定義は、filebeat.ymlの「 Elasticsearch output」で行うため、外部への切り出しが出来ないのではと思っております。

おっしゃるように、ドキュメントでは filebeat.config.inputsかmodulesでreloadは有効とあり、outputは対象になっていないように見えます。

To enable dynamic config reloading, you specify the path and reload options under filebeat.config.inputs or filebeat.config.modules sections.

軽量なデータシッパーであることがウリなbeatsシリーズなので、再起動するのがもっとも確実かつ簡単だと思っておりますが、
どうしても外部から入れるIndex先を変更・指定したいということでしたら、
PipelineのIngest Processorを併用するのはどうでしょうか。

https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-ingest-processor-context.html

Side Effects
[ ctx['_index'] ](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/mapping-index-
field.html)
Modify this to change the destination index for the current document.

このように記載されているので、ctx['_index']を変更することで、Index名を動的に変更させることができるかと思います。
以下はサンプルですが、何かの条件に合致したらindex名をnew-indexにするPipelineの定義です。

PUT _ingest/pipeline/forum1128
{
    "processors": [
      {
        "script": {
          "source": """
            if (何かの条件) {
              ctx['_index'] = "new-index"
            }
          """
        }
      }
    ]
}

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

ありがとうございます。参考にさせて頂きます。

ご教示頂いたPipelineのIngest Processorを使用する際、「何かの条件」をタグ名にすることを検討しています。

外部ファイルを以下のようにし、タグが「1」だったらインデックス名を変更するようにしたいです

- type: log
  enabled: true
  paths:
    - /var/tmp/access.log
    - /var/tmp/error.log
  tags:
    - "1"

その際、Pipelineを以下のように定義したのですが、想定どおりとなりませんでした。

PUT _ingest/pipeline/forum1128
{
    "processors": [
      {
        "script": {
          "source": """
            if (ctx['tags'] == "1") {
              ctx['_index'] = "aaa-index"
            }
          """
        }
      }
    ]
}

おそらく、タグ名がうまく取得できていないと想定しており、いくつか書き方を試してみましたがいずれもうまくいきません。どのように定義すれば良いか、ご教示頂けないでしょうか

ちょうどtagsを使った例が公式サイトにもありますね。(not_prod_dropperのところです)
https://www.elastic.co/guide/en/elasticsearch/reference/master/ingest-conditional-complex.html

HOGEの部分を1と読み替えていただければ以下で動作が確認できるかと思います。

Ingest Pipelineの作成

PUT _ingest/pipeline/forum1128
{
    "processors": [
      {
        "script": {
          "source": """
            Collection tags = ctx.tags;
            if (tags != null && tags.contains("HOGE")){
                    ctx['_index'] = "new-index123"  
            }
          """
        }
      }
    ]
}

テスト

Pipelineにはシミュレート機能があるので、これでテストします。
tags自体が存在しないときや、条件に合致しないときも期待した動作となることを確認します。

POST _ingest/pipeline/forum1128/_simulate
{
  "docs": [
    {
      "_index": "filebeat",
      "_id": "id1",
      "_source": {
        "tags": [
          "HOGE",
          "BAR",
          "PIYO"
        ],
        "message": "aiueo"
      }
    },
    {
      "_index": "filebeat",
      "_id": "id2",
      "_source": {
        "tags": [
          "BAR",
          "PIYO"
        ],
        "message": "aiueo"
      }
    },
    {
      "_index": "filebeat",
      "_id": "id3",
      "_source": {
        "message": "aiueo"
      }
    },
    {
      "_index": "filebeat",
      "_id": "id4",
      "_source": {
        "tags": [
          "HOGE123",
          "BAR",
          "PIYO"
        ],
        "message": "aiueo"
      }
    },
    {
      "_index": "filebeat",
      "_id": "id5",
      "_source": {
        "tags": [],
        "message": "aiueo"
      }
    }
  ]
}
  • id1 -> HOGEが含まれるため、new-indexになる
  • id2 -> HOGEがないため、そのまま
  • id3 -> tagsフィールド自体が存在しないため、そのまま
  • id4 -> HOGE123はあるがHOGEではないため、そのまま
  • id5 -> tagsフィールドはあるが空要素のため、そのまま

以上です