当事件没有发生时,管理员如何概括警报?

Dan*_*ite 6 monitoring nagios syslog logstash

我的用户经常要求我负责知道事件是否没有发生。

我总是不得不使用 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" ] }
  }
}
Run Code Online (Sandbox Code Playgroud)

神奇之处在于 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
Run Code Online (Sandbox Code Playgroud)

冰加(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 "]) ]
Run Code Online (Sandbox Code Playgroud)

top*_*gon 3

我在 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
}
Run Code Online (Sandbox Code Playgroud)

这表示如果没有收到通知,则运行 check_failed 并将 $SERVICEDESC$ 作为参数。让我们在commands.cfg 中定义check_failed 命令。

define command {
    command_name     check_failed
    command_line     /usr/lib/nagios/plugins/check_failed $ARG1$
}
Run Code Online (Sandbox Code Playgroud)

这是/usr/lib/nagios/plugins/check_failed脚本。

#!/bin/bash
/bin/echo "No update from $*. Is NSCA running?"
exit 2
Run Code Online (Sandbox Code Playgroud)

根据 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
}
Run Code Online (Sandbox Code Playgroud)

现在有一个 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
Run Code Online (Sandbox Code Playgroud)

请参阅man send_nsca参考资料 中的选项,但重要的部分是“nagios”是我的 nagios 服务器的名称以及在此脚本末尾打印的字符串。 send_nsca需要标准输入上的一行(此处为 perl)

print "$hostname\t$check\t$state\t$status_info\n";
Run Code Online (Sandbox Code Playgroud)

$hostname 是显而易见的,在本例中 $check 是“raidcheck”,$state 是 nagios 服务状态(0 = 正常,1 = 警告,2 = 严重,3 = 未知,4 = 依赖。)并且 $status_info 是可选的作为状态信息发送的消息。

现在我们可以在客户端的命令行测试检查:

echo -e "$HOSTNAME\traidcheck\t2\tUh oh, raid degraded (just kidding..)" | /usr/sbin/send_nsca -H nagios
Run Code Online (Sandbox Code Playgroud)

这为我们提供了 nagios 被动检查,预计每 freshness_threshold 秒更新一次。如果检查未更新,则运行 check_command (在本例中为 check_failed)。上面的示例适用于 nagios 2.X 安装,但可能适用于 nagios 3.X(可能需要进行细微修改)。