def test_levellistflush(self): log1 = Log('firstone.log') log2 = Log('secondone.log') logs = [log1, log2] resume = reporting.Resume(logs) reports = { 'TARGET': 0, 'TRACE': 0, 'DEBUG': 0, 'INFO': 0, 'WARN': 0, 'OTHERS': [], 'ERROR': [], 'FATAL': [], 'CRITICAL': [] } self.assertEquals(resume.logsReport['firstone.log'], reports) self.assertEquals(resume.logsReport['secondone.log'], reports) reports_firstone = resume.logsReport['firstone.log'] tobe_flushed_firstone = [ k for k in reports_firstone if isinstance(reports_firstone[k], list) ] resume.flushReport() flushed_firstone = [ k for k in reports_firstone if isinstance(reports_firstone[k], list) ] self.assertEquals(tobe_flushed_firstone, flushed_firstone)
def testshouldHaveItsOwnColor(self): fh = open('config','w') fh.write(self.logname+'='+'green\n') fh.close() properties = Property('config') properties.parse_properties() log = Log(self.logname,properties) log.openLog() self.assertTrue(log.ownOutputColor) log.closeLog() os.remove(self.config)
def testReportResumeForTwoDifferentLogs(self): log = Log('out.log') log2 = Log('out2.log') arrayLogs = [log, log2] fh = log.openLog() logcolors = LogColors() message = Message(logcolors) resume = reporting.Resume(arrayLogs) for anylog in arrayLogs: self.readAndUpdateLines(anylog, message, resume) outlogReport = resume.logsReport[log.path] expectedOutLogErrorReport = 'error> not so wrong' gotLogTrace = outlogReport['ERROR'][0].split('=>> ')[1] self.assertEquals(expectedOutLogErrorReport, gotLogTrace)
def test_unregister_method_for_shutdown(self): logcolors = LogColors() log = Log('anylog') poster = notifications.Poster(PropertiesStub(), http_conn=HttpConnStub) poster.registered_logs[log] = {'id': 5, 'logserver': 'anyserver'} body = poster.unregister(log) self.assertTrue(body)
def testShouldReportOtherNotifications(self): inactivity_mock = self.mocker.mock() inactivity_mock.alerting_msg self.mocker.count(1, None) self.mocker.result('Inactivity action detected') inactivity_mock.alerted self.mocker.count(1, None) self.mocker.result(True) def populate_log(): fh = open('out2.log', 'w') someLogTracesForLog = [ 'something here', 'something there', 'something somewhere' ] for line in someLogTracesForLog: fh.write(line + '\n') fh.close() populate_log() log = Log('out2.log') arrayLogs = [log] logcolors = LogColors() message = Message(logcolors) resume = reporting.Resume(arrayLogs) resume.add_notifier(inactivity_mock) self.mocker.replay() for anylog in arrayLogs: self.readAndUpdateLines(anylog, message, resume) outlogReport = resume.logsReport[log.path] expectedOthersReport = 'Inactivity action detected' gotLogTrace = outlogReport['OTHERS'][0].split('=>> ')[1] self.assertEquals(expectedOthersReport, gotLogTrace)
def test_flush_report_aftergaptime_daemonized(self): log = Log('out.log') arrayLogs = [log] logcolors = LogColors() message = Message(logcolors) resume = reporting.Resume(arrayLogs) resume.is_daemonized = True resume.gapTime = 0.05 for anylog in arrayLogs: self.readAndUpdateLines(anylog, message, resume) def overgap(): return resume.gapTime + 10 resume.timer.inactivityEllapsed = overgap resume.update(message, log) expected = { 'TARGET': 0, 'TRACE': 0, 'DEBUG': 0, 'INFO': 0, 'WARN': 0, 'OTHERS': [], 'ERROR': [], 'FATAL': [], 'CRITICAL': [] } outlogReport = resume.logsReport[log.path] self.assertEquals(expected, outlogReport)
def testshouldGetTupleOfOptionalParameters(self): log = Log('/var/log/messages',self.__createAConfigWithProperties()) ownColors, ownTargets, logpath = (log.ownOutputColor, log.patTarget, log.path) self.assertTrue(ownColors) self.assertTrue(ownTargets) self.assertTrue(logpath)
def testNotMarkMarkedNotMark(self): trace = "INFO this is an info trace" sys.stdout = MemoryWriter() logcolors = LogColors() termcolors = TermColorCodes() message = Message(logcolors) notifier = notifications.CornerMark(0.01) anylog = Log('out.log') message.parse(trace, anylog) padding = self.ttcols - len(notifier.MARK) output = padding * " " + termcolors.backgroundemph + notifier.MARK +\ termcolors.reset notifier.notify(message, anylog) self.assertFalse(sys.stdout.captured) def belowgap(): return 0 notifier.timer.corner_mark_ellapsed = belowgap trace = "FATAL there could be an error in the application" message.parse(trace, anylog) notifier.notify(message, anylog) self.assertTrue(sys.stdout.captured) self.assertEquals(output, sys.stdout.captured[0]) trace = "INFO this is an info trace" sys.stdout.flush() notifier.timer.corner_mark_ellapsed = overgap message.parse(trace, anylog) notifier.notify(message, anylog) self.assertFalse(sys.stdout.captured)
def test_shouldPost_if_alertable(self): logcolors = LogColors() logtrace = 'this is an error log trace' log = Log('anylog') message = Message(logcolors) message.parse(logtrace, log) poster = notifications.Poster(PropertiesStub(), http_conn=HttpConnStub) body = poster.notify(message, log) self.assertTrue(body)
def setUp(self): self.onelog = Log(self.log_name) onelogtrace = 'this is an info log trace' anotherlogtrace = 'this is a debug log trace' fh = open(self.log_name, 'w') fh.write(onelogtrace + '\n') fh.write(anotherlogtrace + '\n') fh.close() self.raise_count = 0
def setUp(self): self.mocker = mocker.Mocker() self.onelog = Log(self.log_name) onelogtrace = 'this is an info log trace' anotherlogtrace = 'this is a debug log trace' fh = open(self.log_name, 'w') fh.write(onelogtrace + '\n') fh.write(anotherlogtrace + '\n') fh.close() self.apicture = pjoin(TESTS_DIR, 'apicture.png')
def test_execute_if_targetMessage(self): logcolors = LogColors() logtrace = 'this is a target log trace' log = Log('anylog') message = Message(logcolors, target='trace') message.parse(logtrace, log) poster = notifications.Poster(PropertiesStub(), http_conn=HttpConnStub) poster.registered_logs[log] = {'id': 1, 'logserver': "anything"} body = poster.notify(message, log) self.assertTrue(body)
def test_printandshoot_notalertable(self): log_trace = 'this is an info log trace' log = Log('anylog') logcolors = LogColors() caller = SubProcessStubPopen() printandshoot = notifications.PrintShot(PropertiesStub(), caller=caller) message = Message(logcolors) message.parse(log_trace, log) printandshoot.notify(message, log) self.assertFalse(sys.stdout.contains(SubProcessStubPopen.msg))
def testnoNotification(self): pattern = re.compile(r'hi, this line to be notified') trace = "info this is just a log trace" notifier = notifications.Filter(pattern) sys.stdout = MemoryWriter() logcolors = LogColors() message = Message(logcolors) anylog = Log('out.log') message.parse(trace, anylog) notifier.notify(message, anylog) # assert is empty self.assertFalse(sys.stdout.captured)
def testShouldNotifyWithNoFullTrigger(self): logcolor = LogColors() message = Message(logcolor) log = Log('anylog') logpath = log.path command = 'echo' properties = PropertiesStub(command) trace = "this is a fatal log trace" executor = notifications.Executor(properties, trigger_executor=TriggerExecutorStub) trigger = executor._build_trigger(trace, logpath) self.assertEqual(['echo'], trigger)
def test_hostnameinconfig(self): logfile = 'out.log' fh = open(logfile, 'w') someLogTraces = ['FATAL> something went wrong', 'ERROR> not so wrong', 'WARN> be careful', 'DEBUG> looking behind the scenes', 'INFO> the app is running'] for line in someLogTraces: fh.write(line + '\n') fh.close() logcolors = LogColors() # using default colors termcolors = TermColorCodes() target = None notifier = notifications.Print(PropertiesMock()) message = Message(logcolors, target) log = Log(logfile) log.openLog() sys.stdout = MemoryWriter() hostname = socket.gethostname() for _ in range(len(someLogTraces)): line = log.readLine() line = line.rstrip() level = line.split('>') message.parse(line, log) output = (hostname + ': ' + logcolors.getLevelColor(level[0]) + line + termcolors.reset) notifier.notify(message, log) self.assertTrue(output in sys.stdout.captured) line = log.readLine() self.assertEqual('', line) message.parse(line, log) self.assertFalse(notifier.notify(message, log))
def testshouldNotColorizeifLevelKeyInaWord(self): # Testing boundary regex as for suggestion of # Carlo Bertoldi trace = "this is a logtrace where someinfoword could be found" sys.stdout = MemoryWriter() logcolors = LogColors() message = Message(logcolors) notifier = notifications.Print() anylog = Log('out.log') message.parse(trace, anylog) notifier.notify(message, anylog) self.assertEqual(trace, sys.stdout.captured[0]) self.assertEqual('', message.messageLevel)
def testShouldNotExecuteIfLevelNotInPullers(self): logcolor = LogColors() message = Message(logcolor) log = Log('anylog') command = 'anything %s %s' trace = "this is an info log trace" properties = PropertiesStub(command) executor = notifications.Executor(properties, trigger_executor=TriggerExecutorStub) message.parse(trace, log) executor.notify(message, log) len_captured_lines = len(sys.stdout.captured) self.assertEqual(len_captured_lines, 0)
def test_trace_level(self): level = 'TRACE' trace = "TRACE level for finer informational log traces than DEBUG" sys.stdout = MemoryWriter() logcolors = LogColors() termcolors = TermColorCodes() message = Message(logcolors) notifier = notifications.Print() anylog = Log('out.log') message.parse(trace, anylog) output = logcolors.getLevelColor(level) + trace + termcolors.reset notifier.notify(message, anylog) self.assertEqual(output, sys.stdout.captured[0])
def test_printandshoot_throws(self): log_trace = 'this is a very fatal log trace' log = Log('anylog') logcolors = LogColors() caller = SubProcessStubRaise() printandshoot = notifications.PrintShot(PropertiesStub(), caller=caller) message = Message(logcolors) message.parse(log_trace, log) try: printandshoot.notify(message, log) self.fail() except Exception, err: self.assertEqual(str(err), SubProcessStubRaise.msg)
def testWillMarkForSpecifiedTime(self): trace = "FATAL there could be an error in the application" sys.stdout = MemoryWriter() logcolors = LogColors() termcolors = TermColorCodes() message = Message(logcolors) notifier = notifications.CornerMark(10) anylog = Log('out.log') message.parse(trace, anylog) padding = self.ttcols - len(notifier.MARK) output = padding * " " + termcolors.backgroundemph + notifier.MARK +\ termcolors.reset notifier.notify(message, anylog) self.assertEqual(output, sys.stdout.captured[0])
def testnotify(self): pattern = re.compile(r'hi, this line to be notified') trace = "info hi, this line to be notified" level = "INFO" notifier = notifications.Filter(pattern) sys.stdout = MemoryWriter() logcolors = LogColors() termcolors = TermColorCodes() message = Message(logcolors) anylog = Log('out.log') message.parse(trace, anylog) notifier.notify(message, anylog) output = logcolors.getLevelColor(level) + trace + termcolors.reset self.assertEqual(output, sys.stdout.captured[0])
def testShouldColorizeWarningLevelAsWell(self): '''test that *warning* keyword gets colorized as well''' level = 'WARNING' trace = "WARNING there could be an error in the application" sys.stdout = MemoryWriter() logcolors = LogColors() termcolors = TermColorCodes() message = Message(logcolors) notifier = notifications.Print() anylog = Log('out.log') message.parse(trace, anylog) output = logcolors.getLevelColor(level) + trace + termcolors.reset notifier.notify(message, anylog) self.assertEqual(output, sys.stdout.captured[0])
def testTargetsNoColors(self): fh = open('config.txt','w') regexes = "log$; ^2009-10-12 got something here$" targetsline = "targets /var/log/messages = "+regexes+"\n" fh.write(targetsline) fh.close() property = Property('config.txt') property.parse_properties() self.assertEqual(regexes, property.get_value('targets /var/log/messages')) log = Log('/var/log/messages', property) color = log.logTargetColor.get(re.compile('log$')) self.assertFalse(color) os.remove('config.txt')
def test_printandshoot(self): log_trace = 'this is a fatal log trace' log = Log('anylog') logcolors = LogColors() caller = SubProcessStubPopen() printandshoot = notifications.PrintShot(PropertiesStub(), caller=caller) message = Message(logcolors) message.parse(log_trace, log) printandshoot.notify(message, log) colorized_logtrace = '\x1b[31mthis is a fatal log trace\x1b[0m' self.assertEqual(colorized_logtrace, sys.stdout.captured[0]) # in [1] has '\n', and [2] should have the result self.assertEqual(SubProcessStub.msg, sys.stdout.captured[2])
def testshouldFailColorizeWithBackground(self): trace = "FATAL there could be an error in the application" level = 'WARN' sys.stdout = MemoryWriter() logcolors = LogColors() termcolors = TermColorCodes() logcolors.parse_config(PropertiesBackGround()) message = Message(logcolors) notifier = notifications.Print() anylog = Log('out.log') message.parse(trace, anylog) output = logcolors.getLevelColor(level) + trace + termcolors.reset notifier.notify(message, anylog) self.assertNotEqual(output, sys.stdout.captured[0])
def testMessage(self): logcolors = LogColors() # using default colors termcolors = TermColorCodes() target = None notifier = notifications.Print() message = Message(logcolors, target) log = Log(self.logfile) log.openLog() sys.stdout = MemoryWriter() #testing Colors with default pauseModes for count in range(len(self.someLogTraces)): line = log.readLine() line = line.rstrip() level = line.split('>') message.parse(line, log) output = (logcolors.getLevelColor(level[0]) + line + termcolors.reset) notifier.notify(message, log) self.assertTrue(output in sys.stdout.captured) line = log.readLine() self.assertEqual('', line) message.parse(line, log) self.assertFalse(notifier.notify(message, log))
def testShouldExecuteIfTargetMessage(self): logcolor = LogColors() logfile = 'anylog' log = Log(logfile) command = "echo %s %s" trace = "this is an info log trace" trigger = ['echo', trace, logfile] properties = PropertiesStub(command) message = Message(logcolor, target='trace') message.parse(trace, log) executor = notifications.Executor(properties, trigger_executor=TriggerExecutorStub) executor.notify(message, log) self.assertEqual(TriggerExecutorStub.execute_msg, sys.stdout.captured[0])
def testMarkedTARGETOverMarkableLevel(self): logfile = "/any/path/out.log" trace = "this is a FATAL targeted log trace" sys.stdout = MemoryWriter() logcolors = LogColors() termcolors = TermColorCodes() notifier = notifications.CornerMark(0.02) anylog = Log(logfile, PropertiesStub()) message = Message(logcolors, properties=PropertiesStub) padding = self.ttcols - len(notifier.MARK) output = padding * " " + termcolors.oncyanemph + notifier.MARK +\ termcolors.reset message.parse(trace, anylog) notifier.notify(message, anylog) self.assertEqual(output, sys.stdout.captured[0])
def testshouldColorizefirstLevelFoundignoringSecondinSameTrace(self): # Test for fix 5 # Should give priority to FATAL in next trace level = 'FATAL' trace = "FATAL there could be an error in the application" sys.stdout = MemoryWriter() logcolors = LogColors() termcolors = TermColorCodes() message = Message(logcolors) notifier = notifications.Print() anylog = Log('out.log') message.parse(trace, anylog) output = (logcolors.getLevelColor(level) + trace + termcolors.reset) notifier.notify(message, anylog) self.assertEqual(output, sys.stdout.captured[0])
def setUp(self): self.utils_back = log4tailer.setup_mail self.os_fork = os.fork self.os_chdir = os.chdir self.os_umask = os.umask self.os_dup2 = os.dup2 self.os_setsid = os.setsid self.onelog = Log(self.log_name) onelogtrace = 'this is an info log trace' anotherlogtrace = 'this is a debug log trace' fh = open(self.log_name, 'w') fh.write(onelogtrace + '\n') fh.write(anotherlogtrace + '\n') fh.close() self.raise_count = 0
def tailer(self): '''Stdout multicolor tailer''' message = Message(self.logcolors, self.target, self.properties) anylog = Log('anylog') for hostname in self.hostnames.keys(): command = self.hostnames[hostname]['command'] self.logger.debug("command [%s] to be executed in host [%s]" % (command, hostname)) self.hostnameChannels[hostname]['channel'].exec_command(command) try: lasthostnameChanged = "" while True: for hostname in self.hostnames.keys(): sshChannel = self.hostnameChannels[hostname]['channel'] rr, _, _ = select.select([sshChannel], [], [], 0.0) if len(rr) > 0: lines = sshChannel.recv(4096).split('\n') if hostname != lasthostnameChanged: self.__hostnameChangedHeader(hostname) for line in lines: message.parse(line, anylog) self.actions.notify(message, anylog) lasthostnameChanged = hostname self._wait_for(1) except: print "\nfinishing ..." for hostname in self.hostnames.keys(): sshChannel = self.hostnameChannels[hostname]['channel'] sshclient = self.hostnameChannels[hostname]['client'] command = self.hostnames[hostname]['command'] procidCommand = 'pgrep -f -x ' + '\"' + command + '\"' self.logger.debug("procid command [%s]" % procidCommand) sshChannel.close() stdin, stdout, stderr = sshclient.exec_command(procidCommand) res = stdout.readlines() if res: procid = res[0].rstrip() self.logger.debug("procid [%s]" % procid) # is process still alive after closing channel? if procid: # kill it killprocid = 'kill -9 ' + procid stdin, stdout, stderr = sshclient.exec_command( killprocid) #sshChannel.shutdown(2) sshclient.close() print "Ended log4tailer, because colors are fun" sys.exit()
def openLog(self): log = Log(self.logname) log.openLog() return log