侧边栏壁纸
  • 累计撰写 176 篇文章
  • 累计创建 87 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

ELK使用Painless脚本字段获取nginx日志真实IP

Z先森
2023-07-24 / 0 评论 / 0 点赞 / 13 阅读 / 0 字 / 正在检测是否收录...

生产环境的来源IP有很多类,各种有CDN和没CDN的,所以日志里面存在下面各种形式获取的IP:

  • $http_x_real_ip
  • $http_x_forwarded_for
  • $remote_addr

不同情况下真实IP的变量不一样,想要通过elk来做日志分析的话,可以使用Painless脚本字段来判断索引的字段内容来新增字段。 先列脚本内容:

if( doc['http_x_real_ip.keyword'].size() > 0 && doc['http_x_real_ip.keyword'].value != null ){
    return doc['http_baidu_cdn_real_ip.keyword'].value;
}else if ( doc['http_x_forwarded_for.keyword'].size() > 0 && doc['http_x_forwarded_for.keyword'].value != null ){
    return doc['http_x_forwarded_for.keyword'].value;
}else{
    return doc['remote_addr.keyword'].value;
}

坑一:

用来判断的字段不存在的时候会报错,比如http_x_real_ip.keyword不存在,那么es会报错,解决方案,先加一层判断: doc['http_x_real_ip.keyword'].size() > 0

坑二:

logstash传的值,如果事先预配了的话,grok的match不应该如下写: (?:(%{IPORHOST:http_x_real_ip}|%{DATA:http_x_real_ip})) 这样写的话,用null是匹配不到的,可以手动指定值为'-',如下: (?:(%{IPORHOST:http_x_real_ip}|-))

更新:

不需要从es上面的脚本字段处理,直接从logstash上面处理即可(由于日志逻辑做了个改变,舍弃了x_forward)

# 设置 real_ip 的值,如果 http_x_real_ip 不为空,则使用它;否则,使用 remote_addr 的值
if [http_x_real_ip] {
  mutate {
    add_field => { "real_ip" => "%{http_x_real_ip}" }
  }
} else {
  mutate {
    add_field => { "real_ip" => "%{remote_addr}" }
  }
}
0

评论区