自打 Centos 升级到版本7以后,无论是爱还是恨,每个人都不得不面对systemd。systemd由Lennart Poettering和freedesktoporg开发,立足于一款方便,快捷的服务项初始化工具管理工具。虽然systemd提高了初学者的使用复杂性,让熟悉service和/etc/init.d等System V init的人会感觉有点繁琐和不适应。但是相比较System V init Systemd确实更强大,系能也更高,依赖服务的处理更好。本文虫虫介绍给大家基于Systemd和D-bus实现实时在线服务信息的捕捉,并基于此利用Chronograf为监控前端仪表盘实现一个服务监控系统。

Systemd服务和 D-Bus 消息通讯

D-Bus可能大家都不熟悉,此处我们首先对其做个简单介绍。

D-Bus( inter-process communication bus ),中文进程间通信总线,和定义一样D-Bus用来管理注册在其上的应用程序,并且彼此之间互相通信的服务。D-Bus应用程序有D-Bus服务器端或客户端端构成。客户端连接到D-Bus服务器,注册该服务,然后服务器会给服务分配统一的标识,并负责监听该服务。D-Bus是Linux下非常有用的工具,通过该他可以实现对系统硬件(比如系统电源Upower和CPU温度的thermald)和Systemd等软件服务的监控。

Systemd在D-Bus上注册名为org.freedesktop.systemd1服务,当系统服务的状态随时间变化时,会向客户端发送一些信号。

我们检查系统是否已经安装D-bus可以使用

ps aux|grep dbus

利用busctl status来检查D-bus状态,并返回其配置

systemd服务在D-Bus上注册,并在Systemd服务有变化是发送消息。

当服务启动,停止或失败时,Systemd将总线上的信号广播给所有可用的客户端。我们可以通过下面命令,监听D-Bus的广播消息,并将其重定向到文件Chongchong.msg:

busctl monitor org.freedesktop.systemd1 >Chongchong.msg

我们ctrl+c关闭消息推送,然后查看Chongchong.msg文件,可以看到大量很多消息,方法调用,方法返回和信号。可以看到涉及的服务为httpd,它的状态数组下有一个ActiveState的键值为active,表示该服务转台为运行中。Systemd服务可以支持6种不同的状态:活动(active),重新加载(reloading),非活动(inactive),失败(failed),激活(activating),停用(deactivating)。当服务发出失败的信号时候,说明我们服务有故障了需要 告警 。我们构建的监控系统就是基于对这些服务状态信息进行捕捉和解析实现监控。

监控架构和实现

整体上监控很简单就是通过D-Bus客户端(golang实现)监听服务的消息,并存入InfluxDB数据库,然后通过Chronograf实现监控仪表盘。整体架构如下图:

首先,在监控机上运行dbus-daemon。然后我们运行一个利用Golang语言编写的简单的D-Bus客户端(也可以使用Python,Perl等其他语言)用来订阅D-bus上systemd的信号,并对这些信号进行解析取出我们关注的服务状态信息,并将信息存储到InfluxDB数据库中。

然后我们安装监控前端,利用Chronograf创建仪表板从InfluxDB为数据源获取服务和仪表的统计数据,来显示各个服务的当前运行状态。当服务失败时,通过Kapacitor(流处理引擎)接收失败信号,并自动发送告警邮件。

利用Golang编写D-Bus客户端

捕获来自systemd的信号的第一步是构建一个简单的客户端,它主要的作用是:

1.连接到总线。

2.订阅systemd信号。

3.解析并向InfluxDB发送监控数据。

关键代码如下:

函数getPoint()连接获取服务状态消息:

函数initInflux()连接Influx数据库:

函数getStateValue()转化服务状态(六种)的对应值-1~5:

数据库结构

对于我的InfluxDB数据结构,我们选择以服务名称作为标记( 索引 ),并将状态(失败,活动,激活..)作为值。

状态state,我们使用前面的getStateValue()转为了对应的整数-1,0,1,2,4,5便于后面的监控汇聚计算

利用Chronograf构建监控仪表板

之前的文章中,虫虫给大家介绍过使用Grafana构建仪表盘的监控方案。此处我们使用Chronograf来构建一个仪表板,向我们展示一些与我们的服务相关的统计数据以及我们关注的重要的服务图监控的重要服务的量表。如下图所示,仪表板有三个主要部分:

1.给定时间的活动,非活动和失败服务的计数(single-stat块)。

2.表格显示每项服务随时间变化的状态的历史记录。

3. 12个仪表显示重点监控的12种不同服务。

计算活动,非活动和失败的服务

首先是构建single-stat块的方法:

状态变化历史记录

以同样的方式,用下面的方法构建历史表的输入:

12种服务状态仪表盘

同样,通过一下方式构建每一个服务状态的仪表盘

反复多次可以,构建出我们需要的所有的服务状态仪表盘。整个监控前端页面部分就构建完成,最后是监控告警部分

监控告警

以前我们也说过了,华丽的监控前端和仪表盘只不过是个花瓶子而已,我们不可能时时盯着它,真正有用的是除了问题进行监控告警。本实例中告警我们使用Kapacitor,一个流处理引擎,用于服务失败时触发告警。

安装并运行Kapacitor,然后跳转到Chronograf告警面板。

单击”Manage Tasks”,会显示两个部分:alert rules和tick scripts。点击” Build Alert Rule “按钮创建一个新的告警规则。

此警报配置为在服务失败时(即状态值等于-1)触发告警。

总结

本文我们以Linux Systemd 服务和D-Bus消息总线为基础,通过构建Golang脚本实现对系统服务状态的实时采集和入库,并基于Chromograf构建监控前端仪表盘,最后基于Kapacitor实现了服务失败时候的监控告警。本文可以做为一个样板用来构建实际线上服务状态监控系统,当然更多的探索和实践需要大家动手尝试。