我的用户常常要求我对了解事件是否未发生负有同样的责任。
我总是不得不用 croned shell 脚本和大量日期边缘情况测试来构建自定义且脆弱的解决方案。
集中式日志记录应该能够以更好、更易于维护的方式掌握没有在过去 N 小时内发生。类似 logstash 通知和 nagios 警报。
更新
toppledwagon 的回答非常有帮助。o O(灯泡。)我现在有十几个批处理作业正在接受新鲜度检查。我想公正地对待他的全面回答,并跟进我如何实施他的想法。
我配置了 jenkins 来发出系统日志,logstash 会捕获它们并通过 nsca 向 nagios 发送状态更新。我还使用 check_mk 来确保 nagios 中的所有内容都是 DRY 且井井有条的。
Logstash 过滤器
:::ruby
filter {
if [type] == "syslog" {
grok {
match => [ "message", '%{SYSLOGBASE} job="%{DATA:job}"(?: repo="%{DATA:repo}")?$',
"message", "%{SYSLOGLINE}" ]
break_on_match => true
}
date { match => [ "timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ] }
}
}
神奇之处在于 grok 的 match 参数中的双模式对以及 break_on_match => true。Logstash 将依次尝试每个模式,直到其中一个匹配。
Logstash 输出
我们使用 logstash nagios_nsca 输出插件让 icinga 知道我们在 syslog 中看到了 jenkins 作业。
:::ruby
output {
if [type] == "syslog"
and [program] == "jenkins"
and [job] == "Install on Cluster"
and "_grokparsefailure" not in [tags] {
nagios_nsca {
host => "icinga.example.com"
port => 5667
send_nsca_config => "/etc/send_nsca.cfg"
message_format => "%{job} %{repo}"
nagios_host => "jenkins"
nagios_service => "deployed %{repo}"
nagios_status => "2"
}
} # if type=syslog, program=jenkins, job="Install on Cluster"
} # output
icinga (nagios)
最后,我们通过 nsca 到达了 icinga (nagios)。现在我们需要为每个我们想要注意到没有按时发生的作业定义被动服务检查。这可能有很多作业,所以让我们将check_mk
python 作业列表转换为 nagios 对象定义。
check_mk
就这么酷。
/etc/check_mk/conf.d/新鲜度.mk
# check_mk requires local variables be prefixed with '_'
_dailies = [ 'newyork' ]
_day_stale = 86400 * 1.5
_weeklies = [ 'atlanta', 'denver', ]
_week_stale = 86400 * 8
_monthlies = [ 'stlouis' ]
_month_stale = 86400 * 32
_service_opts = [
("active_checks_enabled", "0"),
("passive_checks_enabled", "1"),
("check_freshness", "1"),
("notification_period", "workhours"),
("contacts", "root"),
("check_period", "workhours"),
]
# Define a new command 'check-periodically' that sets the service to UKNOWN.
# This is called after _week_stale seconds have passed since the service last checked in.
extra_nagios_conf += """
define command {
command_name check-periodicaly
command_line $USER1$/check_dummy 3 $ARG1$
}
"""
# Loop through all passive checks and assign the new check-period command to them.
for _repo in _dailies + _weeklies + _monthlies:
_service_name = 'deployed %s' % _repo
legacy_checks += [(('check-periodicaly', _service_name, False), ['lead'])]
# Look before you leap - python needs the list defined before appending to it.
# We can't assume it already exists because it may be defined earlier.
if "freshness_threshold" not in extra_service_conf:
extra_service_conf["freshness_threshold"] = []
# Some check_mk wizardry to set when the check has passed its expiration date.
# Results in (659200, ALL_HOSTS, [ 'atlanta', 'denver' ]) for weeklies, etc.
extra_service_conf["freshness_threshold"] += [
(_day_stale, ALL_HOSTS, ["deployed %s" % _x for _x in _dailies] ),
(_week_stale, ALL_HOSTS, ["deployed %s" % _x for _x in _weeklies] ),
(_month_stale, ALL_HOSTS, ["deployed %s" % _x for _x in _monthlies] ),
]
# Now we assign all the other nagios directives listed in _service_opts
for _k,_v in _service_opts:
if _k not in extra_service_conf:
extra_service_conf[_k] = []
extra_service_conf[_k] += [(_v, ALL_HOSTS, ["deployed "]) ]
答案1
我在 nagios 中为各种事件设置了被动检查。然后在事件结束时,将被动检查发送到 nagios(通过包装器脚本或内置于事件本身中)。如果在 freshness_threshold 秒内未收到被动检查,它将在本地运行 check_command。check_command 设置为一个简单的 shell 脚本,它返回关键信息和服务描述信息。
我手边没有代码示例,但如果有兴趣的话我可以提供。
编辑一个添加的代码示例:
这假设您已经完成了 NSCA 和 send_nsca 的基本设置(确保客户端上的 send_nsca.cfg 和 nagios 服务器上的 nsca.cfg 中的密码和加密方法相同。然后在 nagios 服务器上启动 nsca 守护程序。)
首先,我们定义一个可供其他被动检查使用的模板。该模板将放入 services.cfg 中。
define service {
name standard-passive-service-template
active_checks_enabled 0
passive_checks_enabled 1
check_freshness 1
max_check_attempts 1
normal_check_interval 10
retry_check_interval 5
contact_groups sysadmins
notification_interval 0
notification_options w,u,c,r
notification_period 24x7
check_period 24x7
check_command check_failed!$SERVICEDESC$
register 0
}
这表示如果没有收到通知,则以 $SERVICEDESC$ 作为参数运行 check_failed。让我们在 command.cfg 中定义 check_failed 命令。
define command {
command_name check_failed
command_line /usr/lib/nagios/plugins/check_failed $ARG1$
}
这是/usr/lib/nagios/plugins/check_failed
脚本。
#!/bin/bash
/bin/echo "No update from $*. Is NSCA running?"
exit 2
根据 nagios,出口为 2 表示该服务至关重要(请参阅下文了解所有 nagios 服务状态)。采购/usr/lib/nagios/plugins/utils.sh
是另一种方式,那么您可以exit $STATE_CRITICAL
。但即使您没有这样做,上述方法也可以工作。
这会给出“NSCA 是否正在运行”的附加通知,因为可能是服务未正确签入,也可能是 NSCA 发生故障。这种情况比人们想象的更常见。如果同时收到多个被动检查,请检查 NSCA 是否存在问题。
现在我们需要一个被动检查来接受结果。在这个例子中,我有一个专门制作的 cron 作业,它知道我们环境中所有不同类型的 raid 控制器。当它运行时,它会向这个被动检查发送通知。在这个例子中,我不想在半夜被叫醒(根据需要编辑 notification_period。)
define service {
use standard-passive-service-template
hostgroup_name all
service_description raidcheck
notification_period daytime
flap_detection_enabled 1
freshness_threshold 7500 # 125 minutes
notification_options c
is_volatile 0
servicegroups raidcheck
}
现在有一个 cronjob 将信息发送回 nagios 服务器。以下是 /etc/cron.d/raidcheck 中的行
0 * * * * root /usr/local/bin/raidcheck --cron | /usr/sbin/send_nsca -H nagios -to 1000 >> /dev/null 2>&1
请man send_nsca
参阅选项,但重要的部分是“nagios”是我的 nagios 服务器的名称,也是打印在此脚本末尾的字符串。 send_nsca
期望在 stdin 上有一行形式(此处为 perl)
print "$hostname\t$check\t$state\t$status_info\n";
$hostname 很明显,$check 在这种情况下是“raidcheck”,$state 是 nagios 服务状态(0 = OK,1 = 警告,2 = 严重,3 = 未知,4 = 依赖。)并且 $status_info 是作为状态信息发送的可选消息。
现在我们可以在客户端的命令行上测试检查:
echo -e "$HOSTNAME\traidcheck\t2\tUh oh, raid degraded (just kidding..)" | /usr/sbin/send_nsca -H nagios
这为我们提供了一个 nagios 被动检查,该检查预计每 freshness_threshold 秒更新一次。如果检查未更新,则运行 check_command(在本例中为 check_failed)。上面的示例适用于 nagios 2.X 安装,但可能适用于 nagios 3.X(可能略作修改)。