Как разобрать файл nagios status.dat? - PullRequest
4 голосов
/ 02 февраля 2009

Я бы хотел проанализировать файл status.dat для nagios3 и вывести его как xml с помощью скрипта python. 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
    }

Может иметь любое количество хостов, а хост может иметь любое количество сервисов.

Ответы [ 7 ]

9 голосов
/ 03 апреля 2010

Пфф, возьми себя в руки mk_livestatus. http://mathias -kettner.de / checkmk_livestatus.html

5 голосов
/ 23 февраля 2009

Nagiosity делает именно то, что вы хотите:

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

2 голосов
/ 10 февраля 2016

бесстыдно украденный из приведенных выше примеров, Вот сборка версии для Python 2.4, которая возвращает dict, содержащий массивы разделов 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')]
2 голосов
/ 16 февраля 2012

За последние несколько месяцев я написал и выпустил инструмент, который анализирует Nagios status.dat и objects.cache и строит модель, которая допускает некоторые действительно полезные манипуляции с данными Nagios. Мы используем его для управления внутренней панелью операций, которая является упрощенным «мини» Nagios. Он постоянно совершенствуется, и я пренебрегал тестированием и документацией, но код не слишком сумасшедший, и я чувствую, что за ним довольно легко следить.

Дайте мне знать, что вы думаете ... https://github.com/zebpalmer/NagParser

2 голосов
/ 05 июня 2010

Если вы немного доработаете решение 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-дом, это было бы здорово.

2 голосов
/ 02 февраля 2009

Вы можете сделать что-то вроде этого:

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')
2 голосов
/ 02 февраля 2009

Не знаю nagios и его конфигурационный файл, но структура кажется довольно простой:

# comment
identifier {
  attribute=
  attribute=value
}

, который можно просто перевести на

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

все содержится внутри тега корневого уровня .

Я не вижу разрывов строк в значениях. Есть ли в nagios многострочные значения?

Вам необходимо позаботиться о знаках равенства в значениях атрибутов, поэтому установите для своего регулярного выражения значение non-жадный.

...