使用 document_id 将 logstash 输出到 elasticsearch;当我没有 document_id 时怎么办?

logstash output to elasticsearch with document_id; what to do when I don't have a document_id?

我有一些 logstash 输入,我在其中使用 document_id 删除重复项。但是,大多数输入没有 document_id。下面通过实际的 document_id 来探测,但如果它不存在,它会被接受为字面上的 %{document_id},这意味着大多数文档被视为彼此的副本。这是我的输出块的样子:

output {
        elasticsearch_http {
            host => "127.0.0.1"
            document_id => "%{document_id}"
        }
}

我想我可以在输出中使用条件。失败,错误在代码下方。

output {
        elasticsearch_http {
            host => "127.0.0.1"
            if document_id {
                document_id => "%{document_id}"
            } 
        }
}

Error: Expected one of #, => at line 101, column 8 (byte 3103) after output {
        elasticsearch_http {
    host => "127.0.0.1"
    if 

我尝试了几个 "if" 语句,但它们都失败了,这就是为什么我认为问题在于该块中有任何类型的条件。以下是我尝试过的替代方案:

if document_id <> "" {
if [document_id] <> "" {
if [document_id] {
if "hello" <> "" {

解决此问题的一种方法是确保 document_id 始终可用。您可以通过在过滤器部分添加一个 UUID filter 来实现此目的,如果 document_id 字段不存在,该字段将创建该字段。

filter {
    if "" in [document_id] {
        uuid {
            target => "document_id"
        }
    }
}

根据 Magnus Bäck 的建议进行了编辑。谢谢!

您接近条件性想法,但不能将其放入插件块中。改为这样做:

output {
  if [document_id] {
    elasticsearch_http {
      host => "127.0.0.1"
      document_id => "%{document_id}"
    } 
  } else {
    elasticsearch_http {
      host => "127.0.0.1"
    } 
  }
}

(但其他答案之一中使用 uuid 过滤器的建议也很好。)

参考:docinfo_fields

对于任何添加到 elasticsearch 中的文档,如果在插入期间未指定 _id,则会自动生成。我们稍后可以使用相同的 _id 来 update/delete/search 查询,方法是使用 docinfo_fields 功能。

示例:

filter {
    json {
        source => "message"
    }
    
    elasticsearch {
        hosts => "http://localhost:9200/"
        user => elastic
        password => elastic
        query => "..."
        docinfo_fields => {
          "_id" => "docid"
          "_index" => "document_index"
        }
    }
    if ("_elasticsearch_lookup_failure" not in [tags]) {
        #... doc update logic ...
    }
}
output {
    elasticsearch {
        hosts => "http://localhost:9200/"
        user => elastic
        password => elastic
        index => "%{document_index}"
        action => "update"
        doc_as_upsert => true
        document_id => "%{docid}"
    }
}