def test_remove_seekfile_with_dry_run(self): """--expiration, --remove-seekfile, and --dry-run options """ self.config["pattern_list"] = ["ERROR"] self.config["scantime"] = 2 self.config["expiration"] = 4 log = LogChecker(self.config) # within expiration # Dec 5 12:34:50 hostname test: ERROR line1 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile1, line1) log.check(self.logfile_pattern, remove_seekfile=True) self.seekfile1 = log._create_seek_filename( self.logfile_pattern, self.logfile1) time.sleep(2) # Dec 5 12:34:54 hostname test: ERROR line2 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile2, line2) # seek file of logfile1 should not be purged. log.clear_state() log.check(self.logfile_pattern, remove_seekfile=True) self.seekfile2 = log._create_seek_filename( self.logfile_pattern, self.logfile2) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line2, self.logfile2)) self.assertTrue(os.path.exists(self.seekfile1)) self.assertTrue(os.path.exists(self.seekfile2)) # with dry run self.config["dry_run"] = True log = LogChecker(self.config) # over expiration # Dec 5 12:34:50 hostname test: ERROR line1 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile1, line1) log.check(self.logfile_pattern, remove_seekfile=True) time.sleep(6) # Dec 5 12:34:54 hostname test: ERROR line2 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile2, line2) log.clear_state() log.check(self.logfile_pattern, remove_seekfile=True) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line2, self.logfile2)) self.assertTrue(os.path.exists(self.seekfile1)) self.assertTrue(os.path.exists(self.seekfile2))
def test_negpattern(self): """--negpattern option """ self.config["pattern_list"] = ["ERROR"] self.config["critical_pattern_list"] = ["FATAL"] self.config["negpattern_list"] = ["IGNORE"] log = LogChecker(self.config) # check --pattern # Dec 5 12:34:50 hostname test: ERROR IGNORE line1 = self._make_line(self._get_timestamp(), "test", "ERROR IGNORE") self._write_logfile(self.logfile, line1) log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_OK) self.assertEqual(log.get_message(), self.MESSAGE_OK) # check --critical-pattern # Dec 5 12:34:50 hostname test: FATAL IGNORE line2 = self._make_line(self._get_timestamp(), "test", "FATAL IGNORE") self._write_logfile(self.logfile, line2) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_CRITICAL) self.assertEqual( log.get_message(), self.MESSAGE_CRITICAL_ONE.format(line2, self.logfile))
def test_cachetime(self): """--cachetime """ self.config["pattern_list"] = ["ERROR"] self.config["cachetime"] = 2 log = LogChecker(self.config) cachefile = log._create_cache_filename(self.logfile) # within cachetime # Dec 5 12:34:50 hostname test: ERROR line = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line) # check log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line, self.logfile)) # check again log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line, self.logfile)) log._remove_cache(cachefile) # over cachetime # Dec 5 12:34:50 hostname test: ERROR line = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line, self.logfile)) # check again time.sleep(self.config["cachetime"] + 1) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_OK) log._remove_cache(cachefile)
def test_cachetime_with_dry_run(self): """--cachetime and --dry-run """ self.config["pattern_list"] = ["ERROR"] self.config["cachetime"] = 60 log = LogChecker(self.config) cachefile = log._create_cache_filename(self.logfile) # create a cache file # Dec 5 12:34:50 hostname test: ERROR line = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line, self.logfile)) # verify it does not read a cache file. self.config["dry_run"] = True log = LogChecker(self.config) # Dec 5 12:34:50 hostname test: NOOP line = self._make_line(self._get_timestamp(), "test", "NOOP") self._write_logfile(self.logfile, line) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_OK) # verify a cache file is not updated. self.config["dry_run"] = False log = LogChecker(self.config) # Dec 5 12:34:50 hostname test: ERROR line = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line, self.logfile)) log._remove_cache(cachefile)
def test_scantime(self): """--scantime option """ self.config["pattern_list"] = ["ERROR"] self.config["scantime"] = 2 log = LogChecker(self.config) # within scantime. # Dec 5 12:34:50 hostname test: ERROR line1 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile1, line1) log.clear_state() log.check(self.logfile_pattern) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line1, self.logfile1)) # over scantime # Dec 5 12:34:50 hostname test: ERROR line2 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile1, line2) time.sleep(4) log.clear_state() log.check(self.logfile_pattern) self.assertEqual(log.get_state(), LogChecker.STATE_OK) self.assertEqual(log.get_message(), self.MESSAGE_OK) # multiple logfiles. # Dec 5 12:34:50 hostname test: ERROR line3 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile1, line3) time.sleep(4) # Dec 5 12:34:54 hostname test: ERROR line4 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile2, line4) # logfile1 should be older than spantime. Therefore, don't scan it. log.clear_state() log.check(self.logfile_pattern) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line4, self.logfile2))
def test_criticalpattern_with_case_sensitive(self): """--criticalpattern and --case-insensitive options """ initial_data = { "logformat": self.logformat_syslog, "pattern_list": [], "critical_pattern_list": ["error"], "negpattern_list": [], "critical_negpattern_list": [], "case_insensitive": True, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": False, "multiline": False, "scantime": 86400, "expiration": 691200 } log = LogChecker(initial_data) f = open(self.logfile, 'a') f.write("Dec 5 12:34:56 hostname noop: NOOP\n") f.write("Dec 5 12:34:56 hostname test: ERROR\n") f.write("Dec 5 12:34:57 hostname noop: NOOP\n") f.flush() f.close() log.check_log(self.logfile, self.seekfile) self.assertEqual(log.get_state(), LogChecker.STATE_CRITICAL) self.assertEqual(log.get_message(), 'CRITICAL: Critical Found 1 lines: Dec 5 12:34:56 hostname test: ERROR at %s' % self.logfile)
def test_negpattern_with_multiple_lines(self): """--negpattern options with multiple lines """ initial_data = { "logformat": self.logformat_syslog, "pattern_list": ["ERROR"], "critical_pattern_list": [], "negpattern_list": ["IGNORE"], "critical_negpattern_list": [], "case_insensitive": False, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": False, "multiline": True, "scantime": 86400, "expiration": 691200 } log = LogChecker(initial_data) f = open(self.logfile, 'a') f.write("Dec 5 12:34:56 hostname test: ERROR\n") f.write("Dec 5 12:34:56 hostname test: ERROR IGNORE\n") f.flush() f.close() log.check_log(self.logfile, self.seekfile) self.assertEqual(log.get_state(), LogChecker.STATE_OK) self.assertEqual(log.get_message(), 'OK - No matches found.')
def test_scantime_without_scantime(self): """--scantime option without scantime. """ initial_data = { "logformat": self.logformat_syslog, "pattern_list": ["ERROR"], "critical_pattern_list": [], "negpattern_list": [], "critical_negpattern_list": [], "case_insensitive": False, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": False, "multiline": False, "scantime": 2, "expiration": 691200 } log = LogChecker(initial_data) f = open(self.logfile1, 'a') f.write("Dec 5 12:34:56 hostname noop: NOOP\n") f.write("Dec 5 12:34:56 hostname test: ERROR\n") f.write("Dec 5 12:34:57 hostname noop: NOOP\n") f.flush() f.close() time.sleep(4) log.check_log_multi(self.logfile_pattern, self.seekdir, remove_seekfile=False) self.assertEqual(log.get_state(), LogChecker.STATE_OK) self.assertEqual(log.get_message(), 'OK - No matches found.')
def test_scantime_within_scantime(self): """--scantime option within scantime. """ initial_data = { "logformat": self.logformat_syslog, "pattern_list": ["ERROR"], "critical_pattern_list": [], "negpattern_list": [], "critical_negpattern_list": [], "case_insensitive": False, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": False, "multiline": False, "scantime": 2, "expiration": 691200 } log = LogChecker(initial_data) f = open(self.logfile1, 'a') f.write("Dec 5 12:34:58 hostname noop: NOOP\n") f.write("Dec 5 12:34:59 hostname test: ERROR\n") f.write("Dec 5 12:34:59 hostname noop: NOOP\n") f.flush() f.close() # The first ERROR message should be older than scantime. Therefore, don't scan it. log.check_log_multi(self.logfile_pattern, self.seekdir, remove_seekfile=False) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), 'WARNING: Found 1 lines (limit=1/0): Dec 5 12:34:59 hostname test: ERROR at %s' % self.logfile1)
def test_format(self): """--format option """ initial_data = { "logformat": "^(\[%a %b %d %T %Y\] \[\S+\]) (.*)$", "pattern_list": ["ERROR"], "critical_pattern_list": [], "negpattern_list": [], "critical_negpattern_list": [], "case_insensitive": False, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": False, "multiline": False, "scantime": 86400, "expiration": 691200 } log = LogChecker(initial_data) f = open(self.logfile, 'a') f.write("[Thu Dec 05 12:34:56 2013] [error] NOOP\n") f.write("[Thu Dec 05 12:34:56 2013] [error] ERROR\n") f.write("[Thu Dec 05 12:34:57 2013] [error] NOOP\n") f.flush() f.close() log.check_log(self.logfile, self.seekfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), "WARNING: Found 1 lines (limit=1/0): [Thu Dec 05 12:34:56 2013] [error] ERROR at %s" % self.logfile)
def test_replace_pipe_symbol(self): """replace pipe symbol """ initial_data = { "logformat": self.logformat_syslog, "pattern_list": ["ERROR"], "critical_pattern_list": [], "negpattern_list": [], "critical_negpattern_list": [], "case_insensitive": False, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": False, "multiline": False, "scantime": 86400, "expiration": 691200 } log = LogChecker(initial_data) f = open(self.logfile, 'a') f.write("Dec | 5 12:34:56 hostname noop: NOOP\n") f.write("Dec | 5 12:34:56 hostname test: ERROR\n") f.write("Dec | 5 12:34:57 hostname noop: NOOP\n") f.flush() f.close() log.check_log(self.logfile, self.seekfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), 'WARNING: Found 1 lines (limit=1/0): Dec (pipe) 5 12:34:56 hostname test: ERROR at %s' % self.logfile)
def test_pattern_with_header(self): """--pattern and --header options """ self.config["pattern_list"] = ["ERROR"] self.config['output_header'] = True log = LogChecker(self.config) # 1 line matched # Dec 5 12:34:50 hostname test: ERROR timestamp = self._get_timestamp() line1 = self._make_line(timestamp, "test", "ERROR") header1 = self._make_line(timestamp, "test", "") self._write_logfile(self.logfile, line1) log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE_WITH_HEADER.format(header1, self.logfile)) # 2 lines matched # Dec 5 12:34:50 hostname test: ERROR1 # Dec 5 12:34:50 hostname test: ERROR2 timestamp = self._get_timestamp() line2 = self._make_line(timestamp, "test", "ERROR1") line3 = self._make_line(timestamp, "test", "ERROR2") header2 = self._make_line(timestamp, "test", "") header3 = self._make_line(timestamp, "test", "") self._write_logfile(self.logfile, [line2, line3]) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_TWO_WITH_HEADER.format( header2, header3, self.logfile)) # no line matched # Dec 5 12:34:50 hostname noop: NOOP line4 = self._make_line(self._get_timestamp(), "noop", "NOOP") self._write_logfile(self.logfile, line4) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_OK) self.assertEqual(log.get_message(), self.MESSAGE_OK)
def test_remove_seekfile_inode_with_dry_run(self): """--trace_inode, --expiration, --remove-seekfile, and --dry-run options """ self.config["pattern_list"] = ["ERROR"] self.config["trace_inode"] = True self.config["scantime"] = 2 self.config["expiration"] = 3 log = LogChecker(self.config) # create logfile # Dec 5 12:34:50 hostname test: ERROR line1 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line1) # log rotation os.rename(self.logfile, self.logfile1) # create new logfile # Dec 5 12:34:50 hostname test: ERROR line2 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line2) # do check_log_multi, and create seekfile and seekfile1 log.clear_state() log.check(self.logfile_pattern, remove_seekfile=True) seekfile_1 = log._create_seek_filename(self.logfile_pattern, self.logfile, trace_inode=True) seekfile1_1 = log._create_seek_filename(self.logfile_pattern, self.logfile1, trace_inode=True) time.sleep(4) # update logfile # Dec 5 12:34:54 hostname test: ERROR line3 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line3) # log rotation, purge old logfile2 os.rename(self.logfile1, self.logfile2) os.rename(self.logfile, self.logfile1) # with dry run self.config["dry_run"] = True log = LogChecker(self.config) log.clear_state() log.check(self.logfile_pattern, remove_seekfile=True) seekfile1_2 = log._create_seek_filename(self.logfile_pattern, self.logfile1, trace_inode=True) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), self.MESSAGE_WARNING_ONE.format(line3, self.logfile1)) self.assertEqual(seekfile_1, seekfile1_2) self.assertTrue(os.path.exists(seekfile1_1)) self.assertTrue(os.path.exists(seekfile1_2))
def test_seekfile_tag(self): """--seekfile-tag """ initial_data = { "logformat": self.logformat_syslog, "pattern_list": ["ERROR"], "critical_pattern_list": [], "negpattern_list": [], "critical_negpattern_list": [], "case_insensitive": False, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": False, "multiline": False, "scantime": 86400, "expiration": 691200 } log = LogChecker(initial_data) # create new logfiles f = open(self.logfile, 'a') f.write("Dec 5 12:34:51 hostname noop: NOOP\n") f.write("Dec 5 12:34:51 hostname test: ERROR\n") f.write("Dec 5 12:34:52 hostname noop: NOOP\n") f.flush() f.close() f = open(self.logfile1, 'a') f.write("Dec 5 12:34:56 hostname noop: NOOP\n") f.write("Dec 5 12:34:56 hostname test: ERROR\n") f.write("Dec 5 12:34:57 hostname noop: NOOP\n") f.flush() f.close() f = open(self.logfile2, 'a') f.write("Dec 5 12:34:58 hostname noop: NOOP\n") f.write("Dec 5 12:34:59 hostname noop: NOOP\n") f.flush() f.close() # create seekfile of logfile seekfile_1 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile, seekfile_tag=self.tag1) seekfile_2 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile, seekfile_tag=self.tag1) seekfile_3 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile, seekfile_tag=self.tag2) log.check_log(self.logfile, seekfile_3) log.clear_state() log.check_log_multi(self.logfile_pattern, self.seekdir, seekfile_tag=self.tag2) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), 'WARNING: Found 1 lines (limit=1/0): Dec 5 12:34:56 hostname test: ERROR at %s' % self.logfile1) self.assertEqual(seekfile_1, seekfile_2) self.assertNotEquals(seekfile_1, seekfile_3) self.assertTrue(seekfile_1.find(self.tag1)) self.assertTrue(os.path.exists(seekfile_3))
def test_multiline(self): """--multiline """ self.config["pattern_list"] = ["ERROR1.*ERROR2"] self.config["negpattern_list"] = ["IGNORE"] self.config["multiline"] = True log = LogChecker(self.config) # check --pattern, --multiline # Dec 5 12:34:50 hostname test: ERROR1 # Dec 5 12:34:50 hostname test: ERROR2 timestamp = self._get_timestamp() lines = [] messages = ["ERROR1", "ERROR2"] for message in messages: lines.append(self._make_line(timestamp, "test", message)) self._write_logfile(self.logfile, lines) log.clear_state() log.check(self.logfile) # detected line: Dec 5 12:34:50 hostname test: ERROR1 ERROR2 self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format( lines[0] + " " + messages[1], self.logfile)) # check --pattern, --negpattern and --multiline # Dec 5 12:34:50 hostname test: ERROR # Dec 5 12:34:50 hostname test: ERROR IGNORE timestamp = self._get_timestamp() lines = [] messages = ["ERROR", "ERROR IGNORE"] for message in messages: lines.append(self._make_line(timestamp, "test", message)) self._write_logfile(self.logfile, lines) log.clear_state() log.check(self.logfile) # detected line: Dec 5 12:34:50 hostname test: ERROR ERROR IGNORE self.assertEqual(log.get_state(), LogChecker.STATE_OK) self.assertEqual(log.get_message(), self.MESSAGE_OK)
def test_case_insensitive(self): """--case-insensitive option """ self.config["pattern_list"] = ["error"] self.config["critical_pattern_list"] = ["fatal"] self.config["negpattern_list"] = ["ignore"] self.config["case_insensitive"] = True log = LogChecker(self.config) # check --pattern # Dec 5 12:34:50 hostname test: ERROR line1 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line1) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line1, self.logfile)) # check --critical-pattern # Dec 5 12:34:50 hostname test: FATAL line2 = self._make_line(self._get_timestamp(), "test", "FATAL") self._write_logfile(self.logfile, line2) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_CRITICAL) self.assertEqual( log.get_message(), self.MESSAGE_CRITICAL_ONE.format(line2, self.logfile)) # check --pattern and --negpattern # Dec 5 12:34:50 hostname test: ERROR ERROR IGNORE line3 = self._make_line(self._get_timestamp(), "test", "ERROR IGNORE") self._write_logfile(self.logfile, line3) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_OK) self.assertEqual(log.get_message(), self.MESSAGE_OK)
def test_logfile(self): """--logfile option """ self.config["pattern_list"] = ["ERROR"] log = LogChecker(self.config) # check -logfile option with wild card '*' # Dec 5 12:34:50 hostname test: ERROR line1 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile1, line1) time.sleep(1) # Dec 5 12:34:51 hostname test: ERROR line2 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile2, line2) log.clear_state() log.check(self.logfile_pattern) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_TWO_IN_TWO_FILES.format( line1, self.logfile1, line2, self.logfile2)) # --logfile option with multiple filenames # Dec 5 12:34:51 hostname test: ERROR line1 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile1, line1) time.sleep(1) # Dec 5 12:34:52 hostname test: ERROR line2 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile2, line2) logfile_pattern = "{0} {1}".format(self.logfile1, self.logfile2) log.clear_state() log.check(logfile_pattern) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_TWO_IN_TWO_FILES.format( line1, self.logfile1, line2, self.logfile2))
def test_seekfile(self): """--seekfile option """ self.config["pattern_list"] = ["ERROR"] log = LogChecker(self.config) # 1 line matched # Dec 5 12:34:50 hostname test: ERROR line1 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line1) log.check(self.logfile, seekfile=self.seekfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line1, self.logfile)) # 2 lines matched # Dec 5 12:34:50 hostname test: ERROR1 # Dec 5 12:34:50 hostname test: ERROR2 line2 = self._make_line(self._get_timestamp(), "test", "ERROR1") line3 = self._make_line(self._get_timestamp(), "test", "ERROR2") self._write_logfile(self.logfile, [line2, line3]) log.clear_state() log.check(self.logfile, seekfile=self.seekfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_TWO.format(line2, line3, self.logfile)) # no line matched # Dec 5 12:34:50 hostname noop: NOOP line4 = self._make_line(self._get_timestamp(), "noop", "NOOP") self._write_logfile(self.logfile, line4) log.clear_state() log.check(self.logfile, seekfile=self.seekfile) self.assertEqual(log.get_state(), LogChecker.STATE_OK) self.assertEqual(log.get_message(), self.MESSAGE_OK)
def test_dry_run(self): """--dry-run option """ self.config["pattern_list"] = ["ERROR"] log = LogChecker(self.config) # create a seek file # Dec 5 12:34:50 hostname noop: NOOP line4 = self._make_line(self._get_timestamp(), "noop", "NOOP") self._write_logfile(self.logfile, line4) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_OK) self.assertEqual(log.get_message(), self.MESSAGE_OK) # verify a seek file is not updated. self.config["dry_run"] = True log = LogChecker(self.config) # Dec 5 12:34:50 hostname test: ERROR line = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line, self.logfile)) log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line, self.logfile))
def test_critical_pattern(self): """--critical-pattern option """ self.config["critical_pattern_list"] = ["FATAL"] log = LogChecker(self.config) # Dec 5 12:34:50 hostname test: FATAL line = self._make_line(self._get_timestamp(), "test", "FATAL") self._write_logfile(self.logfile, line) log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_CRITICAL) self.assertEqual(log.get_message(), self.MESSAGE_CRITICAL_ONE.format(line, self.logfile))
def test_trace_inode(self): """--trace_inode """ self.config["pattern_list"] = ["ERROR"] self.config["trace_inode"] = True log = LogChecker(self.config) # within expiration # create logfile # Dec 5 12:34:50 hostname test: ERROR line1 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line1) # create seekfile of logfile log.check(self.logfile_pattern) seekfile_1 = log._create_seek_filename(self.logfile_pattern, self.logfile, trace_inode=True) # update logfile # Dec 5 12:34:51 hostname test: ERROR line2 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line2) # log rotation os.rename(self.logfile, self.logfile1) # create a new logfile # Dec 5 12:34:52 hostname noop: NOOP line3 = self._make_line(self._get_timestamp(), "noop", "NOOP") self._write_logfile(self.logfile, line3) # create seekfile of logfile log.clear_state() log.check(self.logfile_pattern) seekfile_2 = log._create_seek_filename(self.logfile_pattern, self.logfile, trace_inode=True) seekfile1_2 = log._create_seek_filename(self.logfile_pattern, self.logfile1, trace_inode=True) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), self.MESSAGE_WARNING_ONE.format(line2, self.logfile1)) self.assertEqual(seekfile_1, seekfile1_2) self.assertTrue(os.path.exists(seekfile_2)) self.assertTrue(os.path.exists(seekfile1_2))
def test_format(self): """--format option """ self.config["logformat"] = r"^(\[%a %b %d %T %Y\] \[\S+\] )(.*)$" self.config["pattern_list"] = ["ERROR"] log = LogChecker(self.config) # [Thu Dec 05 12:34:50 2013] [error] ERROR line = self._make_customized_line(self._get_customized_timestamp(), "error", "ERROR") self._write_customized_logfile(self.logfile, line) log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), self.MESSAGE_WARNING_ONE.format(line, self.logfile))
def test_encoding(self): """--pattern and --encoding """ self.config["pattern_list"] = ["エラー"] self.config["encoding"] = "EUC-JP" log = LogChecker(self.config) # Dec 5 12:34:50 hostname test: エラー line = self._make_line(self._get_timestamp(), "test", "エラー") self._write_logfile(self.logfile, line, encoding='EUC-JP') log.clear_state() log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), self.MESSAGE_WARNING_ONE.format(line, self.logfile))
def test_critical_pattern_with_quiet(self): """--critical-pattern and --quiet options """ self.config["critical_pattern_list"] = ["FATAL"] self.config['output_quiet'] = True log = LogChecker(self.config) # Dec 5 12:34:50 hostname test: FATAL line = self._make_line(self._get_timestamp(), "test", "FATAL") self._write_logfile(self.logfile, line) log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_CRITICAL) self.assertEqual( log.get_message(), self.MESSAGE_CRITICAL_ONE_WITH_QUIET.format(self.logfile))
def test_remove_seekfile_within_expiration(self): """--expiration and --remove-seekfile options """ initial_data = { "logformat": self.logformat_syslog, "pattern_list": ["ERROR"], "critical_pattern_list": [], "negpattern_list": [], "critical_negpattern_list": [], "case_insensitive": False, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": False, "multiline": False, "scantime": 2, "expiration": 10 } log = LogChecker(initial_data) f = open(self.logfile1, 'a') f.write("Dec 5 12:34:56 hostname noop: NOOP\n") f.write("Dec 5 12:34:56 hostname test: ERROR\n") f.write("Dec 5 12:34:57 hostname noop: NOOP\n") f.flush() f.close() log.check_log_multi(self.logfile_pattern, self.seekdir, remove_seekfile=True) log.clear_state() time.sleep(4) f = open(self.logfile2, 'a') f.write("Dec 5 12:34:58 hostname noop: NOOP\n") f.write("Dec 5 12:34:59 hostname test: ERROR\n") f.write("Dec 5 12:34:59 hostname noop: NOOP\n") f.flush() f.close() # seek file of logfile1 should be purged. log.check_log_multi(self.logfile_pattern, self.seekdir, remove_seekfile=True) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), 'WARNING: Found 1 lines (limit=1/0): Dec 5 12:34:59 hostname test: ERROR at %s' % self.logfile2) self.assertTrue(os.path.exists(self.seekfile1)) self.assertTrue(os.path.exists(self.seekfile2))
def test_replace_pipe_symbol(self): """replace pipe symbol """ line = "Dec | 5 12:34:56 hostname test: ERROR" self.config["pattern_list"] = ["ERROR"] log = LogChecker(self.config) # Dec 5 12:34:50 hostname test: ERROR | line = self._make_line(self._get_timestamp(), "test", "ERROR |") self._write_logfile(self.logfile, line) log.check(self.logfile) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format( line.replace("|", "(pipe)"), self.logfile))
def test_logfile_with_filename(self): """--logfile option with multiple filenames """ initial_data = { "logformat": self.logformat_syslog, "pattern_list": ["ERROR"], "critical_pattern_list": [], "negpattern_list": [], "critical_negpattern_list": [], "case_insensitive": False, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": False, "multiline": False, "scantime": 86400, "expiration": 691200 } log = LogChecker(initial_data) f = open(self.logfile1, 'a') f.write("Dec 5 12:34:56 hostname noop: NOOP\n") f.write("Dec 5 12:34:56 hostname test: ERROR\n") f.write("Dec 5 12:34:57 hostname noop: NOOP\n") f.flush() f.close() time.sleep(1) f = open(self.logfile2, 'a') f.write("Dec 5 12:34:58 hostname noop: NOOP\n") f.write("Dec 5 12:34:59 hostname test: ERROR\n") f.write("Dec 5 12:34:59 hostname noop: NOOP\n") f.flush() f.close() logfile_pattern = "%s %s" % (self.logfile1, self.logfile2) log.check_log_multi(logfile_pattern, self.seekdir, remove_seekfile=False) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), 'WARNING: Found 2 lines (limit=1/0): Dec 5 12:34:56 hostname test: ERROR at %s,Dec 5 12:34:59 hostname test: ERROR at %s' % (self.logfile1, self.logfile2))
def test_tag(self): """--tag """ self.config["pattern_list"] = ["ERROR"] log = LogChecker(self.config) # create new logfiles # Dec 5 12:34:50 hostname test: ERROR line1 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line1) # Dec 5 12:34:50 hostname test: ERROR line2 = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile1, line2) # Dec 5 12:34:50 hostname test: ERROR line3 = self._make_line(self._get_timestamp(), "noop", "NOOP") self._write_logfile(self.logfile2, line3) # create seekfile of logfile seekfile_1 = log._create_seek_filename(self.logfile_pattern, self.logfile, tag=self.tag1) seekfile_2 = log._create_seek_filename(self.logfile_pattern, self.logfile, tag=self.tag1) seekfile_3 = log._create_seek_filename(self.logfile_pattern, self.logfile, tag=self.tag2) log.check(self.logfile, seekfile=seekfile_3) log.clear_state() log.check(self.logfile_pattern, tag=self.tag2) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), self.MESSAGE_WARNING_ONE.format(line2, self.logfile1)) self.assertEqual(seekfile_1, seekfile_2) self.assertNotEqual(seekfile_1, seekfile_3) self.assertTrue(seekfile_1.find(self.tag1)) self.assertTrue(os.path.exists(seekfile_3))
def test_trace_inode_without_expiration(self): """--trace_inode, --expiration and --remove-seekfile options """ initial_data = { "logformat": self.logformat_syslog, "pattern_list": ["ERROR"], "critical_pattern_list": [], "negpattern_list": [], "critical_negpattern_list": [], "case_insensitive": False, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": True, "multiline": False, "scantime": 2, "expiration": 3 } log = LogChecker(initial_data) # create logfile f = open(self.logfile, 'a') f.write("Dec 5 12:34:50 hostname noop: NOOP\n") f.write("Dec 5 12:34:51 hostname test: ERROR\n") f.write("Dec 5 12:34:52 hostname noop: NOOP\n") f.flush() f.close() # log rotation os.rename(self.logfile, self.logfile1) # create new logfile f = open(self.logfile, 'a') f.write("Dec 5 12:34:53 hostname noop: NOOP\n") f.write("Dec 5 12:34:53 hostname test: ERROR\n") f.write("Dec 5 12:34:54 hostname noop: NOOP\n") f.flush() f.close() # do check_log_multi, and create seekfile and seekfile1 log.check_log_multi(self.logfile_pattern, self.seekdir, remove_seekfile=True) log.clear_state() seekfile_1 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile, trace_inode=True) seekfile1_1 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile1, trace_inode=True) time.sleep(4) # update logfile f = open(self.logfile, 'a') f.write("Dec 5 12:34:58 hostname noop: NOOP\n") f.write("Dec 5 12:34:59 hostname test: ERROR\n") f.write("Dec 5 12:34:59 hostname noop: NOOP\n") f.flush() f.close() # log rotation, purge old logfile2 os.rename(self.logfile1, self.logfile2) os.rename(self.logfile, self.logfile1) # seek file of old logfile1 should be purged. log.check_log_multi(self.logfile_pattern, self.seekdir, remove_seekfile=True) seekfile1_2 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile1, trace_inode=True) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), 'WARNING: Found 1 lines (limit=1/0): Dec 5 12:34:59 hostname test: ERROR at %s' % self.logfile1) self.assertEqual(seekfile_1, seekfile1_2) self.assertFalse(os.path.exists(seekfile1_1)) self.assertTrue(os.path.exists(seekfile1_2))
def test_trace_inode(self): """--trace_inode """ initial_data = { "logformat": self.logformat_syslog, "pattern_list": ["ERROR"], "critical_pattern_list": [], "negpattern_list": [], "critical_negpattern_list": [], "case_insensitive": False, "warning": 1, "critical": 0, "nodiff_warn": False, "nodiff_crit": False, "trace_inode": True, "multiline": False, "scantime": 86400, "expiration": 691200 } log = LogChecker(initial_data) # create logfile f = open(self.logfile, 'a') f.write("Dec 5 12:34:51 hostname noop: NOOP\n") f.write("Dec 5 12:34:51 hostname test: ERROR\n") f.write("Dec 5 12:34:52 hostname noop: NOOP\n") f.flush() f.close() # create seekfile of logfile log.check_log_multi(self.logfile_pattern, self.seekdir, remove_seekfile=False) log.clear_state() seekfile_1 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile, trace_inode=True) # update logfile f = open(self.logfile, 'a') f.write("Dec 5 12:34:55 hostname noop: NOOP\n") f.write("Dec 5 12:34:55 hostname test: ERROR\n") f.write("Dec 5 12:34:56 hostname noop: NOOP\n") f.flush() f.close() # log rotation os.rename(self.logfile, self.logfile1) # create a new logfile f = open(self.logfile, 'a') f.write("Dec 5 12:34:59 hostname noop: NOOP\n") f.flush() f.close() # create seekfile of logfile log.check_log_multi(self.logfile_pattern, self.seekdir, remove_seekfile=False) seekfile_2 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile, trace_inode=True) seekfile1_2 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile1, trace_inode=True) self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual(log.get_message(), 'WARNING: Found 1 lines (limit=1/0): Dec 5 12:34:55 hostname test: ERROR at %s' % self.logfile1) self.assertEqual(seekfile_1, seekfile1_2) self.assertTrue(os.path.exists(seekfile_2)) self.assertTrue(os.path.exists(seekfile1_2))
def test_lock_timeout(self): """--lock-timeout """ self.config["pattern_list"] = ["ERROR"] self.config["lock_timeout"] = 6 log = LogChecker(self.config) lockfile = log._create_lock_filename(self.logfile) # within lock_timeout # |time|sub |main | # |----|-----------|-----------| # | 0|fork |sleep | # | 1|lock OK |sleep | # | 1| |check | # | 1| |lock fail | # | *| |sleep | # | 5|unlock OK |sleep | # | 5| |lock OK | # | 5| |unlock OK | # Dec 5 12:34:50 hostname test: ERROR line = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line) # locked by an another process locked_time = 4 wait_interval = 0.1 proc = self._run_locked_subprocess(lockfile, locked_time) for _ in range(100): if os.path.isfile(lockfile): break time.sleep(wait_interval) # check log.clear_state() start_time = time.time() log.check(self.logfile) elapsed_time = time.time() - start_time proc.wait() self.assertEqual(log.get_state(), LogChecker.STATE_WARNING) self.assertEqual( log.get_message(), self.MESSAGE_WARNING_ONE.format(line, self.logfile)) self.assertTrue(elapsed_time < self.config["lock_timeout"]) self.assertTrue(elapsed_time > locked_time - wait_interval) # over lock_timeout # |time|sub |main | # |----|-----------|-----------| # | 0|fork |sleep | # | 1|lock OK |sleep | # | 1| |check | # | 1| |lock fail | # | *| |sleep | # | 7| |timeout | # | 9|unlock OK | | # Dec 5 12:34:50 hostname test: ERROR line = self._make_line(self._get_timestamp(), "test", "ERROR") self._write_logfile(self.logfile, line) # locked by an another process locked_time = 8 wait_interval = 0.1 proc = self._run_locked_subprocess(lockfile, locked_time) for _ in range(100): if os.path.isfile(lockfile): break time.sleep(wait_interval) # check log.clear_state() start_time = time.time() log.check(self.logfile) elapsed_time = time.time() - start_time proc.wait() self.assertEqual(log.get_state(), LogChecker.STATE_UNKNOWN) self.assertEqual(log.get_message(), self.MESSAGE_UNKNOWN_LOCK_TIMEOUT) self.assertTrue(elapsed_time > self.config["lock_timeout"]) self.assertTrue(elapsed_time < locked_time)