How to parse nagios status.dat file?

给你一囗甜甜゛ 提交于 2019-11-29 14:50:36

Nagiosity does exactly what you want:

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

Pfft, get yerself mk_livestatus. http://mathias-kettner.de/checkmk_livestatus.html

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.

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

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.

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

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')]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!