Logstash如何匹配API输入数据与服务器本地CSV文件数据
问题根因
你当前配置匹配失败核心是3个逻辑错误:
- 未区分输入源事件:HTTP接口传入的API数据、file插件读取的CSV行数据是两类完全独立的事件,会异步单独进入filter阶段。CSV行事件只有
server/os字段,没有API返回的[result][host]字段;API事件只有接口返回的JSON结构,没有server/os字段,原有相等判断永远无法成立,所有事件都会被drop规则丢弃。 - 字段取值路径错误:API返回的
result是数组类型,直接取[result][host]拿不到值,正确路径是取数组第一个元素的[result][0][host]。 - 匹配逻辑设计错误:逐事件判断字段相等的逻辑,根本无法实现“静态CSV映射表和动态API请求数据”的关联,没有任何时序保证能让同一时间点进入filter的两个事件字段刚好匹配。
优化方案
用translate过滤器预加载CSV映射关系到内存,启动时直接完成server到OS的键值映射加载,API请求进入时直接查内存字典匹配即可,完全规避跨事件匹配的时序问题,稳定性更高。
优化后完整配置
input{ http{ host => "*****" port => "****" type => "api_input" # 确保自动解析JSON请求体 codec => "json" } } filter { # 只处理API输入的事件,跳过其他无关事件 if [type] == "api_input" { # 提取数组中实际的host字段值 mutate { add_field => { "match_host" => "%{[result][0][host]}" } } # 加载CSV映射表做匹配 translate { field => "match_host" target => "OS_Name" # 指向你的CSV文件路径 dictionary_path => "/etc/logstash/conf.d/Event.csv" # 指定CSV格式,列顺序和文件内一致:第一列是匹配键(server),第二列是返回值(os) dictionary_type => "file" file_type => "csv" csv_options => { "col_sep" => "," } # 匹配不到时OS_Name置空,也可以按需设置默认值 fallback => "Unknown" # 按需配置CSV刷新间隔,单位秒,设为300就是每5分钟重载一次CSV更新 refresh_interval => 300 } # 可选:如果不需要保留临时字段和原始冗余字段可以删除 mutate { remove_field => ["match_host", "headers", "@version"] } } } output { # 只输出匹配成功的API事件 if [type] == "api_input" and [OS_Name] != "Unknown" { stdout { codec => rubydebug } } }
配置说明
- 移除了原配置中把CSV作为事件流输入的逻辑,避免大量无关CSV行事件进入pipeline占用资源
- 给HTTP输入明确指定JSON编解码,确保接口返回的结构能被正确解析
- 先提取API返回数组内的host值作为匹配键,直接从预加载的内存映射表中查对应的操作系统信息,匹配无时序依赖
- 支持CSV文件动态刷新,不需要重启Logstash就能更新映射关系
- 过滤掉匹配失败的事件和冗余字段,输出内容更干净
测试验证
用你提供的样例API数据{"result":[{"host":"server_4","parameter":"22"}]}请求HTTP监听端口,会输出如下结果,正确匹配server_4对应的Windows系统:
{ "result" => [ [0] { "host" => "server_4", "parameter" => "22" } ], "@timestamp" => 2024-XX-XXTXX:XX:XX.XXXZ, "OS_Name" => "Windows", "type" => "api_input" }
内容的提问来源于stack exchange,提问作者samrathal
相关产品推荐
相关产品推荐

