# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging import subprocess import tempfile import unittest class TestTail(unittest.TestCase): def setUp(self): self.log_file = tempfile.NamedTemporaryFile() self.logrotate_config = tempfile.NamedTemporaryFile() self.logrotate_config.write("""%s { copytruncate notifempty missingok rotate 1 weekly }""" % self.log_file.name) self.logrotate_config.flush() self.logrotate_state_file = tempfile.NamedTemporaryFile() self.last_line = None def _trigger_logrotate(self): subprocess.check_call([ 'logrotate', '-v', # Verbose logging '-f', # Force the rotation even though the file isn't old # Create a state file that you have file permissions for '-s', self.logrotate_state_file.name, self.logrotate_config.name ]) def test_logrotate_copytruncate(self): from collector.checks.utils import TailFile def line_parser(l): self.last_line = l tail = TailFile(logging.getLogger(), self.log_file.name, line_parser) self.assertEqual(tail._size, 0) # Write some data to the log file init_string = "hey there, I am a log\n" self.log_file.write(init_string) self.log_file.flush() # Consume from the tail gen = tail.tail(line_by_line=False, move_end=True) next(gen) # Verify that the tail consumed the data I wrote self.assertEqual(tail._size, len(init_string)) try: # Trigger a copytruncate logrotation on the log file self._trigger_logrotate() # Write a new line to the log file new_string = "I am shorter\n" self.log_file.write(new_string) self.log_file.flush() # Verify that the tail recognized the logrotation next(gen) self.assertEqual(self.last_line, new_string[:-1], self.last_line) except OSError: "logrotate is not present" if __name__ == '__main__': logging.getLogger().setLevel(logging.DEBUG) logging.getLogger().addHandler(logging.StreamHandler()) unittest.main()