
大家好!
我想与您分享在Golang上编写Prometheus的导出器有多么容易,并用一个小程序的示例演示如何做到这一点,该程序监视当前TCP连接的地理位置。
0.免责声明
可以这么说,我想一开始就概述本出版物的范围,并说它没有说清楚,以便以后再没有问题:
- 是的,这不是客户的可视化。 这是远程连接的可视化。 也就是说,它不会将连接分为远程服务器发起连接的连接和本机发起的连接,而是将在地图上显示所有内容-例如,具有存储库的服务器,从此处将更新下载到您的计算机。
- 是的,我知道网络上有一些匿名工具可以隐藏客户端的真实IP。 该工具的目的不是要识别任何客户的确切GPS坐标,而是要至少了解他们的地理位置。
- whois提供的信息比IP地址所在的国家/地区更为准确,但是在这里,我与Grafan插件的限制联系在一起,该插件仅显示国家/地区,而不显示城市。
1.我们写“后端”:出口商在忙
因此,我们需要做的第一件事是编写一个出口商,该出口商实际上将从我们的服务器收集数据并将其发送给Prometheus。 语言的选择非常好:Prometheus拥有用于以多种流行语言编写导出程序的客户端库 ,但我选择Go,首先是因为它是如此“本地化”(因为Prometheus被写在上面),其次是因为它本身我在DevOps实践中使用。
足够好的歌词,让我们开始编写代码。 让我们开始写“自下而上”:首先,这些功能用于通过IP和远程IP地址列表确定国家,然后将其全部发送给Prometheus。
1.1。 我们通过IP地址确定国家
嗯,额头上绝对有所有东西,我没什么好想的 ,只是使用了freegeoip.net服务,在撰写本文时,其API已被弃用,现在他们提供免费注册,并且每月可以发出10,000个请求(这足以满足我们的目的) ) 一切都很简单:这里有一个http://api.ipstack.com/<IP>?access_key=<API_KEY>
形式的终结点,它仅向我们返回带有我们所需country_code
字段的country_code
这就是可视化所需的全部内容。
因此,让我们编写一个通过IP拉动国家的软件包。
我们导入必要的库,并创建一个结构,将生成的json对象“解压”到该结构中。 注意参数legacy=1
,我必须使用它来实现向后兼容; 当然,如果您使用他们的API,请使用最新版本。
在这里,我们将使用github.com/shirou/gopsutil/net
软件包并过滤掉处于ESTABLISHED
状态的连接,不包括本地IP地址和自定义黑名单中的地址,这些地址可以在启动时传递给导出器(例如,排除您自己的所有公共IP地址)
带有函数的包,返回地图[string] int:与国家/地区的连接数。 1.3。 最后,将所有内容发送给普罗米修斯
更准确地说,他本人将承担一切。 我们只听端口并提供收集的指标。
使用github.com/prometheus/client_golang/prometheus
创建一个Gauge
类型的度量。 实际上,您可以创建Counter
,然后我们将在查询数据库时使用rate
。 从Prometheus的角度来看,后者也许更有效,但是在我写这个出口商的时候(六个月前),我才刚开始熟悉Prometheus,而Gauge
对我来说已经足够了:
location = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "job_location", Help: "Location connections number", }, []string{"location"}, )
使用前面的段落收集了指标之后,我们更新了向量:
for code, number := range c.ConnectionsByCode { location.With(prometheus.Labels{"location": code}).Set(float64(number)) }
我们以一个单独的goroutine中的无限循环开始所有这一切,然后将端口绑定到主端口中,然后等待Prometheus获取我们的指标:
prometheus.MustRegister(location) http.Handle("/metrics", prometheus.Handler()) log.Fatal(http.ListenAndServe(*addr, nil))
实际上,所有代码都可以在GitHub的存储库中查看,我不想在这里连续复制所有内容。
2.“前端”:Grafana
但是首先,当然,您需要告诉Prometheus收集我们的指标:
- job_name: 'GeoIPExporter' scrape_interval: 10s static_configs: - targets: ['127.0.0.1:9300']
(或者,如果有Kubernetes,则使用服务发现)。 可以通过发送HUP
信号使Prometheus重新读取配置:
$ pgrep "^prometheus$" | xargs -i kill -HUP {}
我们在用户界面中转到它并检查是否已收集指标:

好的,现在轮到Grafan了。 我们使用必须预先安装的grafana-worldmap-panel
插件:
$ grafana-cli plugins install grafana-worldmap-panel
接下来,在用户界面中转到她,然后单击添加面板->世界地图面板。 在“指标”选项卡中,输入以下查询:
sum(job_location) by (location)
并指定图例格式: {{location}}
。 一切应该看起来像这样:

接下来,转到“世界地图”选项卡,并按照屏幕快照中的说明配置所有内容:

仅此而已! 享受我们的地图。
通过这种简单的方法,您可以在Grafan中绘制漂亮的连接图。
感谢您的关注,并期待您的评论。
待办
当然,为了将工具用于其预期目的,您需要完成它:过滤出本地子网的地址等等。 顺便说一句,如果有人感兴趣并想要开发此导出器-欢迎使用GitHub上的存储库!
友情链接