Sirius' blog

黄沙百战穿金甲,不破楼兰誓不还

所谓 tig,就是指 telegraf,influxdb 以及 grafana 组成的一套工具链。telegraf 负责数据收集,influxdb 是数据库,负责数据存储和管理,grafana 则是可视化界面,查询 influxdb 中存储的数据并以可视化图表的形式展现出来。

之前豆豆搞过一个活动室的温湿度监控的系统,就是用的这套工具链,再加上受 mcwindy teeworlds Online 人数查询 bot 的启发,我觉得可以每隔一段时间查询各 mod 的人数记录下来,再用这套工具链表现人数的变化。

首先是写脚本,mcwindy 的那套脚本是 js 的,而且我不需要那么多功能,索性就自己用 python 写了一个,就是用 status.tw 的 api 查询全部服务器信息。因为 status.tw 做了 bot 的检测,所以要加一个 UA,否则会 403。

从 api 拿到的数据首先转换成 json,然后提取出其中国服的数据,将各 mod 的人数加起来,存储到事先准备好的 dict 里面。目前的方法会导致入流量很大,因为会拿到所有服务器的数据,之后可能研究一下 api 只拿国服的数据可能会好一些。

data2 = data.read().decode()
jdata = json.loads(data2)
for i in jdata['servers']:
    if i['country'] == 'China': # and len(i['players']) != 0:
        try:
            num_player[i['gamemode']] += len(i['players'])
        except KeyError:
            num_player[i['gamemode']] = len(i['players'])

然后再计算一下总人数,再把 dict 按照 json 格式打印出来就行。

服务器是 Debian 10,源里面是没有 telegraf 和 grafana 的,要自己去下 deb:telegrafgrafana。然后从源里安装 influxdb 和 influxdb-client。

influxdb 要设置一个 admin 和普通用户,后者用来给 telegraf 写数据。毕竟是放在公网上面的服务,还是加个权限比较好。

create user admin with password <password> with all privileges; 
create user telegraf with password <password>;
grant [READ,WRITE,ALL] on telegraf to telegraf;

然后改 telegraf 的配置,要改用户名和密码,然后要把 net 插件的注释去掉

[[inputs.net]]
   interfaces = ["eth0"]

自己写的收集数据的脚本可以用 exec 插件,在 /etc/telegraf/telegraf.d/ 下建立一个配置文件:

[[inputs.exec]]
  commands = ["python3 /path/to/script/getnum.py"]
  interval = "60s"
  timeout = "60s"
  data_format = "json"
  name_suffix = "player_num"

由于脚本输出的是 json 格式,所以 data_format 设置为 “json”。

之后重启 telegraf。

Grafana 安装之后启动,可以访问 <服务器 IP>:3000 来查看(也可以在 /etc/grafana/grafana.ini 里更改端口),别忘了防火墙放行 3000 端口。默认用户名和密码都是 admin,登录后会要求更改密码。在设置里添加数据源,选择 influxdb。

Grafana 有很多现成的模板,比如 928。可以选用现成的模板也可以自己添加 panel import_template

添加 panel 是比较复杂的一个过程,也可以参考现有的模板,另外 net 插件收集到的 byte_recv 和 byte_sent 数据是流量统计,因此要统计带宽占用的话需要对其求导,之前这里卡了很久。Panel 的添加都是通过图形界面完成的,添加完成后在 grafana.ini 中去掉 anonymous 的注释,其他人就可以无需登录就能查看图表:

[auth.anonymous]
enabled = true
org_name = Main Org.

这是我做的图表,统计了 teeworlds 各 mod 的人数和我管理的那台服务器的统计数据:Teeworlds Dashboard

截图如下:

grafana screenshot

更新:

后面增加了其他 teeworlds 机器的监控,因此使用 variable 做了根据主机过滤,但由于主机名很多都是些随机字符串,不方便直接根据主机名进行查看,找了一下,在这个网址找到了解决办法:

首先在 influxdb 中建立一个 measurement,如名为 Hostname,用于存储主机名和 alias 的对应关系:

insert Hostname,value=[hostnameA],text=[aliasA] count=1 0
insert Hostname,value=[hostnameB],text=[aliasB] count=1 0
...

之后建立两个变量,一个用于显示的变量和一个隐藏的用于查询的变量:

用于显示的变量的查询语句(Server):

SHOW TAG VALUES From Hostname WITH KEY = "text"

用于查询的变量的查询语句(alias):

SHOW TAG VALUES FROM Hostname WITH KEY = "value" WHERE "text"=~ /$Server/

之后在 query 中选择 Host =~ /^$alias$/,在一些需要显示当前机器的地方使用 $Server 即可。