Logstash の output elasticsearch ブロック内で if 分岐して index 名を動的に変更したい

現在、client (elastic-agent) => Logstash (整形) => Elasticsearch という構成を検証しています。

複数のサーバからまず elastic-agent (filebeats) で Logstash サーバ向けにログを転送、
Logstash サーバでは必要に応じて filter を行って Elasticsearch へ送信、
ということを考えています。

以下のような設定をしようとしたところ、syntax error になってしまいました。
output の elasticsearch ブロックの中では event の内容などは使えないのでしょうか?

input {
  elastic_agent {
    port => 5044
    enrich => none
  }

}

filter {
  if "test" in [tags] {
    ruby {
      path => "/path/to/test.rb"
    }
  }
}

output {
  elasticsearch {
    hosts => [
      "https://host1.example.com:9200",
      "https://host2.example.com:9200",
      "https://host3.example.com:9200"
    ]
    if "test" in [tags] {
      index => "test-%{+YYYY.MM.dd}"
    } else {
      index => "default-%{+YYYY.MM.dd}"
    }
    user => "username"
    password => "password"
  }
}

エラーメッセージ

Expected one of [ \\t\\r\\n], \"#\", \"=>\" at line 28, column 8 (byte 449)

なお、同様の if 文を elasticsearch ブロックの中ではなく外に記載した場合は期待通りに index 名を分けることができたのですが、
それだと index 毎に elasticsearch ブロックを記載する必要が出てしまい、なんとか index 名だけ動的に変更したいと考えています。

各バージョン

  • Elasticsearch : 8.12.1
  • Logstash : 8.13.0
  • elastic-agent : 8.13.0

Try:

output {
  elasticsearch {
    if "test" in [tags] {
      hosts => [ "https://host1.example.com:9200", "https://host2.example.com:9200", "https://host3.example.com:9200"  ]
      index => "test-%{+YYYY.MM.dd}"
      user => "username"
      password => "password"
    } 
    else {
      hosts => [ "https://host1.example.com:9200", "https://host2.example.com:9200", "https://host3.example.com:9200"  ]
      index => "default-%{+YYYY.MM.dd}"
      user => "username"
      password => "password"
    }
  }
}

No change, it seems.

[2024-04-02T10:17:19,694][ERROR][logstash.agent           ] Failed to execute action {:action=>LogStash::PipelineAction::Create/pipeline_id:elastic-agent, :exception=>"LogStash::ConfigurationError", :message=>"Expected one of [ \\t\\r\\n], \"#\", \"=>\" at line 23, column 8 (byte 285) after output {\n  elasticsearch {\n    if ", :backtrace=>["/usr/share/logstash/logstash-core/lib/logstash/compiler.rb:32:in `compile_imperative'", "org/logstash/execution/AbstractPipelineExt.java:239:in `initialize'", "org/logstash/execution/AbstractPipelineExt.java:173:in `initialize'", "/usr/share/logstash/logstash-core/lib/logstash/java_pipeline.rb:48:in `initialize'", "org/jruby/RubyClass.java:931:in `new'", "/usr/share/logstash/logstash-core/lib/logstash/pipeline_action/create.rb:49:in `execute'", "/usr/share/logstash/logstash-core/lib/logstash/agent.rb:386:in `block in converge_state'"]}

以下のような形で自己解決しました

input {
  elastic_agent {
    port => 5044
    enrich => none
  }

}

filter {
  if "test" in [tags] {
    ruby {
      path => "/path/to/test.rb"
    }
    mutate {
      "add_field" => { "index_name" => "test" }
    }
  } else {
    mutate {
      "add_field" => { "index_name" => "default" }
    }
  }
}

output {
  elasticsearch {
    hosts => [
      "https://host1.example.com:9200",
      "https://host2.example.com:9200",
      "https://host3.example.com:9200"
    ]
    index => "%{index_name}-%{+YYYY.MM.dd}"
    user => "username"
    password => "password"
  }
}

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