Commits

jordilin committed 07d23b9

slows down tailing upon alert trace

Comments (0)

Files changed (8)

log4client/src/log4tailer/__init__.py

     if options.screenshot and properties:
         printandshoot = notifications.PrintShot(properties)
         actions[0] = printandshoot
+    if options.slowdown:
+        actions.append(notifications.SlowDown(default_config.tail_context))
 
 
 def monitor(options, args, default_config, wait_for=time.sleep):

log4client/src/log4tailer/configuration.py

 
 import os
 from . import logcolors
+from . import strategy
 
 class DefaultConfig(object):
     def __init__(self):
         self.properties = None
         self.alt_config = os.path.expanduser('~/.log4tailer')
         self.post = False
+        self.tail_context = strategy.TailContext(self.throttle)

log4client/src/log4tailer/log4tail.py

     parser.add_option("--screenshot", action="store_true", dest="screenshot",
         help="takes a terminal screenshot whenever it finds an alertable log "
                 "trace")
+    parser.add_option("--slowdown", action="store_true", dest="slowdown",
+        help="throttles output for a second up to 5 consecutive tails")
+ 
     return parser.parse_args(argv)
 
 

log4client/src/log4tailer/logtailer.py

         self.pause = default_config.pause
         self.silence = default_config.silence
         self.actions = default_config.actions
-        self.throttleTime = default_config.throttle
         self.target = default_config.target
         self.properties = default_config.properties
         self.mailAction = None
         self._wait_for = wait_for
+        self.tail_context = default_config.tail_context
+        self.tail_context.throttle_time = default_config.throttle
 
     def addLog(self, log):
         self.arrayLog.append(log)
         message = Message(self.logcolors, self.target, self.properties)
         resume = self.resumeBuilder()
         self.posEnd()
-        get_log_lines = "readLines"
-        if self.throttleTime:
-            get_log_lines = "readLine"
         if self.silence:
             daemonize()
         try:
             curpath = ""
             while True:
                 found = 0
-                self._wait_for(self.throttleTime)
+                self._wait_for(self.tail_context.throttle_time)
                 for log in self.arrayLog:
                     curpath = log.path
                     if hasRotated(log):
                         found = 0
-                    lines = getattr(log, get_log_lines)()
+                    lines =  self.tail_context.get_trace(log)
                     if not lines:
                         # notify actions
                         message.parse('', log)

log4client/src/log4tailer/notifications.py

 from log4tailer.timing import Timer
 from smtplib import SMTP, SMTPServerDisconnected
 from log4tailer.termcolorcodes import TermColorCodes
+from log4tailer import strategy
 import subprocess
 from subprocess import PIPE
 import threading
     return winid
 
 
+class SlowDown(object):
+
+    Pullers = ['WARN', 'ERROR', 'FATAL', 'CRITICAL']
+    THROTTLE_TIME = 1
+    MAX_COUNT = 10
+
+    def __init__(self, tail_context):
+        self.tail_context = tail_context
+        self.counter = 0
+        self.triggered = False
+
+    def notify(self, message, log):
+        msg_level = message.messageLevel.upper()
+        if not message.isATarget() and msg_level not in self.Pullers:
+            if self.triggered:
+                self.counter += 1
+                if self.counter > self.MAX_COUNT :
+                    self.tail_context.change_tail_method(
+                            strategy.TailMultiLineMethod())
+                    self.tail_context.throttle_time = 0
+                    self.counter = 0
+                    self.triggered = False
+            return
+        self.counter = 0
+        self.triggered = True
+        self.tail_context.change_tail_method(strategy.TailOneLineMethod())
+        self.tail_context.throttle_time = self.THROTTLE_TIME
+
+
 class PrintShot(Print):
     """Prints log trace and takes
     an screenshot whenever we find an alertable

log4client/src/log4tailer/strategy.py

+class TailOneLineMethod(object):
+    def __init__(self):
+        self.read_method = "readLine"
+    
+    def get_trace(self, log):
+        return getattr(log, self.read_method)()
+
+
+class TailMultiLineMethod(object):
+
+    def __init__(self):
+        self.read_method = "readLines"
+
+    def get_trace(self, log):
+        return getattr(log, self.read_method)()
+        
+
+class TailContext(object):
+
+    def __init__(self, throttle_time, default_tail_method=TailMultiLineMethod):
+        self.tail_method = default_tail_method()
+        self.throttle_time = throttle_time
+
+    def change_tail_method(self, tail_method):
+        self.tail_method = tail_method
+
+    def get_trace(self, log):
+        return self.tail_method.get_trace(log)

log4client/tests/test_logtailer.py

                 'silence': False,
                 'mail': False,
                 'nomailsilence': False,
-                'screenshot': False}
+                'screenshot': False, 
+                'slowdown' : False}
         self._options_mocker_generator(options_mock, params)
         default_config = DefaultConfig()
         self.mocker.replay()
                 'inactivity': False,
                 'nomailsilence': False,
                 'post': False,
-                'screenshot': False}
+                'screenshot': False, 
+                'slowdown': False}
         self._options_mocker_generator(options_mock, params)
         default_config = DefaultConfig()
         self.mocker.replay()

log4client/tests/test_printnotification.py

 import unittest
 import sys
 from log4tailer.logfile import Log
+from log4tailer.strategy import TailContext
+from log4tailer.strategy import TailOneLineMethod
+from log4tailer.strategy import TailMultiLineMethod
 from log4tailer.message import Message
 from log4tailer.logcolors import LogColors
 from log4tailer import notifications
         return True
 
 
-class PropertiesTraceSpacing(object):
+class PropertiesTraceStub(object):
 
     def __init__(self):
         pass
     def get_value(self, key):
         if key == 'tracespacing':
             return 1
+        if key == 'slowdown':
+            # would slow down for 5 seconds
+            # one log trace/second
+            return 5
         return "false"
 
 
 
     def test_oneline_space_between_traces(self):
         sys.stdout = MemoryWriter()
-        notifier = notifications.Print(PropertiesTraceSpacing())
+        notifier = notifications.Print(PropertiesTraceStub())
         logtrace = "this is a log trace in red"
         message = MessageMock(logtrace)
         log = LogMock()
 
     def tearDown(self):
         sys.stdout = self.sysout
+
+
+class WaitForMock(object):
+
+    def __init__(self):
+        self.called = False
+
+    def __call__(self):
+        self.called = True
+
+
+class TailMethod(object):
+    def __init__(self):
+        pass
+
+    def get_trace(self, log):
+        return "hi"
+
+
+class OtherTailMethod(object):
+    """docstring for OtherTailMethod"""
+    def __init__(self):
+        pass
+
+
+class TailContextTestCase(unittest.TestCase):
+
+    def test_instantiates(self):
+        throttle_time = 0
+        context = TailContext(throttle_time, default_tail_method=TailMethod)
+        self.assertTrue(isinstance(context, TailContext))
+
+    def test_changes_tail_method(self):
+        throttle_time = 0
+        context = TailContext(throttle_time, default_tail_method=TailMethod)
+        context.change_tail_method(OtherTailMethod())
+        self.assertTrue(isinstance(context.tail_method, OtherTailMethod))
+
+    def test_get_trace(self):
+        throttle_time = 0
+        context = TailContext(throttle_time, default_tail_method=TailMethod)
+        trace = context.get_trace(DummyLog())
+        self.assertEqual(trace, "hi")
+
+
+class DummyLog(object):
+    def __init__(self):
+        pass
+
+    def readLine(self):
+        return "one line"
+
+    def readLines(self):
+        return "many lines"
+
+
+class TailOneLineMethodTestCase(unittest.TestCase):
+
+    def test_instantiates(self):
+        one_line_method = TailOneLineMethod()
+        self.assertTrue(isinstance(one_line_method, TailOneLineMethod))
+
+    def test_get_trace(self):
+        one_line_method = TailOneLineMethod()
+        self.assertTrue(one_line_method.read_method, "readLine")
+        trace = one_line_method.get_trace(DummyLog())
+        self.assertEqual(trace, "one line")
+
+
+class TailMultiLineMethodTestCase(unittest.TestCase):
+
+    def test_instantiates(self):
+        one_line_method = TailMultiLineMethod()
+        self.assertTrue(isinstance(one_line_method, TailMultiLineMethod))
+
+    def test_get_trace(self):
+        one_line_method = TailMultiLineMethod()
+        self.assertTrue(one_line_method.read_method, "readLines")
+        trace = one_line_method.get_trace(DummyLog())
+        self.assertEqual(trace, "many lines")
+
+
+class WarningMessage(object):
+    def __init__(self):
+        self.messageLevel = "warn"
+
+    def isATarget(self):
+        return False
+
+
+class NormalMessage(object):
+    def __init__(self):
+        self.messageLevel = "info"
+
+    def isATarget(self):
+        return False
+
+
+class SlowDownNotificationTestCase(unittest.TestCase):
+
+    def test_instantiates(self):
+        throttle_time = 0
+        context = TailContext(throttle_time)
+        slow_down = notifications.SlowDown(context)
+        self.assertTrue(isinstance(slow_down, notifications.SlowDown))
+
+    def test_notify_changes_tail_method(self):
+        throttle_time = 0
+        context = TailContext(throttle_time)
+        self.assertTrue(isinstance(context.tail_method, TailMultiLineMethod))
+        slow_down = notifications.SlowDown(context)
+        slow_down.notify(WarningMessage(), DummyLog())
+        self.assertTrue(isinstance(context.tail_method, TailOneLineMethod))
+
+    def test_notify_back_to_default_after_10_tails(self):
+        throttle_time = 0
+        context = TailContext(throttle_time)
+        self.assertTrue(isinstance(context.tail_method, TailMultiLineMethod))
+        slow_down = notifications.SlowDown(context)
+        notifications.SlowDown.MAX_COUNT = 1
+        slow_down.notify(WarningMessage(), DummyLog())
+        self.assertTrue(isinstance(context.tail_method, TailOneLineMethod))
+        slow_down.notify(NormalMessage(), DummyLog())
+        slow_down.notify(NormalMessage(), DummyLog())
+        self.assertTrue(isinstance(context.tail_method, TailMultiLineMethod))