【问题标题】:How to parse nagios status.dat file?如何解析 nagios status.dat 文件?
【发布时间】:2009-02-02 13:11:09
【问题描述】:

我想解析 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
    }

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

【问题讨论】:

    标签: python parsing nagios


    【解决方案1】:

    Pfft,获取你自己的 mk_livestatus。 http://mathias-kettner.de/checkmk_livestatus.html

    【讨论】:

    • 根据他们的文档,MK_Livestatus 避免了使用数据库的重复和开销。 “Livestatus 使用 Nagios Event Broker API 并将二进制模块加载到您的 Nagios 进程中。但与 NDO 不同的是,Livestatus 不会主动写出数据。相反,它会打开一个套接字,通过该套接字可以按需检索数据。” [英文调整编辑]它似乎得到定期更新。
    【解决方案2】:

    Nagioosity 完全按照您的意愿行事:

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

    【讨论】:

    • 根据他们的文档,Nagioity “采用 nagios 实时状态数据并作为 XML 输出。”自 2011 年以来一直没有更新,但它只是一个小的 python 脚本。
    【解决方案3】:

    从上面的例子中无耻地窃取, 这是 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')]
    

    【讨论】:

      【解决方案4】:

      不知道nagios及其配置文件,但结构看起来很简单:

      # comment
      identifier {
        attribute=
        attribute=value
      }
      

      可以简单地翻译成

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

      全部包含在根级 标记内。

      我没有在值中看到换行符。 nagios 有多行值吗?

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

      【讨论】:

        【解决方案5】:

        你可以这样做:

        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')
        

        【讨论】:

          【解决方案6】:

          如果您稍微调整 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,那就太棒了。

          【讨论】:

          • 太好了,谢谢!注意:您可以通过在 parseConf 开始时编译正则表达式将运行时间缩短一半。
          【解决方案7】:

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

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

          【讨论】:

          • 感谢您在 NagParser / nagparser / Services / nicetime.py 上的代码!我还发现了一个 perl one -liner 可以正确翻译日期,geekpeek.net/nagios-log-convert-timestamp。不过,在我的服务器上,它找到了许多 1969 年的日期 :)。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-22
          • 2021-06-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多