这次接到的需求是,可以根据用户的ip地址,实时展示在我们大中国的地图上。
被飞哥告知可以在EFK上实现,再经过一番调研,得出以下结论
-
目的效果图
image.png
- 在服务器上配置GEO插件。参考地址 https://github.com/y-ken/fluent-plugin-geoip
# for RHEL/CentOS
$ sudo yum groupinstall "Development Tools"
$ sudo yum install geoip-devel --enablerepo=epel
# for td-agent2
$ sudo td-agent-gem install fluent-plugin-geoip
- 配置td-agent文件
<filter nginx.**>
@type extract_query_params
key path
only url_path
discard_key true
add_url_path true
add_field_prefix params.
skip_adding_null_record true
</filter>
<filter nginx.**>
@type geoip
geoip_lookup_key remote
geoip_database /opt/td-agent/embedded/lib/ruby/gems/2.1.0/gems/fluent-plugin-geoip-1.2.0/data/GeoLiteCity.dat
geoip2_database /opt/td-agent/embedded/lib/ruby/gems/2.1.0/gems/fluent-plugin-geoip-1.2.0/data/GeoLite2-City.mmdb
<record>
city ${city.names.zh-CN["remote"]}
country ${country.iso_code["remote"]}
country_name ${country.names.zh-CN["remote"]}
location '[${location.longitude["remote"]},${location.latitude["remote"]}]'
</record>
</filter>
其中remote字段为解析出的ip地址。目前线上应该改为 http_x_forwarded_for字段。
注意,这里的filter必须分开写
最终输出location字段为解析出的经纬度。

- 配置elasticsearch
配置好以上需求后,直接打开Kibana的地图,会出现以下错误
No Compatible Fields: The "xxx" index pattern does not contain any of the following field types: geo_point
主要是因为,在Kibana中查看地图选项的数据源格式应该为geo-point。而现在生成的location数据为number类型,Kibana无法读取。
所以需要做以下配置。
-
首先,运行以下命令,查看mappings中的路径
image.png
可以看到mappings下的路径为fluentd。线上目前是_doc。
然后,执行以下代码,设置相应的模板,可以使后面生成的新的索引文件中,location的类型为geo-point。
PUT _template/logstash
{
"template": "logstash-*",
"mappings": {
"fluentd": {
"properties" : {
"location": { "type": "geo_point"}
}
}
}
}
至此已经设置完所有配置。接下来主要说哪里有坑。
第一次配置td-agent的时候,需要把location的字段注销,保证没有在新的索引文件生成之前没有任何number类型的location写入,否则,location的geo-point类型不生效。
等到第二天,再把location的注销取消,然后刷新Kibana中的index pattern就可以看到正常数据了!

至此,打完收工
网友评论