2009-02-02 89 views
4

我想解析nagios3的status.dat文件,並用python腳本輸出爲xml。 xml部分很簡單,但我該如何解析文件?使用多行正則表達式? 由於許多主機和服務都受到監控,文件可能會很大,將整個文件加載到內存中是否明智?
我只需要提取具有嚴重狀態和所屬主機的服務。如何解析nagios status.dat文件?

任何幫助和指向正確的方向將受到高度讚賞。

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 
    } 

它可以有任意數量的主機和主機可以有任意數量的服務。

回答

5

Nagiosity不正是你想要什麼:

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

+0

按照他們的文檔,Nagiosity「採取Nagios的實時狀態達達和輸出XML。」它自2011年以來一直未更新,但它只是一個小型的Python腳本。 – AnneTheAgile 2014-08-02 20:07:58

2

不知道的Nagios和它的配置文件,但結構看起來很簡單:

# comment 
identifier { 
    attribute= 
    attribute=value 
} 

這可以簡單地翻譯成

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

都含有具有root級別內<的Nagios >標籤。

我在值中看不到換行符。 nagios是否有多行值?

您需要注意屬性值中的等號,因此請將您的正則表達式設置爲非貪婪。

2

你可以做這樣的事情:

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

Pfft,得到yerself mk_livestatus。 http://mathias-kettner.de/checkmk_livestatus.html

+0

根據他們的文檔,MK_Livestatus避免了使用數據庫的重複和開銷。 「Livestatus利用Nagios Event Broker API並將二進制模塊加載到您的Nagios進程中,但與NDO不同的是,Livestatus不會主動寫出數據,而是打開一個可根據需要檢索數據的套接字。」 [英文tweak-edited]似乎越來越定期更新。 – AnneTheAgile 2014-08-02 20:06:39

2

如果你稍微調整安德烈的解決方案,您可以使用該代碼來解析這兩個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,這將是非常棒的。

+0

太好了,謝謝!注意:通過在parseConf的開頭編譯正則表達式,可以將運行時間減半。 – abesto 2013-04-11 12:05:30

2

在過去的幾個月中,我編寫併發布了一個工具,用於解析Nagios status.dat和objects.cache,並構建一個模型,以便對Nagios數據進行一些非常有用的操作。我們用它來驅動一個簡化的'迷你'Nagios內部操作儀表板。它的持續發展和我忽略了測試和文檔,但代碼不是太瘋狂,我覺得很容易遵循。

讓我知道你在想什麼...... https://github.com/zebpalmer/NagParser

+0

我感謝您在NagParser/nagparser/Services/nicetime.py上的代碼!我還發現一個perl單線程可能會正確地翻譯日期,http://geekpeek.net/nagios-log-convert-timestamp/。在我的服務器上它通過:)找到許多1969年的日期。 – AnneTheAgile 2014-08-02 20:15:25

2

已經無恥地從上面的例子中被盜, 這裏有一個版本構建的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 

要獲得所有名稱的主機具有contactgroups與「DEVOPS」開頭:

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