背景:
ai引擎检测到的攻击数据会写入kafka,然后通过logstash采集到es,提供给安全人员做人工评判。因为攻击可能重复出现,所以我们希望攻击(url)中只出现一次。并且安全人员需要在攻击的基础上添加评论和判断结果(ai判断的攻击有可能是假的 有可能是真的,所以需要操作这个索引)
期望:
我们希望攻击第一次出现的时候写入es中,当后续再次出现相同攻击的时候,我们以url作为索引id,对之前的数据进行覆盖,保证一个攻击只出现一次。并且保证党安全人员对该条文档操作的时候,结果字段和评论字段保留不覆盖,其他字段可以覆盖
操作:
确定的一件事是把url作为索引中唯一的标识,保证索引唯一
如下

对于es来说id重复的话,之前的会被覆盖,整个流程是先根据id删除之前的 ,然后在新增一条新数据,这样的后果是如果安全人员在该条日志上做了评论,则重复的id会把评论字段覆盖掉。所以需要解决如下问题。
尝试一:
elasticsearch {
hosts => ["127.0.0.1:9201","127.0.0.1:9202","127.0.0.1:9203","127.0.0.1:9204"]
index => "http_attack_detection"
document_id => "%{id}"
action => "update"
}
输出中有个action字段,action的可选值为index,create,update,detele。默认为index。当时选择了update,但是发现采用update的时候会出现这种情况:
如果id存在,则覆盖,如果id不存在,则打印一条错误日志(不会影响logstash的运行)
这样的话实际上还是会覆盖,不能满足我们的要求
action
Value type is string
Default value is "index"
Protocol agnostic (i.e. non-http, non-java specific) configs go here Protocol agnostic methods The Elasticsearch action to perform. Valid actions are:
index: indexes a document (an event from Logstash).
delete: deletes a document by id (An id is required for this action)
create: indexes a document, fails if a document by that id already exists in the index.
update: updates a document by id. Update has a special case where you can upsert — update a document if not already present. See the upsert option. NOTE: This does not work and is not supported in Elasticsearch 1.x. Please upgrade to ES 2.x or greater to use this feature with Logstash!
尝试二:
elasticsearch的输出中添加doc_as_upsert => true
但是尝试之后发现
当id存在的时候会覆盖,当id不存的时候会新增,这样也不满足我们的需求。所以这种方法也不适合
尝试三:
我们不采用覆盖的方式,如果之前_id存在的话,直接抛弃掉新数据。这样的话评论之类的数据不会被覆盖。如果_id不存在的话 直接新增。
解决方案是把尝试一中的action由update改为create
这个方法解决了我们的问题

参考:https://www.elastic.co/guide/en/logstash/current/plugins-outputs-elasticsearch.html#plugins-outputs-elasticsearch-doc_as_upsert
网友评论