How to parse nagios status.dat file?

前端 未结 7 1064
一生所求
一生所求 2020-12-21 02:06

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 re

相关标签:
7条回答
  • 2020-12-21 02:23

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

    0 讨论(0)
  • 2020-12-21 02:30

    Nagiosity does exactly what you want:

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

    0 讨论(0)
  • 2020-12-21 02:37

    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')]
    
    0 讨论(0)
  • 2020-12-21 02:37

    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.

    0 讨论(0)
  • 2020-12-21 02:45

    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.

    0 讨论(0)
  • 2020-12-21 02:46

    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')
    
    0 讨论(0)
提交回复
热议问题