Beispiel #1
0
 def __init__(self, logfileName, patternDef):
     self.logfileName = logfileName
     self.parseTree = ParseTree()
     self.nodeMeta = {} # holds parseTree node metadata keyed by full node pathname
     self.log = None
     # each parser has it's own "compiled" pattern struct as it may contain logfile-specific
     #  {{var}} variable expansions
     self.patternSpec = PatternSpec(self, patternDef)
Beispiel #2
0
class Parser(object):
    "client log parser, instances maintain parsing state & parse tree for a given log file"

    def __init__(self, logfileName, patternDef):
        self.logfileName = logfileName
        self.parseTree = ParseTree()
        self.nodeMeta = {} # holds parseTree node metadata keyed by full node pathname
        self.log = None
        # each parser has it's own "compiled" pattern struct as it may contain logfile-specific
        #  {{var}} variable expansions
        self.patternSpec = PatternSpec(self, patternDef)

    def watchField(self, pattern, field):
        "sets a watchpoint on the given parseTree field for the given pattern"
        self.parseTree.watch(field, self._curryWatch(pattern))

    def _curryWatch(self, pattern):
        "generates a curried watchField callback function applied to the given pattern"
        def fieldChanged(parseTree, key, val):
            pattern.fieldChanged(parseTree, key, val)
        return fieldChanged

    def parse(self):
        "perform a parse on my logfile"
        # grab log copy
        with open(self.logfileName) as logfile:
            self.log = logfile.read()
        # read logfile line-by-line, match against pattern-spec
        with open(self.logfileName) as logfile:
            lineNo = 0
            line = logfile.readline()
            while line:
                line = line.strip()
                self.patternSpec.match(line, lineNo)
                line = logfile.readline()
                lineNo += 1
        # clean up
        self.patternSpec.endParse(lineNo)
        self.optimizeParseTree()

    ordinalRE = re.compile(r'\d\d\d')

    def optimizeParseTree(self):
        "optimize parse-tree - remove unneeded ordinal levels, turn ordinal-indexes into lists"
        def optimize(subtree):
            keys = subtree.keys()
            # look for keys that are 3-digit ordinals
            if keys:
                if all(self.ordinalRE.match(k) for k in keys):
                    if False and len(keys) == 1:
                        # single entry, elide level
                        return optimize(subtree[list(keys)[0]])
                    else:
                        # turn multi-entry into  list
                        return [optimize(subtree[k]) for k in sorted(keys)]
                else:
                    # non-ordinal index level, iterate keys & optimize subtrees
                    for k, v in subtree.items():
                        if isinstance(v, NameSpace):
                            subtree[k] = optimize(v)
                    return subtree
        self.parseTree = optimize(self.parseTree)