Sensu相关概念详解

在前文中,我们通过一个实例配置对Sensu有了初步地了解,但是对其中的一些概念只是有一个模糊的印象,本文将对Sensu中的几个重要概念或者说是术语,进行详尽的介绍。

Sensu的设计中涵盖了一些自定义的概念,比如check、event、HandlerFilter等。

Check

Check是指在客户端运行的可执行程序,用于检测和监控客户端上的各种服务、资源和应用程序的运行状态等,比如监控HTTP的运行状态,或者收集机器的可用内存值。Check实际上是一个可执行的脚本,它的输出数据是STDOUT或者STDERR,并且在执行后会返回一个值来表示所检测内容的状态。通常使用0表示OK1表示WARNING2表示CRITICAL3以及更大的值表示UNKNOWN或其他用户自定义状态。Sensu的check配置和Nagios是相同的,因此Nagios中的Check插件可以直接在Sensu中使用。

根据Check的调度方式不同,可以分为发布/订阅模式,即由服务端来调度和推送check的执行请求,发布/订阅模式下的check则是在服务器端配置,在配置的时候需要为check设置订阅主题。当要执行该check时,服务器会根据订阅主题分发执行请求,所有订阅了相应主题的客户端会收到执行的请求,从而运行check程序。同样的,执行的返回结果也会通过消息队列返回给服务器;

另外一种是Standalone模式,该模式下的check直接在客户端进行配置,不需要服务器端发出执行的请求,可以根据配置的时间间隔在客户端自主执行,每次执行后会将结果通过消息队列返回给服务器。

Check定义参数

参数名称 描述 必填 类型 默认值 示例
type Check类型,standard/metric no String standard "type": "metric"
command 执行的check命令 true(除非配置了extension String "command": "check-process.rb -p cron"
extension 可以替换command使用,不常用 true(除非配置了command String "extension": "system_profile"
standalone 是否是standalone模式 false Boolean false "standalone": true
subscribers 订阅者 true(除非配置了standalone Array "subscribers": ["test"]
publish 是否发布 false Boolean true "publish": false
interval 执行周期 true(除非publish配为false,或者配置了cron Integer "interval": 60
cron 执行周期可以配置为cron表达式 true(除非publish配为false,或者配置了interval String "cron": "0 0 * * *"
timeout 超时时间 false Integer "timeout": 30
stdin 是否将检查结果写入到进程STDIN false Boolean false "stdin": true
auto_resolve 当Check由CRITICAL或者WARNING切换到OK状态时,是否自动清除之前产生的event,当需要手动清除时可以设置为false时 false Boolean true "auto_resolve": false
force_resolve 强制将event置为解决状态 false Boolean false "force_resolve": true
handle 是否处理Check产生的event false Boolean true "handle": true
handler 用来指定处理Check产生的event的handler的名称 false String "handler": "file"
handlers 可以同时指定多个handler false Array "handlers": ["file", "email"
truncate_output 是否对output进行截短,对metric类型的check默认为true,其他默认为false false Boolean false "truncate_output": false
truncate_output_length 设置output的最大长度,超过部分会截短 false Integer 255 "truncate_output_length": 1024

其他高级参数配置可以参考官方文档

Check配置

安装检测插件

脚本check-process.rb可以用于检测服务进程是否在运行,可以使用下面的命令在客户端进行安装。

1
sensu-install -p process-checks

发布/订阅模式示例

服务端新建文件/etc/sensu/conf.d/check_cron.json,文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
{
"checks": {
"cron": {
"command": "check-process.rb -p cron",
"subscribers": [
"test"
],
"interval": 60
}
}
}

该Check会发送到test订阅客户端上运行。
上一篇文章中已经使用了发布/订阅模式,这里基于之前搭建的系统,我们主要来讲下Standalone模式的Check。

Standalone模式示例

客户端新建文件/etc/sensu/conf.d/check_cron.json,文件内容如下:

1
2
3
4
5
6
7
8
9
{
"checks": {
"cron": {
"command": "check-process.rb -p cron",
"standalone": true,
"interval": 60
}
}
}

通过配置"standalone": true表明这是一个Standalone模式的Check,该Check会在客户端每60s运行一次。

不像发布/订阅模式,Standalone模式的Check在uchiwa页面是看不到的,只有在Check状态不正常时,在页面才会收到告警。

正常情况下的可以通过client端的日志查看Check的执行过程:

client端的Check日志

我们将Check中的cron进程修改为一个不存在的进程,再次观察,可以发现uchiwa页面可以收到Check告警信息:

uchiwa页面的告警信息

指标采集

Check还可以分为两种类型:标准采集standard和指标采集metric

  • 对于标准类型的check来说,Sensu不会在每次执行后都生成event,而只是在check所返回的结果为非0或者是从非0变为0的时候才会生成event。这样带来的好处是降低了负载,适用于那些只关注于非正常状态,而在正常的状态无需采取措施的监控场景。
  • 指标采集类型的check则会在每次执行后,无论其返回的结果是什么都会生成event。此类型的check一般用于获取监控指标的信息,除了check所返回的状态值,还有一些其它的输出信息可以通过event进行收集,然后返回给Sensu服务器。

之前我们接触的一致都是standard类型的check,比如HTTP状态、cron服务状态的监控等。下面我们来配置一个metric采集的Check。

安装采集插件

脚本metrics-cpu.rb用来采集和输出CPU指标,可以在客户端执行如下命令进行安装:

1
sensu-install -p cpu-checks

Check定义

在客户端新建文件/etc/sensu/conf.d/cpu_metrics.json,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
{
"checks": {
"cpu_metrics": {
"type": "metric",
"command": "metrics-cpu.rb",
"interval": 10,
"standalone": true,
"truncate_output": false,
"handler": "debug"
}
}
}

这里采用Standalone模式进行配置,另外参数truncate_output的设置为false的目的是不用截短output。因为指标采集的输出通常较长,默认会对output进行截短。也可以通过"truncate_output_length": 666设置output的长度。

指标采集结果

重启sensu-client服务后,可以在uchiwa页面看到指标采集结果。

指标采集结果

Check结果

Check结果结果是客户端再check执行完成后推送到Sensu transport中的JSON格式的数据,一般包含如下信息:

  • check定义相关,如command,subscribers,interval,name等,以及check输出
  • 客户端名称

  • check结果示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    {
    "client": "client66",
    "check": {
    "command": "/usr/lib64/nagios/plugins/check_http -I 127.0.0.1",
    "handler": "file",
    "name": "check_http",
    "issued": 1517317008,
    "executed": 1517317024,
    "duration": 0.006,
    "output": "HTTP OK: HTTP/1.1 200 OK - 289 bytes in 0.001 second response time |time=0.000647s;;;0.000000 size=289B;;;0\n",
    "status": 0
    }
    }

其中各个字段的含义为:

  • issued - check请求发出的时间
  • executed - 客户端执行check的时间
  • duration - 客户端执行check所耗时长
  • output - check命令的输出
  • status - check运行的退出状态码

Event

Sensu使用event来通知所监控内容的状态变化。比如当check执行后返回2,这表示所监控的内容出现了较为严重的问题,那么Sensu会生成event来报告这个问题,event会绑定一个或多个handler来对所报告的问题进行处理。event包含有一些上下文信息,即event data,主要包括执行check的客户端信息和check运行后的结果信息。通常event数据是以JSON格式传递的,以下是一个event的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
"event": {
"client": {
"name": "client66",
"address": "192.168.2.196",
"subscriptions": ["test",
"client:client66"],
"version": "1.2.0",
"timestamp": 1517148354
},
"check": {
"command": "/usr/lib64/nagios/plugins/check_http -I 127.0.0.1",
"interval": 10,
"subscribers": ["test"],
"name": "check_http",
"issued": 1517066088,
"executed": 1517148355,
"duration": 0.005,
"output": "connect to address 127.0.0.1 and port 80: 拒绝连接\nHTTP CRITICAL - Unable to open TCP socket\n",
"status": 2,
"type": "standard",
"history": ["2","2"],
"total_state_change": 0
},
"occurrences": 33,
"occurrences_watermark": 34,
"action": "create",
"timestamp": 1517066088,
"id": "9287299a-cebc-4708-893f-213257d105ca",
"last_state_change": 1517065768,
"last_ok": 1517065428,
"silenced": false,
"silenced_by": []
}

可以看到,event数据包含了Sensu客户端的基本信息,包括名称、IP等,同时也包含了所执行的check信息,客户端执行了该check并返回了状态值为2,同时输出内容HTTP CRITICAL: HTTP/1.1 503 Service Temporarily Unavailable,可以用来帮助handler对问题进行处理。

Event属性

属性 描述 类型 可取值 默认值
id event的唯一id String 任意的uuid
timestamp event的发生时间 Integer
action event动作 String create/resolve/flapping create
occurrences 已发生次数 Integer 1
check check结果和check相关属性 Hash
check.history check的历史退出状态,最多21个 Array
client 客户端属性 Hash
silenced 是否沉默 Boolean
silenced_by 匹配该event的沉默的、条目ID列表 Array

Handler

Sensu handler用于处理Sensu event,例如发生告警邮件,将采集指标存放到时序数据库等。Handler在check的配置文件中指定,可以同时指定多个handler对event进行处理。Sensu包括以下几种类型的handler

  • Pipe handler - 最常用,将event数据通过STDIN传递给处理程序;
  • TCP/UDP handler - 将event数据发送给一个远程的socket,如外部API;
  • Transport handler - 将数据发送给Sensu transport(默认为RabbitMQ
  • Set handler - 用于组成一个event handler集合,使得能够同时管理多个特定类型的event

默认handler

当check中没有指定handler时,Sensu会尝试使用default的handler,若没有定义名为default的handler,Sensu会在日志中报错。

handler配置

安装插件

1
2
wget -O /etc/sensu/plugins/event-file.rb http://sensuapp.org/docs/1.2/files/event-file.rb
chmod +x /etc/sensu/plugins/event-file.rb

由于event-file.rb需要Ruby运行环境,因此需要安装相关依赖:

1
yum install ruby ruby-devel

定义handler

这里以pipe类型为例,新增文件/etc/sensu/conf.d/event_file.json,内容如下:

1
2
3
4
5
6
7
8
9
10
{
"handlers": {
"file": {
"command": "/etc/sensu/plugins/event-file.rb",
"type": "pipe",
"timeout": 10,
"severities": ["critical", "unknown"]
}
}
}

TCP/UDP handler示例

下面的示例定义了一个TCP handler,会将event数据转发到定义的socket上。

1
2
3
4
5
6
7
8
9
10
11
12
{
"handlers": {
"example_tcp_handler": {
"type": "tcp",
"timeout": 30,
"socket": {
"host": "10.0.1.99",
"port": 4444
}
}
}
}

Transport handler示例

该handler会将event数据推送到名为example_handler_queue的Sensu transport,其他组件可以通过订阅该消息队列来处理该event。

1
2
3
4
5
6
7
8
9
10
11
{
"handlers": {
"example_transport_handler": {
"type": "transport",
"pipe": {
"type": "direct",
"name": "example_handler_queue"
}
}
}
}

Set handler示例

相当于一个handler的结合,在check中引用时就可以通过notify_all_the_things来引用其中定义的多个handler。

1
2
3
4
5
6
7
8
9
10
11
12
{
"handlers": {
"notify_all_the_things": {
"type": "set",
"handlers": [
"file",
"example_tcp_handler",
"example_transport_handler"
]
}
}
}

handler属性

属性 描述 是否必须 类型 可取值 默认值
type 类型 true String pipe/tcp/udp/transport/set
filter 过滤器 false String
filters 可以同时配置多个过滤器 false Array
severities 定义处理哪个级别的event false Array ok/warning/critical/unknown
mutator 转换器 false String
timeout 超时时长,只在pipetcp中适用 false Integer 10
handle_silenced 是否处理沉默的event false Boolean false
handle_flapping 是否处理跃动状态的event false Boolean false
command handler的执行命令 true(type==pipe String

Filter

Sensu Filter用来过滤一些Sensu event。Filter会检查event中的数据和定义的过滤规则是否匹配,然后判断是否将event发送给handler。需要注意的是filter只能针对单个的handler配置有效,在handler set配置中是无效的。

Filter处理流程

  • Sensu在处理event时,会检查handler的定义文件,在执行handler之前,会先执行该handler配置的filter,若配置了多个filter,会顺序执行;
  • 将filter属性和event数据进行比较;
  • 若filter将event删除了,那么之后就不会有的分析和处理

Filter分类

Sensu filter包含两种过滤方式:Inclusive包含和Exclusive排除。

  • 包含式:默认的处理方式,只有符合filter定义的event才会被处理,可以用个参数"negate": false设置,如果同时使用多个,需要同时满足(x AND y AND z)才会处理
  • 排除式:会过滤掉符合filter定义的event,可以用个参数"negate": true设置

包含方式指定的是含有相应信息的event才会被发送至handler
排除方式则相反,含有指定信息的event会被过滤掉,不会被发送到handler进行处理。值得注意的是,可以同时指定多个filter,此时event需要同时匹配所有指定的filter规则。

Filter示例

Filter属性直接比较

该filter会匹配数据中包含客户端属性"environment": "test"的event。

1
2
3
4
5
6
7
8
9
10
11
12
{
"filters": {
"production_filter": {
"negate": false,
"attributes": {
"client": {
"environment": "test"
}
}
}
}
}

处理状态改变的event

下面定义的filter可以用来匹配状态变化的event,因为在每次event状态改变时,occurrences的数值都会被重置,或者event的actionresolve状态,因为当check结果状态由非00时出action会切换到resolve状态。

1
2
3
4
5
6
7
8
9
10
{
"filters": {
"state_change_only": {
"negate": false,
"attributes": {
"occurrences": "eval: value == 1 || ':::action:::' == 'resolve'"
}
}
}
}

重复event的处理

下面的filter用来匹配check时间间隔是60s,并且occurrences!=1,即不是第一次发生(或者发生次数不能被60整除)。需要注意的是这里配置的是一个Exclusive类型的filter,即匹配的将会被过滤。即该过滤器的目的是对check间隔是60s并且在第一次发生时以及每小时进行处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"filters": {
"filter_interval_60_hourly": {
"negate": true,
"attributes": {
"check": {
"interval": 60
},
"occurrences": "eval: value != 1 && value % 60 != 0"
}
}
}
}

还有我们之前用的例子,仅处理出现次数大于5的event:

1
2
3
4
5
6
7
8
9
{
"filters": {
"recurrence": {
"attributes": {
"occurrences": "eval: value > 5"
}
}
}
}

仅处理工作时间的event

仅处理周一到周五9点到17点的event。

1
2
3
4
5
6
7
8
9
10
{
"filters": {
"nine_to_fiver": {
"negate": false,
"attributes": {
"timestamp": "eval: [1,2,3,4,5].include?(Time.at(value).wday) && Time.at(value).hour.between?(9,17)"
}
}
}
}

Filter配置属性

属性 描述 是否必须 类型 默认值
negate 配置是否会移除符合filter的event false Boolean false
attributes 用来和event数据比较的属性 true Hash
when 何时使用该filter false Hash

when使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"filters": {
"offhours": {
"attributes": {
"client": {
"environment": "production"
}
},
"when": {
"days": {
"all": [
{
"begin": "5:00 PM",
"end": "8:00 AM"
}
],
"friday": [
{
"begin": "12:00 PM",
"end": "5:00 PM"
}
]
}
}
}
}
}

Mutator

Sensu Mutators用来转换event数据,然后将转换后的数据传递给event handler。通过使用Mutator对event数据进行处理,可以减少重复代码,简化事件处理过程。Mutator在Sensu服务器端执行,从STDIN接收JSON格式的event数据,并将转换后的数据写入STDOUT。Mutator会返回一个退出状态码用于标识转换是否成功。如果Mutator执行失败,事件将不会被handler处理,并且会将错误信息记录到日志中。

Sensu监控处理流程

如图所示,Sensu的监控流程如下:

  • Sensu ServerSensu Client一个Service Check请求
  • Sensu Client来执行Service Check
  • Service Check会发出状态信息和检测数据作为check结果
  • Sensu Client将check结果发送到Sensu Transport(如redis, rabbitmq)
  • Sensu Server会对check结果进行处理,并将check的最新结果写入到Data Store,同事创建相应的event
  • Sensu Server会通过Event Handler来处理event
    • 通过Handler上定义的FilterHandler进行过滤
    • 处理Handler所绑定的Mutator
    • 最终执行Event Handler

Sensu的监控流程

hoxis wechat
一个脱离了高级趣味的程序员,关注回复1024有惊喜~
赞赏一杯咖啡
0%