fixbot/logwatch/sources.py
changeset 40 b9fdb7710768
parent 21 aa6df8f9c44a
child 48 ba101beeb062
equal deleted inserted replaced
39:e82b6df5baa3 40:b9fdb7710768
       
     1 from twisted.internet import reactor, protocol
       
     2 from twisted.python import log
       
     3 
       
     4 from fixbot import fifo
       
     5 
       
     6 class LogSource (object) :
       
     7     def __init__ (self, name, filters) :
       
     8         # set later on
       
     9         self.module = None
       
    10         
       
    11         # what filters to apply
       
    12         self.filters = filters
       
    13         
       
    14         # name, for display purposes
       
    15         self.name = name
       
    16 
       
    17         # used to gather data together into lines
       
    18         self.buf = ""
       
    19 
       
    20     def setModule (self, module) :
       
    21         self.module = module
       
    22 
       
    23     def handleError (self, msg) :
       
    24         log.err(msg)
       
    25         self.module.error(msg)
       
    26 
       
    27     def handleData (self, data) :
       
    28         data = self.buf + data
       
    29         
       
    30         while "\n" in data :
       
    31             line, data = data.split("\n", 1)
       
    32 
       
    33             self.handleLine(line)
       
    34 
       
    35         self.buf = data
       
    36 
       
    37     def handleLine (self, line) :
       
    38         log.msg("Matching line `%s'..." % line)
       
    39 
       
    40         for filter in self.filters :
       
    41             # let the filter process the line
       
    42             out = filter.test(line)
       
    43 
       
    44             if out :
       
    45                 # positive match, send
       
    46                 log.msg("\t%s: %s" % (filter.event_type, out))
       
    47                 self.module.sendEvent(filter.event_type, out)
       
    48 
       
    49                 break
       
    50 
       
    51             elif out is False :
       
    52                 # negative match, stop processing
       
    53                 return
       
    54 
       
    55             else :  # None
       
    56                 # no match
       
    57                 continue
       
    58 
       
    59 class File (LogSource, protocol.ProcessProtocol) :
       
    60     """
       
    61         Stream lines from a regular file using /usr/bin/tail -f
       
    62     """
       
    63 
       
    64     def __init__ (self, name, path, filters) :
       
    65         super(File, self).__init__(name, filters)
       
    66 
       
    67         self.path = path
       
    68 
       
    69         log.msg("spawning tail process for %s:%s" % (name, path))
       
    70 
       
    71         reactor.spawnProcess(self, "/usr/bin/tail", ["tail", "-n0", "--follow=name", path])
       
    72 
       
    73     def errReceived (self, data) :
       
    74         self.handleError("tail for %s: %s" % (self.name, data))
       
    75 
       
    76     def outReceived (self, data) :
       
    77         self.handleData(data)
       
    78 
       
    79     def processEnded (self, reason) :
       
    80         self.handleError("tail process for %s quit: %s" % (self.name, reason.getErrorMessage()))
       
    81 
       
    82 class Fifo (LogSource, fifo.Fifo) :
       
    83     """
       
    84         Stream lines from a fifo object.
       
    85     """
       
    86 
       
    87     def __init__ (self, name, path, filters) :
       
    88         LogSource.__init__(self, name, filters)
       
    89 
       
    90         log.msg("opening fifo for %s:%s" % (name, path))
       
    91 
       
    92         fifo.Fifo.__init__(self, path)
       
    93     
       
    94     def dataReceived (self, data) :
       
    95         self.handleData(data)
       
    96 
       
    97     def handleEOF (self) :
       
    98         self.handleError("!!! EOF on fifo %s, re-opening" % self.name)
       
    99         self.reopen()
       
   100     
       
   101     def connectionLost (self, reason) :
       
   102         super(Fifo, self).connectionLost(reason)
       
   103         self.handleError("lost fifo for %s: %s" % (self.name, reason.getErrorMessage()))
       
   104 
       
   105