通常,我的用户要求我同样负责知道事件是否尚未发生。
我总是不得不使用 cron'ed shell 脚本和大量的日期边缘案例测试来构建自定义和脆弱的解决方案。
集中式日志记录应该允许一种更好、更易于维护的方式来掌握过去 N 小时内没有发生的事情。诸如logstash 通知和nagios 警报之类的东西。
更新
toppledwagon 的回答非常有帮助。o O(灯泡。)我现在有十几个批处理作业正在检查新鲜度。我想让他彻底的回答公正,并跟进我是如何实施他的想法的。
我将 jenkins 配置为发出系统日志,logstash 捕获它们并通过 nsca 将状态更新发送到 nagios。我还使用 check_mk 来保持一切干燥并在 nagios 中组织。
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
冰糖 (nagios)
最后,我们通过 nsca 到达了 icinga (nagios)。现在,我们将需要为我们想要注意的每项工作定义的被动服务检查没有按时发生。这可能是很多工作,所以让我们使用check_mk
将 Python 工作列表转换为 nagios 对象定义。
check_mk
那样很酷。
/etc/check_mk/conf.d/freshness.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 "]) ]
我在 nagios 中为各种事件设置了被动检查。然后在事件结束时,将被动检查发送到 nagios(通过包装脚本或内置到事件本身中。)如果在 freshness_threshold 秒内未收到被动检查,它将在本地运行 check_command。check_command 设置为一个简单的 shell 脚本,它返回关键信息和服务描述信息。
我没有方便的代码示例,但如果可以的话,如果有兴趣的话。
编辑一个添加的代码示例:
这假设您已经完成了 NSCA 和 send_nsca 的基本设置(确保客户端上的 send_nsca.cfg 和 nagios 服务器上的 nsca.cfg 中的密码和加密方法相同。然后在 nagios 服务器上启动 nsca 守护程序。)
首先,我们定义一个模板,其他被动检查可以使用。这进入 services.cfg。
这表示如果没有收到通知,请使用 $SERVICEDESC$ 作为参数运行 check_failed。让我们在 commands.cfg 中定义 check_failed 命令。
这是
/usr/lib/nagios/plugins/check_failed
脚本。根据 nagios,退出 2 使该服务变得至关重要(请参阅下面的所有 nagios 服务状态。)采购
/usr/lib/nagios/plugins/utils.sh
是另一种方式,那么您可以exit $STATE_CRITICAL
。但是,即使您没有,上述方法也有效。这会给出“NSCA 是否正在运行”的附加通知,因为可能是服务未正确签入,或者可能是 NSCA 失败。这比人们想象的要普遍。如果同时进行多项被动检查,请检查 NSCA 是否存在问题。
现在我们需要一个被动检查来接受结果。在这个例子中,我有一个特制的 cron 作业,它知道我们环境中所有不同类型的 raid 控制器。当它运行时,它会向该被动检查发送通知。在这个例子中,我不想在半夜被吵醒(根据需要编辑 notification_period。)
现在有将信息发送回 nagios 服务器的 cronjob。这是 /etc/cron.d/raidcheck 中的行
查看
man send_nsca
选项,但重要的部分是“nagios”是我的 nagios 服务器的名称,以及在此脚本末尾打印的字符串。send_nsca
期望在形式的标准输入上有一行(此处为 perl)$hostname 很明显,在这种情况下 $check 是 'raidcheck',$state 是 nagios 服务状态(0 = OK,1 = 警告,2 = 关键,3 = 未知,4 = 依赖。)并且 $status_info 是可选的消息作为状态信息发送。
现在我们可以在客户端的命令行上测试检查:
这给了我们一个 nagios 被动检查,它期望每 freshness_threshold 秒更新一次。如果检查未更新,则运行 check_command(在这种情况下为 check_failed)。上面的示例适用于 nagios 2.X 安装,但可能适用于 nagios 3.X(可能稍作修改)。
不确定您所指的“事件没有发生”的类型可以采用不同的形式,它可以是有条件的或无条件的。例子:
如果你在第一种情况下并且需要一个开源工具,那么 SEC 中有一个Pairwithwindow规则,而 nxlog 中有一个Absence规则。(请注意,我隶属于后者)。
第二种更简单,两种工具都可以处理。