def setUp(self): curdir = os.getcwd() testdir = os.path.join(curdir, 'test') self.testdir = testdir if not os.path.isdir(testdir): os.mkdir(testdir) logdir = os.path.join(testdir, 'log') if not os.path.isdir(logdir): os.mkdir(logdir) self.logdir = logdir self.logfile = os.path.join(logdir, 'testlog') self.logfile1 = os.path.join(logdir, 'testlog.1') self.logfile2 = os.path.join(logdir, 'testlog.2') self.logfile_pattern = os.path.join(logdir, 'testlog*') seekdir = os.path.join(testdir, 'seek') if not os.path.isdir(seekdir): os.mkdir(seekdir) self.seekdir = seekdir self.seekfile = os.path.join(seekdir, 'testlog.seek') self.seekfile1 = LogChecker.get_seekfile(self.logfile_pattern, seekdir, self.logfile1) self.seekfile2 = LogChecker.get_seekfile(self.logfile_pattern, seekdir, self.logfile2) self.logformat_syslog = LogChecker.FORMAT_SYSLOG
def tearDown(self): if os.path.exists(self.seekfile): os.unlink(self.seekfile) if os.path.exists(self.seekfile1): os.unlink(self.seekfile1) if os.path.exists(self.seekfile2): os.unlink(self.seekfile2) if os.path.exists(self.logfile): seekfile = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile, trace_inode=True) if os.path.exists(seekfile): os.unlink(seekfile) os.unlink(self.logfile) if os.path.exists(self.logfile1): seekfile1 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile1, trace_inode=True) if os.path.exists(seekfile1): os.unlink(seekfile1) os.unlink(self.logfile1) if os.path.exists(self.logfile2): seekfile2 = LogChecker.get_seekfile(self.logfile_pattern, self.seekdir, self.logfile2, trace_inode=True) if os.path.exists(seekfile2): os.unlink(seekfile2) os.unlink(self.logfile2) if os.path.exists(self.logdir): os.removedirs(self.logdir) if os.path.exists(self.seekdir): os.removedirs(self.seekdir) if os.path.exists(self.testdir): os.removedirs(self.testdir)
def test_unlock(self): """LogChecker.unlock() """ lockfileobj = LogChecker.lock(self.lockfile) LogChecker.unlock(self.lockfile, lockfileobj) self.assertFalse(os.path.exists(self.lockfile)) self.assertTrue(lockfileobj.closed)
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 _run_locked_subprocess(self, lockfile, sleeptime): code = ("import time\n" "from check_log_ng import LogChecker\n" "lockfile = '{0}'\n" "lockfileobj = LogChecker.lock(lockfile)\n" "time.sleep({1})\n" "LogChecker.unlock(lockfile, lockfileobj)\n").format( lockfile, LogChecker.to_unicode(str(sleeptime))) code = code.replace("\n", ";") proc = subprocess.Popen(['python', '-c', code]) return proc
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_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_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_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_lock(self): """LogChecker.lock() """ # lock succeeded lockfileobj = LogChecker.lock(self.lockfile) self.assertNotEqual(lockfileobj, None) LogChecker.unlock(self.lockfile, lockfileobj) # locked by an another process locked_time = 4 wait_interval = 0.1 proc = self._run_locked_subprocess(self.lockfile, locked_time) for _ in range(100): if os.path.isfile(self.lockfile): break time.sleep(wait_interval) with warnings.catch_warnings(): warnings.simplefilter("ignore") lockfileobj = LogChecker.lock(self.lockfile) proc.wait() self.assertEqual(lockfileobj, None)
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(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_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_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_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_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_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_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_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_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_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_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_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_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(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_critical_negpattern(self): """--critical-negpattern option """ self.config["pattern_list"] = ["ERROR"] self.config["critical_pattern_list"] = ["FATAL"] self.config["critical_negpattern_list"] = ["IGNORE"] log = LogChecker(self.config) # check --pattern and --critical-negpattern # 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 and --ciritical-negpattern # 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_OK) self.assertEqual(log.get_message(), self.MESSAGE_OK) # check --pattern, --critical-pattern and --critical-negpattern # Dec 5 12:34:50 hostname test: ERROR FATAL IGNORE line3 = self._make_line( self._get_timestamp(), "test", "ERROR FATAL 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_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))