如何解析nagios status.dat文件?

发布于 2024-07-13 19:16:51 字数 3775 浏览 6 评论 0原文

我想解析 nagios3 的 status.dat 文件并使用 python 脚本输出为 xml。 xml 部分很简单,但是我该如何解析该文件呢? 使用多行正则表达式? 由于监控了许多主机和服务,该文件可能会很大,将整个文件加载到内存中是否明智?
我只需要提取具有关键状态的服务及其所属的主机。

任何帮助和正确方向的指出都将受到高度赞赏。

LE 该文件的外观如下:

########################################
#          NAGIOS STATUS FILE
#
# THIS FILE IS AUTOMATICALLY GENERATED
# BY NAGIOS.  DO NOT MODIFY THIS FILE!
########################################

info {
    created=1233491098
    version=2.11
    }

program {
    modified_host_attributes=0
    modified_service_attributes=0
    nagios_pid=15015
    daemon_mode=1
    program_start=1233490393
    last_command_check=0
    last_log_rotation=0
    enable_notifications=1
    active_service_checks_enabled=1
    passive_service_checks_enabled=1
    active_host_checks_enabled=1
    passive_host_checks_enabled=1
    enable_event_handlers=1
    obsess_over_services=0
    obsess_over_hosts=0
    check_service_freshness=1
    check_host_freshness=0
    enable_flap_detection=0
    enable_failure_prediction=1
    process_performance_data=0
    global_host_event_handler=
    global_service_event_handler=
    total_external_command_buffer_slots=4096
    used_external_command_buffer_slots=0
    high_external_command_buffer_slots=0
    total_check_result_buffer_slots=4096
    used_check_result_buffer_slots=0
    high_check_result_buffer_slots=2
    }

host {
    host_name=localhost
    modified_attributes=0
    check_command=check-host-alive
    event_handler=
    has_been_checked=1
    should_be_scheduled=0
    check_execution_time=0.019
    check_latency=0.000
    check_type=0
    current_state=0
    last_hard_state=0
    plugin_output=PING OK - Packet loss = 0%, RTA = 3.57 ms
    performance_data=
    last_check=1233490883
    next_check=0
    current_attempt=1
    max_attempts=10
    state_type=1
    last_state_change=1233489475
    last_hard_state_change=1233489475
    last_time_up=1233490883
    last_time_down=0
    last_time_unreachable=0
    last_notification=0
    next_notification=0
    no_more_notifications=0
    current_notification_number=0
    notifications_enabled=1
    problem_has_been_acknowledged=0
    acknowledgement_type=0
    active_checks_enabled=1
    passive_checks_enabled=1
    event_handler_enabled=1
    flap_detection_enabled=1
    failure_prediction_enabled=1
    process_performance_data=1
    obsess_over_host=1
    last_update=1233491098
    is_flapping=0
    percent_state_change=0.00
    scheduled_downtime_depth=0
    }

service {
    host_name=gateway
    service_description=PING
    modified_attributes=0
    check_command=check_ping!100.0,20%!500.0,60%
    event_handler=
    has_been_checked=1
    should_be_scheduled=1
    check_execution_time=4.017
    check_latency=0.210
    check_type=0
    current_state=0
    last_hard_state=0
    current_attempt=1
    max_attempts=4
    state_type=1
    last_state_change=1233489432
    last_hard_state_change=1233489432
    last_time_ok=1233491078
    last_time_warning=0
    last_time_unknown=0
    last_time_critical=0
    plugin_output=PING OK - Packet loss = 0%, RTA = 2.98 ms
    performance_data=
    last_check=1233491078
    next_check=1233491378
    current_notification_number=0
    last_notification=0
    next_notification=0
    no_more_notifications=0
    notifications_enabled=1
    active_checks_enabled=1
    passive_checks_enabled=1
    event_handler_enabled=1
    problem_has_been_acknowledged=0
    acknowledgement_type=0
    flap_detection_enabled=1
    failure_prediction_enabled=1
    process_performance_data=1
    obsess_over_service=1
    last_update=1233491098
    is_flapping=0
    percent_state_change=0.00
    scheduled_downtime_depth=0
    }

它可以拥有任意数量的主机,并且一个主机可以拥有任意数量的服务。

I'd like to parse status.dat file for nagios3 and output as xml with a python script.
The xml part is the easy one but how do I go about parsing the file? Use multi line regex?
It's possible the file will be large as many hosts and services are monitored, will loading the whole file in memory be wise?
I only need to extract services that have critical state and host they belong to.

Any help and pointing in the right direction will be highly appreciated.

LE Here's how the file looks:

########################################
#          NAGIOS STATUS FILE
#
# THIS FILE IS AUTOMATICALLY GENERATED
# BY NAGIOS.  DO NOT MODIFY THIS FILE!
########################################

info {
    created=1233491098
    version=2.11
    }

program {
    modified_host_attributes=0
    modified_service_attributes=0
    nagios_pid=15015
    daemon_mode=1
    program_start=1233490393
    last_command_check=0
    last_log_rotation=0
    enable_notifications=1
    active_service_checks_enabled=1
    passive_service_checks_enabled=1
    active_host_checks_enabled=1
    passive_host_checks_enabled=1
    enable_event_handlers=1
    obsess_over_services=0
    obsess_over_hosts=0
    check_service_freshness=1
    check_host_freshness=0
    enable_flap_detection=0
    enable_failure_prediction=1
    process_performance_data=0
    global_host_event_handler=
    global_service_event_handler=
    total_external_command_buffer_slots=4096
    used_external_command_buffer_slots=0
    high_external_command_buffer_slots=0
    total_check_result_buffer_slots=4096
    used_check_result_buffer_slots=0
    high_check_result_buffer_slots=2
    }

host {
    host_name=localhost
    modified_attributes=0
    check_command=check-host-alive
    event_handler=
    has_been_checked=1
    should_be_scheduled=0
    check_execution_time=0.019
    check_latency=0.000
    check_type=0
    current_state=0
    last_hard_state=0
    plugin_output=PING OK - Packet loss = 0%, RTA = 3.57 ms
    performance_data=
    last_check=1233490883
    next_check=0
    current_attempt=1
    max_attempts=10
    state_type=1
    last_state_change=1233489475
    last_hard_state_change=1233489475
    last_time_up=1233490883
    last_time_down=0
    last_time_unreachable=0
    last_notification=0
    next_notification=0
    no_more_notifications=0
    current_notification_number=0
    notifications_enabled=1
    problem_has_been_acknowledged=0
    acknowledgement_type=0
    active_checks_enabled=1
    passive_checks_enabled=1
    event_handler_enabled=1
    flap_detection_enabled=1
    failure_prediction_enabled=1
    process_performance_data=1
    obsess_over_host=1
    last_update=1233491098
    is_flapping=0
    percent_state_change=0.00
    scheduled_downtime_depth=0
    }

service {
    host_name=gateway
    service_description=PING
    modified_attributes=0
    check_command=check_ping!100.0,20%!500.0,60%
    event_handler=
    has_been_checked=1
    should_be_scheduled=1
    check_execution_time=4.017
    check_latency=0.210
    check_type=0
    current_state=0
    last_hard_state=0
    current_attempt=1
    max_attempts=4
    state_type=1
    last_state_change=1233489432
    last_hard_state_change=1233489432
    last_time_ok=1233491078
    last_time_warning=0
    last_time_unknown=0
    last_time_critical=0
    plugin_output=PING OK - Packet loss = 0%, RTA = 2.98 ms
    performance_data=
    last_check=1233491078
    next_check=1233491378
    current_notification_number=0
    last_notification=0
    next_notification=0
    no_more_notifications=0
    notifications_enabled=1
    active_checks_enabled=1
    passive_checks_enabled=1
    event_handler_enabled=1
    problem_has_been_acknowledged=0
    acknowledgement_type=0
    flap_detection_enabled=1
    failure_prediction_enabled=1
    process_performance_data=1
    obsess_over_service=1
    last_update=1233491098
    is_flapping=0
    percent_state_change=0.00
    scheduled_downtime_depth=0
    }

It can have any number of hosts and a host can have any number of services.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

素年丶 2024-07-20 19:16:51

Nagiosity 完全可以满足您的需求:

http://code.google.com/p/nagiosity/

Nagiosity does exactly what you want:

http://code.google.com/p/nagiosity/

深海里的那抹蓝 2024-07-20 19:16:51

无耻地窃取了上面的例子,
这是 Python 2.4 的版本构建,它返回一个包含 nagios 部分数组的字典。

def parseConf(source):
    conf = {}
    patID=re.compile(r"(?:\s*define)?\s*(\w+)\s+{")
    patAttr=re.compile(r"\s*(\w+)(?:=|\s+)(.*)")
    patEndID=re.compile(r"\s*}")
    for line in source.splitlines():
        line=line.strip()
        matchID = patID.match(line)
        matchAttr = patAttr.match(line)
        matchEndID = patEndID.match( line)
        if len(line) == 0 or line[0]=='#':
            pass
        elif matchID:
            identifier = matchID.group(1)
            cur = [identifier, {}]
        elif matchAttr:
            attribute = matchAttr.group(1)
            value = matchAttr.group(2).strip()
            cur[1][attribute] = value
        elif matchEndID and cur:
            conf.setdefault(cur[0],[]).append(cur[1])              
            del cur
    return conf

要获取具有以“devops”开头的联系人组的所有主机名称:

nagcfg=parseConf(stringcontaingcompleteconfig)
hostlist=[host['host_name'] for host in nagcfg['host'] 
          if host['contact_groups'].startswith('devops')]

Having shamelessly stolen from the above examples,
Here's a version build for Python 2.4 that returns a dict containing arrays of nagios sections.

def parseConf(source):
    conf = {}
    patID=re.compile(r"(?:\s*define)?\s*(\w+)\s+{")
    patAttr=re.compile(r"\s*(\w+)(?:=|\s+)(.*)")
    patEndID=re.compile(r"\s*}")
    for line in source.splitlines():
        line=line.strip()
        matchID = patID.match(line)
        matchAttr = patAttr.match(line)
        matchEndID = patEndID.match( line)
        if len(line) == 0 or line[0]=='#':
            pass
        elif matchID:
            identifier = matchID.group(1)
            cur = [identifier, {}]
        elif matchAttr:
            attribute = matchAttr.group(1)
            value = matchAttr.group(2).strip()
            cur[1][attribute] = value
        elif matchEndID and cur:
            conf.setdefault(cur[0],[]).append(cur[1])              
            del cur
    return conf

To get all Names your Host which have contactgroups beginning with 'devops':

nagcfg=parseConf(stringcontaingcompleteconfig)
hostlist=[host['host_name'] for host in nagcfg['host'] 
          if host['contact_groups'].startswith('devops')]
冷夜 2024-07-20 19:16:51

不知道 nagios 及其配置文件,但结构似乎非常简单:

# comment
identifier {
  attribute=
  attribute=value
}

它可以简单地转换为

<identifier>
    <attribute name="attribute-name">attribute-value</attribute>
</identifier>

根级中包含的所有内容。 标签。

我没有看到值中的换行符。 nagios 是否具有多行值?

您需要处理属性值中的等号,因此将正则表达式设置为非贪婪。

Don't know nagios and its config file, but the structure seems pretty simple:

# comment
identifier {
  attribute=
  attribute=value
}

which can simply be translated to

<identifier>
    <attribute name="attribute-name">attribute-value</attribute>
</identifier>

all contained inside a root-level <nagios> tag.

I don't see line breaks in the values. Does nagios have multi-line values?

You need to take care of equal signs within attribute values, so set your regex to non-greedy.

装迷糊 2024-07-20 19:16:51

你可以做这样的事情:

def parseConf(filename):
    conf = []
    with open(filename, 'r') as f:
        for i in f.readlines():
            if i[0] == '#': continue
            matchID = re.search(r"([\w]+) {", i)
            matchAttr = re.search(r"[ ]*([\w]+)=([\w\d]*)", i)
            matchEndID = re.search(r"[ ]*}", i)
            if matchID:
                identifier = matchID.group(1)
                cur = [identifier, {}]
            elif matchAttr:
                attribute = matchAttr.group(1)
                value = matchAttr.group(2)
                cur[1][attribute] = value
            elif matchEndID:
                conf.append(cur)
    return conf

def conf2xml(filename):
    conf = parseConf(filename)
    xml = ''
    for ID in conf:
        xml += '<%s>\n' % ID[0]
        for attr in ID[1]:
            xml += '\t<attribute name="%s">%s</attribute>\n' % \
                    (attr, ID[1][attr])
        xml += '</%s>\n' % ID[0]
    return xml

然后尝试做:

print   conf2xml('conf.dat')

You can do something like this:

def parseConf(filename):
    conf = []
    with open(filename, 'r') as f:
        for i in f.readlines():
            if i[0] == '#': continue
            matchID = re.search(r"([\w]+) {", i)
            matchAttr = re.search(r"[ ]*([\w]+)=([\w\d]*)", i)
            matchEndID = re.search(r"[ ]*}", i)
            if matchID:
                identifier = matchID.group(1)
                cur = [identifier, {}]
            elif matchAttr:
                attribute = matchAttr.group(1)
                value = matchAttr.group(2)
                cur[1][attribute] = value
            elif matchEndID:
                conf.append(cur)
    return conf

def conf2xml(filename):
    conf = parseConf(filename)
    xml = ''
    for ID in conf:
        xml += '<%s>\n' % ID[0]
        for attr in ID[1]:
            xml += '\t<attribute name="%s">%s</attribute>\n' % \
                    (attr, ID[1][attr])
        xml += '</%s>\n' % ID[0]
    return xml

Then try to do:

print   conf2xml('conf.dat')
記憶穿過時間隧道 2024-07-20 19:16:51

如果你稍微调整 Andrea 的解决方案,你可以使用该代码来解析 status.dat 和 objects.cache

def parseConf(source):
conf = []
for line in source.splitlines():
    line=line.strip()
    matchID = re.match(r"(?:\s*define)?\s*(\w+)\s+{", line)
    matchAttr = re.match(r"\s*(\w+)(?:=|\s+)(.*)", line)
    matchEndID = re.match(r"\s*}", line)
    if len(line) == 0 or line[0]=='#':
        pass
    elif matchID:
        identifier = matchID.group(1)
        cur = [identifier, {}]
    elif matchAttr:
        attribute = matchAttr.group(1)
        value = matchAttr.group(2).strip()
        cur[1][attribute] = value
    elif matchEndID and cur:
        conf.append(cur)
        del cur
return conf

有点令人费解的是为什么 nagios 选择对这些文件使用两种不同的格式,但是一旦你解析了它们对于一些可用的 python 对象,你可以通过外部命令文件做很多魔法。

如果有人有一个解决方案可以将其放入真正的 xml dom 中,那就太棒了。

If you slightly tweak Andrea's solution you can use that code to parse both the status.dat as well as the objects.cache

def parseConf(source):
conf = []
for line in source.splitlines():
    line=line.strip()
    matchID = re.match(r"(?:\s*define)?\s*(\w+)\s+{", line)
    matchAttr = re.match(r"\s*(\w+)(?:=|\s+)(.*)", line)
    matchEndID = re.match(r"\s*}", line)
    if len(line) == 0 or line[0]=='#':
        pass
    elif matchID:
        identifier = matchID.group(1)
        cur = [identifier, {}]
    elif matchAttr:
        attribute = matchAttr.group(1)
        value = matchAttr.group(2).strip()
        cur[1][attribute] = value
    elif matchEndID and cur:
        conf.append(cur)
        del cur
return conf

It is a little puzzling why nagios chose to use two different formats for these files, but once you've parsed them both into some usable python objects you can do quite a bit of magic through the external command file.

If anybody has a solution for getting this into a a real xml dom that'd be awesome.

爱你是孤单的心事 2024-07-20 19:16:51

在过去的几个月里,我编写并发布了一个工具,它可以解析 Nagios status.dat 和objects.cache,并构建一个模型,允许对 Nagios 数据进行一些真正有用的操作。 我们用它来驱动内部操作仪表板,这是一个简化的“迷你”Nagios。 它正在持续开发中,我忽略了测试和文档,但代码并不太疯狂,我觉得很容易理解。

让我知道你的想法...
https://github.com/zebpalmer/NagParser

For the last several months I've written and released a tool that that parses the Nagios status.dat and objects.cache and builds a model that allows for some really useful manipulation of Nagios data. We use it to drive an internal operations dashboard that is a simplified 'mini' Nagios. Its under continual development and I've neglected testing and documentation but the code isn't too crazy and I feel fairly easy to follow.

Let me know what you think...
https://github.com/zebpalmer/NagParser

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文