def test_metric_logging_metric_name_blacklist_actual_monitor_class(self):
        from scalyr_agent.scalyr_monitor import ScalyrMonitor

        monitor_1_config = {
            "module": "foo1",
            "metric_name_blacklist": ["a", "b"]
        }
        monitor_1_logger = scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo1(1)")
        monitor_1 = ScalyrMonitor(monitor_config=monitor_1_config,
                                  logger=monitor_1_logger)
        monitor_1_metric_file_path = tempfile.mktemp(".log")

        monitor_2_config = {
            "module": "foo2",
            "metric_name_blacklist": ["c", "d"]
        }
        monitor_2_logger = scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo2(1)")
        monitor_2 = ScalyrMonitor(monitor_config=monitor_2_config,
                                  logger=monitor_1_logger)
        monitor_2_metric_file_path = tempfile.mktemp(".log")

        monitor_1_logger.openMetricLogForMonitor(monitor_1_metric_file_path,
                                                 monitor_1)

        monitor_1_logger.emit_value("a", 1)
        monitor_1_logger.emit_value("b", 2)
        monitor_1_logger.emit_value("c", 3)
        monitor_1_logger.emit_value("d", 4)

        self.assertLogFileContainsLineRegex(
            file_path=monitor_1_metric_file_path, expression="d")
        self.assertLogFileContainsLineRegex(
            file_path=monitor_1_metric_file_path, expression="d")
        self.assertLogFileDoesntContainsLineRegex(
            file_path=monitor_1_metric_file_path, expression="a")
        self.assertLogFileDoesntContainsLineRegex(
            file_path=monitor_1_metric_file_path, expression="b")

        monitor_1_logger.closeMetricLog()

        monitor_2_logger.openMetricLogForMonitor(monitor_2_metric_file_path,
                                                 monitor_2)

        monitor_2_logger.emit_value("a", 1)
        monitor_2_logger.emit_value("b", 2)
        monitor_2_logger.emit_value("c", 3)
        monitor_2_logger.emit_value("d", 4)

        self.assertLogFileContainsLineRegex(
            file_path=monitor_2_metric_file_path, expression="a")
        self.assertLogFileContainsLineRegex(
            file_path=monitor_2_metric_file_path, expression="a")
        self.assertLogFileDoesntContainsLineRegex(
            file_path=monitor_2_metric_file_path, expression="c")
        self.assertLogFileDoesntContainsLineRegex(
            file_path=monitor_2_metric_file_path, expression="d")

        monitor_2_logger.closeMetricLog()
    def test_module_with_different_metric_logs(self):
        monitor_one = ScalyrLoggingTest.FakeMonitor("testing one")
        monitor_two = ScalyrLoggingTest.FakeMonitor("testing two")

        metric_file_one_fd, metric_file_one = tempfile.mkstemp(".log")
        metric_file_two_fd, metric_file_two = tempfile.mkstemp(".log")

        # NOTE: We close the fd here because we open it again below. This way file deletion at
        # the end works correctly on Windows.
        os.close(metric_file_one_fd)
        os.close(metric_file_two_fd)

        logger_one = scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo(1)")
        logger_two = scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo(2)")

        logger_one.openMetricLogForMonitor(metric_file_one, monitor_one)
        logger_two.openMetricLogForMonitor(metric_file_two, monitor_two)

        logger_one.report_values({"foo": 5})
        logger_two.report_values({"bar": 4})

        # The value should only appear in the metric log file and not the main one.
        self.assertLogFileContainsLineRegex(file_path=metric_file_one,
                                            expression="foo=5")
        self.assertLogFileDoesntContainsLineRegex(file_path=metric_file_two,
                                                  expression="foo=5")
        self.assertLogFileContainsLineRegex(file_path=metric_file_two,
                                            expression="bar=4")
        self.assertLogFileDoesntContainsLineRegex(file_path=metric_file_one,
                                                  expression="bar=4")

        logger_one.closeMetricLog()
        logger_two.closeMetricLog()
    def test_module_with_different_metric_logs(self):
        monitor_one = ScalyrLoggingTest.FakeMonitor("testing one")
        monitor_two = ScalyrLoggingTest.FakeMonitor("testing two")

        metric_file_one = tempfile.mktemp(".log")
        metric_file_two = tempfile.mktemp(".log")

        logger_one = scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo(1)")
        logger_two = scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo(2)")

        logger_one.openMetricLogForMonitor(metric_file_one, monitor_one)
        logger_two.openMetricLogForMonitor(metric_file_two, monitor_two)

        logger_one.report_values({"foo": 5})
        logger_two.report_values({"bar": 4})

        # The value should only appear in the metric log file and not the main one.
        self.assertLogFileContainsLineRegex(file_path=metric_file_one,
                                            expression="foo=5")
        self.assertLogFileDoesntContainsLineRegex(file_path=metric_file_two,
                                                  expression="foo=5")
        self.assertLogFileContainsLineRegex(file_path=metric_file_two,
                                            expression="bar=4")
        self.assertLogFileDoesntContainsLineRegex(file_path=metric_file_one,
                                                  expression="bar=4")

        logger_one.closeMetricLog()
        logger_two.closeMetricLog()
    def test_module_with_different_metric_logs(self):
        monitor_one = ScalyrLoggingTest.FakeMonitor('testing one')
        monitor_two = ScalyrLoggingTest.FakeMonitor('testing two')

        metric_file_one = tempfile.mktemp('.log')
        metric_file_two = tempfile.mktemp('.log')

        logger_one = scalyr_logging.getLogger(
            'scalyr_agent.builtin_monitors.foo(1)')
        logger_two = scalyr_logging.getLogger(
            'scalyr_agent.builtin_monitors.foo(2)')

        logger_one.openMetricLogForMonitor(metric_file_one, monitor_one)
        logger_two.openMetricLogForMonitor(metric_file_two, monitor_two)

        logger_one.report_values({'foo': 5})
        logger_two.report_values({'bar': 4})

        # The value should only appear in the metric log file and not the main one.
        self.assertTrue(self.__log_contains('foo=5',
                                            file_path=metric_file_one))
        self.assertTrue(self.__log_contains('bar=4',
                                            file_path=metric_file_two))

        self.assertFalse(
            self.__log_contains('foo=5', file_path=metric_file_two))
        self.assertFalse(
            self.__log_contains('bar=4', file_path=metric_file_one))

        self.assertFalse(self.__log_contains('foo=5'))
        self.assertFalse(self.__log_contains('bar=4'))

        logger_one.closeMetricLog()
        logger_two.closeMetricLog()
    def test_module_with_different_metric_logs(self):
        monitor_one = ScalyrLoggingTest.FakeMonitor('testing one')
        monitor_two = ScalyrLoggingTest.FakeMonitor('testing two')

        metric_file_one = tempfile.mktemp('.log')
        metric_file_two = tempfile.mktemp('.log')

        logger_one = scalyr_logging.getLogger('scalyr_agent.builtin_monitors.foo(1)')
        logger_two = scalyr_logging.getLogger('scalyr_agent.builtin_monitors.foo(2)')

        logger_one.openMetricLogForMonitor(metric_file_one, monitor_one)
        logger_two.openMetricLogForMonitor(metric_file_two, monitor_two)

        logger_one.report_values({'foo': 5})
        logger_two.report_values({'bar': 4})

        # The value should only appear in the metric log file and not the main one.
        self.assertTrue(self.__log_contains('foo=5', file_path=metric_file_one))
        self.assertTrue(self.__log_contains('bar=4', file_path=metric_file_two))

        self.assertFalse(self.__log_contains('foo=5', file_path=metric_file_two))
        self.assertFalse(self.__log_contains('bar=4', file_path=metric_file_one))

        self.assertFalse(self.__log_contains('foo=5'))
        self.assertFalse(self.__log_contains('bar=4'))

        logger_one.closeMetricLog()
        logger_two.closeMetricLog()
 def test_component_name(self):
     self.assertEquals(self.__logger.component, 'core')
     self.assertEquals(scalyr_logging.getLogger('scalyr_agent').component, 'core')
     self.assertEquals(scalyr_logging.getLogger('scalyr_agent.foo').component, 'core')
     self.assertEquals(scalyr_logging.getLogger('scalyr_agent.foo.bar').component, 'core')
     self.assertEquals(scalyr_logging.getLogger('scalyr_agent.builtin_monitors.foo').component, 'monitor:foo')
     self.assertEquals(scalyr_logging.getLogger('scalyr_agent.builtin_monitors.foo(ok)').component,
                       'monitor:foo(ok)')
    def test_pass_in_module_with_metric(self):
        monitor_instance = ScalyrLoggingTest.FakeMonitor('testing')
        metric_file_path = tempfile.mktemp('.log')

        monitor_logger = scalyr_logging.getLogger('scalyr_agent.builtin_monitors.foo(1)')
        monitor_logger.openMetricLogForMonitor(metric_file_path, monitor_instance)
        scalyr_logging.getLogger('scalyr_agent.builtin_monitors.foo').report_values({'foo': 5},
                                                                                    monitor=monitor_instance)

        # The value should only appear in the metric log file and not the main one.
        self.assertTrue(self.__log_contains('foo=5', file_path=metric_file_path))
        self.assertFalse(self.__log_contains('foo=5'))

        monitor_logger.closeMetricLog()
 def test_component_name(self):
     self.assertEquals(self.__logger.component, 'core')
     self.assertEquals(
         scalyr_logging.getLogger('scalyr_agent').component, 'core')
     self.assertEquals(
         scalyr_logging.getLogger('scalyr_agent.foo').component, 'core')
     self.assertEquals(
         scalyr_logging.getLogger('scalyr_agent.foo.bar').component, 'core')
     self.assertEquals(
         scalyr_logging.getLogger(
             'scalyr_agent.builtin_monitors.foo').component, 'monitor:foo')
     self.assertEquals(
         scalyr_logging.getLogger(
             'scalyr_agent.builtin_monitors.foo(ok)').component,
         'monitor:foo(ok)')
    def test_rate_limit_no_write_rate(self):
        """
        Drop log messages with log size > max_write_burst but do not drop
        following small log messages
        """
        self.__log_path = tempfile.mktemp('.log')
        scalyr_logging.set_log_destination(use_disk=True,
                                           logs_directory=os.path.dirname(
                                               self.__log_path),
                                           agent_log_file_path=self.__log_path,
                                           max_write_burst=250,
                                           log_write_rate=20000)
        self.__logger = scalyr_logging.getLogger('scalyr_agent.agent_main')

        string_300 = 'a' * 300

        self.__logger.info('First message')
        self.assertTrue(self.__log_contains('First message'))

        self.__logger.info('Dropped message %s', string_300)
        self.assertFalse(self.__log_contains('Dropped message'))

        self.__logger.info('Second message')
        self.assertTrue(self.__log_contains('Second message'))
        self.assertTrue(
            self.__log_contains('Warning, skipped writing 1 log lines'))
示例#10
0
 def test_initialize_monitor(self):
     monitor = ProcessMonitor(
         self.config_commandline,
         scalyr_logging.getLogger("syslog_monitor[test]"))
     self.assertEqual(monitor._ProcessMonitor__metrics_history,
                      defaultdict(dict))
     self.assertEqual(monitor._ProcessMonitor__aggregated_metrics, {})
示例#11
0
    def build_monitor(monitor_config, additional_python_paths,
                      default_sample_interval_secs, global_config):
        """Builds an instance of a ScalyrMonitor for the specified monitor configuration.

        @param monitor_config: The monitor configuration object for the monitor that should be created.  It will
            have keys such as 'module' that specifies the module containing the monitor, as well as others.
        @param additional_python_paths: A list of paths (separate by os.pathsep) to add to the PYTHONPATH when
            instantiating the module in case it needs to packages in other directories.
        @param global_config: The global configuration object

        @type monitor_config: dict
        @type additional_python_paths: str

        @return:  The appropriate ScalyrMonitor instance as controlled by the configuration.
        @rtype: scalyr_monitor.ScalyrMonitor
        """
        # Set up the logs to do the right thing.
        module_name = monitor_config['module']
        monitor_id = monitor_config['id']

        # We have to update this variable before we create monitor instances so that it is used.
        ScalyrMonitor.DEFAULT_SAMPLE_INTERVAL_SECS = default_sample_interval_secs

        # Load monitor.
        monitor_class = MonitorsManager.load_monitor(module_name,
                                                     additional_python_paths)

        # Instantiate and initialize it.
        return monitor_class(monitor_config,
                             scalyr_logging.getLogger(
                                 "%s(%s)" % (module_name, monitor_id)),
                             global_config=global_config)
示例#12
0
    def build_monitor(monitor_config, additional_python_paths, default_sample_interval_secs, global_config ):
        """Builds an instance of a ScalyrMonitor for the specified monitor configuration.

        @param monitor_config: The monitor configuration object for the monitor that should be created.  It will
            have keys such as 'module' that specifies the module containing the monitor, as well as others.
        @param additional_python_paths: A list of paths (separate by os.pathsep) to add to the PYTHONPATH when
            instantiating the module in case it needs to packages in other directories.
        @param global_config: The global configuration object

        @type monitor_config: dict
        @type additional_python_paths: str

        @return:  The appropriate ScalyrMonitor instance as controlled by the configuration.
        @rtype: scalyr_monitor.ScalyrMonitor
        """
        # Set up the logs to do the right thing.
        module_name = monitor_config['module']
        monitor_id = monitor_config['id']

        # We have to update this variable before we create monitor instances so that it is used.
        ScalyrMonitor.DEFAULT_SAMPLE_INTERVAL_SECS = default_sample_interval_secs

        # Load monitor.
        monitor_class = MonitorsManager.load_monitor(module_name, additional_python_paths)

        # Instantiate and initialize it.
        return monitor_class(monitor_config, scalyr_logging.getLogger("%s(%s)" % (module_name, monitor_id)), global_config=global_config)
    def test_run_udp_server(self):
        config = {
            'module': 'scalyr_agent.builtin_monitors.syslog_monitor',
            'protocols': 'udp:5514',
        }
        self.monitor = SyslogMonitor(config, scalyr_logging.getLogger("syslog_monitor[test]"))
        self.monitor.open_metric_log()
        self.monitor.start()

        time.sleep(0.1)

        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sockets.append(s)

        expected = "UDP Test %s" % (uuid.uuid4())
        s.sendto(expected, ('localhost', 5514))
        time.sleep(1)
        self.monitor.stop(wait_on_join=False)
        self.monitor = None
        f = open('agent_syslog.log')
        actual = f.read().strip()
        self.assertTrue(
            expected in actual,
            "Unable to find '%s' in output:\n\t %s" % (expected, actual)
        )
 def setUp(self):
     self.config_commandline = {
         "module": "scalyr_agent.builtin_monitors.linux_process_metrics",
         "id": "myapp",
         "commandline": ".foo.*",
     }
     self.monitor = ProcessMonitor(self.config_commandline, scalyr_logging.getLogger("syslog_monitor[test]"))
示例#15
0
    def test_rate_limit_throttle_write_rate(self):
        """
        Drop log messages with log size > max_write_burst and other following
        log messages if log write rate is low.
        """
        self.__log_path = tempfile.mktemp(".log")
        scalyr_logging.set_log_destination(
            use_disk=True,
            logs_directory=os.path.dirname(self.__log_path),
            agent_log_file_path=self.__log_path,
            max_write_burst=250,
            log_write_rate=0,
        )
        self.__logger = scalyr_logging.getLogger("scalyr_agent.agent_main")

        string_300 = "a" * 300

        self.__logger.info("First message")
        self.assertTrue(self.__log_contains("First message"))

        self.__logger.info("Dropped message %s", string_300)
        self.assertFalse(self.__log_contains("Dropped message"))

        self.__logger.info("Second message")
        self.assertFalse(self.__log_contains("Second message"))
    def test_rate_limit(self):
        self.__log_path = tempfile.mktemp('.log')
        scalyr_logging.set_log_destination(use_disk=True,
                                           logs_directory=os.path.dirname(
                                               self.__log_path),
                                           agent_log_file_path=self.__log_path,
                                           max_write_burst=250,
                                           log_write_rate=0)
        self.__logger = scalyr_logging.getLogger('scalyr_agent.agent_main')

        string_300 = ''

        for i in range(300):
            string_300 = '%sa' % string_300

        self.__logger.info('First message')
        self.assertTrue(self.__log_contains('First message'))

        self.__logger.info('Dropped message %s', string_300)
        self.assertFalse(self.__log_contains('Dropped message'))

        self.__logger.info('Second message')
        self.assertTrue(self.__log_contains('Second message'))
        self.assertTrue(
            self.__log_contains('Warning, skipped writing 1 log lines'))
 def setUp(self):
     self.__log_path = tempfile.mktemp('.log')
     scalyr_logging.set_log_destination(use_disk=True,
                                        logs_directory=os.path.dirname(
                                            self.__log_path),
                                        agent_log_file_path=self.__log_path)
     self.__logger = scalyr_logging.getLogger('scalyr_agent.agent_main')
    def test_run_udp_server(self):
        config = {
            'module': 'scalyr_agent.builtin_monitors.syslog_monitor',
            'protocols': 'udp:5514',
        }
        self.monitor = SyslogMonitor(config, scalyr_logging.getLogger("syslog_monitor[test]"))
        self.monitor.open_metric_log()
        self.monitor.start()

        time.sleep(0.1)

        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sockets.append(s)

        expected = "UDP Test {}".format(uuid.uuid4())
        s.sendto(expected, ('localhost', 5514))
        time.sleep(1)
        self.monitor.stop(wait_on_join=False)
        self.monitor = None
        f = open('agent_syslog.log')
        actual = f.read().strip()
        self.assertTrue(
            expected in actual,
            "Unable to find '%s' in output:\n\t %s" % (expected, actual)
        )
示例#19
0
    def test_run_multiple_servers(self):
        config = {
            'module': 'scalyr_agent.builtin_monitors.syslog_monitor',
            'protocols': 'udp:8000, tcp:8001, udp:8002, tcp:8003',
        }
        self.monitor = SyslogMonitor(
            config, scalyr_logging.getLogger("syslog_monitor[test]"))
        self.monitor.open_metric_log()

        self.monitor.start()

        time.sleep(0.05)

        udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sockets.append(udp)

        tcp1 = socket.socket()
        self.sockets.append(tcp1)

        tcp2 = socket.socket()
        self.sockets.append(tcp2)

        self.connect(tcp1, ('localhost', 8001))
        self.connect(tcp2, ('localhost', 8003))

        expected_udp1 = "UDP Test"
        udp.sendto(expected_udp1, ('localhost', 8000))

        expected_udp2 = "UDP2 Test"
        udp.sendto(expected_udp2, ('localhost', 8002))

        expected_tcp1 = "TCP Test\n"
        tcp1.sendall(expected_tcp1)

        expected_tcp2 = "TCP2 Test\n"
        tcp2.sendall(expected_tcp2)

        time.sleep(1)

        self.monitor.stop(wait_on_join=False)
        self.monitor = None

        f = open('agent_syslog.log')
        actual = f.read().strip()

        expected_tcp1 = expected_tcp1.strip()
        expected_tcp2 = expected_tcp2.strip()

        self.assertTrue(
            expected_udp1 in actual,
            "Unable to find '%s' in output:\n\t %s" % (expected_udp1, actual))
        self.assertTrue(
            expected_udp2 in actual,
            "Unable to find '%s' in output:\n\t %s" % (expected_udp2, actual))
        self.assertTrue(
            expected_tcp1 in actual,
            "Unable to find '%s' in output:\n\t %s" % (expected_tcp1, actual))
        self.assertTrue(
            expected_tcp2 in actual,
            "Unable to find '%s' in output:\n\t %s" % (expected_tcp2, actual))
 def test_config_protocol_multiple_two(self):
     config = {
         "module": "scalyr_agent.builtin_monitors.syslog_monitor",
         "protocols": "tcp, udp",
     }
     self.assertNoException(lambda: SyslogMonitor(
         config, scalyr_logging.getLogger("syslog_monitor[test]")))
    def test_metric_logging_metric_name_blacklist(self):
        monitor_instance = ScalyrLoggingTest.FakeMonitor("testing")
        monitor_instance._metric_name_blacklist = ["name1", "name3"]
        metric_file_path = tempfile.mktemp(".log")

        monitor_logger = scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo(1)")
        monitor_logger.openMetricLogForMonitor(metric_file_path,
                                               monitor_instance)
        monitor_logger.emit_value("name1", 5, {"foo": 5})
        monitor_logger.emit_value("name2", 6, {"foo": 6})
        monitor_logger.emit_value("name3", 7, {"foo": 7})
        monitor_logger.emit_value("name4", 8, {"foo": 8})

        self.assertEquals(monitor_instance.reported_lines, 2)

        # The value should only appear in the metric log file and not the main one.
        self.assertLogFileContainsLineRegex(file_path=metric_file_path,
                                            expression="name2")
        self.assertLogFileContainsLineRegex(file_path=metric_file_path,
                                            expression="foo=6")
        self.assertLogFileContainsLineRegex(file_path=metric_file_path,
                                            expression="name4")
        self.assertLogFileContainsLineRegex(file_path=metric_file_path,
                                            expression="foo=8")
        self.assertLogFileDoesntContainsLineRegex(file_path=metric_file_path,
                                                  expression="name1")
        self.assertLogFileDoesntContainsLineRegex(file_path=metric_file_path,
                                                  expression="name3")

        monitor_logger.closeMetricLog()
    def test_metric_logging_with_bad_name(self):
        monitor_instance = ScalyrLoggingTest.FakeMonitor("testing")

        metric_file_fd, metric_file_path = tempfile.mkstemp(".log")

        # NOTE: We close the fd here because we open it again below. This way file deletion at
        # the end works correctly on Windows.
        os.close(metric_file_fd)

        monitor_logger = scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo(1)")
        monitor_logger.openMetricLogForMonitor(metric_file_path,
                                               monitor_instance)

        monitor_logger.emit_value("1name", 5)
        self.assertLogFileContainsLineRegex(file_path=metric_file_path,
                                            expression="sa_1name")

        monitor_logger.emit_value("name+hi", 5)
        self.assertLogFileContainsLineRegex(file_path=metric_file_path,
                                            expression="name_hi")

        monitor_logger.emit_value("name", 5, {"hi+": 6})
        self.assertLogFileContainsLineRegex(file_path=metric_file_path,
                                            expression="hi_")

        monitor_logger.closeMetricLog()
示例#23
0
    def build_monitor(monitor_config, additional_python_paths):
        """Builds an instance of a ScalyrMonitor for the specified monitor configuration.

        @param monitor_config: The monitor configuration object for the monitor that should be created.  It will
            have keys such as 'module' that specifies the module containing the monitor, as well as others.
        @param additional_python_paths: A list of paths (separate by os.pathsep) to add to the PYTHONPATH when
            instantiating the module in case it needs to packages in other directories.

        @type monitor_config: dict
        @type additional_python_paths: str

        @return:  The appropriate ScalyrMonitor instance as controlled by the configuration.
        @rtype: scalyr_monitor.ScalyrMonitor
        """
        # Set up the logs to do the right thing.
        module_name = monitor_config['module']
        monitor_id = monitor_config['id']

        # Load monitor.
        monitor_class = MonitorsManager.load_monitor(module_name,
                                                     additional_python_paths)

        # Instantiate and initialize it.
        return monitor_class(
            monitor_config,
            scalyr_logging.getLogger("%s(%s)" % (module_name, monitor_id)))
示例#24
0
 def setUp(self):
     super(TestUtilWithLogCapture, self).setUp()
     self.__logger = scalyr_logging.getLogger("util")
     self.__logger.set_keep_last_record(False)
     self.__tempdir = tempfile.mkdtemp()
     self.__path = os.path.join(self.__tempdir, "testing.json")
     self.__temp_file_path = self.__path + "~"
示例#25
0
 def setUp(self):
     self.config_commandline = {
         "module": "scalyr_agent.builtin_monitors.linux_process_metrics",
         "id": "myapp",
         "commandline": ".foo.*",
     }
     self.monitor = ProcessMonitor(self.config_commandline, scalyr_logging.getLogger("syslog_monitor[test]"))
    def test_metric_logging_extra_fields_are_sorted(self):
        monitor_instance = ScalyrLoggingTest.FakeMonitor("testing")
        metric_file_fd, metric_file_path = tempfile.mkstemp(".log")

        # NOTE: We close the fd here because we open it again below. This way file deletion at
        # the end works correctly on Windows.
        os.close(metric_file_fd)

        monitor_logger = scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo(1)")
        monitor_logger.openMetricLogForMonitor(metric_file_path,
                                               monitor_instance)
        monitor_logger.emit_value("test_name", 5, {
            "g": 9,
            "c": 5,
            "a": 7,
            "b": 8
        })

        self.assertEquals(monitor_instance.reported_lines, 1)

        # The value should only appear in the metric log file and not the main one.
        self.assertLogFileContainsLineRegex(file_path=metric_file_path,
                                            expression="test_name 5")
        self.assertLogFileContainsLineRegex(file_path=metric_file_path,
                                            expression="a=7 b=8 c=5 g=9")
        self.assertLogFileDoesntContainsLineRegex(expression="a=7")
        self.assertLogFileDoesntContainsLineRegex(expression="g=9")

        monitor_logger.closeMetricLog()
    def test_run_udp_server(self):
        config = {
            "module": "scalyr_agent.builtin_monitors.syslog_monitor",
            "protocols": "udp:5514",
            "log_flush_delay": 0.0,
        }
        self.monitor = TestSyslogMonitor(
            config, scalyr_logging.getLogger("syslog_monitor[test]"))
        self.monitor.open_metric_log()
        self.monitor.start()

        time.sleep(0.1)

        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sockets.append(s)

        expected = "UDP Test %s" % (uuid.uuid4())
        self.send_and_wait_for_lines(s,
                                     expected,
                                     dest_addr=("localhost", 5514))

        # without close, the logger will interfere with other test cases.
        self.monitor.close_metric_log()

        self.monitor.stop(wait_on_join=False)
        self.monitor = None
        f = open("agent_syslog.log", "r")
        actual = f.read().strip()
        self.assertTrue(
            expected in actual,
            "Unable to find '%s' in output:\n\t %s" % (expected, actual),
        )
示例#28
0
 def test_config_protocol_multiple_two(self):
     config = {
         'module': 'scalyr_agent.builtin_monitors.syslog_monitor',
         'protocols': 'tcp, udp'
     }
     self.assertNoException(lambda: SyslogMonitor(
         config, scalyr_logging.getLogger("syslog_monitor[test]")))
示例#29
0
 def test_config_port_too_high(self):
     config = {
         'module': 'scalyr_agent.builtin_monitors.syslog_monitor',
         'protocols': 'udp:70000'
     }
     self.assertRaises(
         Exception, lambda: SyslogMonitor(
             config, scalyr_logging.getLogger("syslog_monitor[test]")))
示例#30
0
 def test_config_protocol_invalid(self):
     config = {
         'module': 'scalyr_agent.builtin_monitors.syslog_monitor',
         'protocols': 'XXX'
     }
     self.assertRaises(
         Exception, lambda: SyslogMonitor(
             config, scalyr_logging.getLogger("syslog_monitor[test]")))
    def test_rate_limit_no_write_rate(self):
        """
        Drop log messages with log size > max_write_burst but do not drop
        following small log messages
        """
        max_write_burst = 500
        log_write_rate = 20000

        scalyr_logging.set_log_destination(
            use_disk=True,
            logs_directory=os.path.dirname(self.__log_path),
            agent_log_file_path=self.__log_path,
            max_write_burst=max_write_burst,
            log_write_rate=log_write_rate,
        )
        self.__logger = scalyr_logging.getLogger("scalyr_agent.agent_main")

        self.__logger.set_keep_last_record(True)
        # NOTE: Actual value which is being used for the rate limitting is the formatted value
        # and that value contains much more information than the string we generate here.
        # This means that 450 + common formatted string data will aways be > 500 and we need to
        # make sure that "max_write_burst" value we use is large enough so formatted "First
        # message" and "Second message" (with a warning) fit in that value, otherwise depending
        # on the timing and fill rate, the test may fail.
        string_450 = "a" * 450

        self.__logger.info("First message")
        self.assertLogFileContainsLineRegex(expression="First message")

        first_message_record = self.__logger.last_record
        self.assertEqual(first_message_record.message, "First message")

        self.__logger.info("Dropped message %s", string_450)
        self.assertLogFileDoesntContainsLineRegex(expression="Dropped message")

        self.__logger.info("Second message")

        second_message_record = self.__logger.last_record
        self.assertEqual(second_message_record.message, "Second message")

        # Verify that formatted first mesage + second message length is not larger then 500
        # (max_write_burst) which would indicate invalid test which may intermediatly fail
        # depending on the test timing
        self.assertEqual(1, second_message_record.rate_limited_dropped_records)

        if (first_message_record.formatted_size +
                second_message_record.formatted_size) >= max_write_burst:
            self.fail(
                "Length of the formatted first and second mesage string is longer than "
                "%s bytes (max_write_burst). Increase max_write_burst used or update the "
                "strings otherwise tests may occasionally fail." %
                (max_write_burst))

        self.assertLogFileContainsLineRegex(expression="Second message")
        expression = "Warning, skipped writing 1 log lines"
        self.assertLogFileContainsLineRegex(expression=expression)
        self.assertTrue(second_message_record.rate_limited_result)
        self.assertTrue(second_message_record.rate_limited_set)
 def test_component_name(self):
     self.assertEquals(self.__logger.component, "core")
     self.assertEquals(
         scalyr_logging.getLogger("scalyr_agent").component, "core")
     self.assertEquals(
         scalyr_logging.getLogger("scalyr_agent.foo").component, "core")
     self.assertEquals(
         scalyr_logging.getLogger("scalyr_agent.foo.bar").component, "core")
     self.assertEquals(
         scalyr_logging.getLogger(
             "scalyr_agent.builtin_monitors.foo").component,
         "monitor:foo",
     )
     self.assertEquals(
         scalyr_logging.getLogger(
             "scalyr_agent.builtin_monitors.foo(ok)").component,
         "monitor:foo(ok)",
     )
    def test_pass_in_module_with_metric(self):
        monitor_instance = ScalyrLoggingTest.FakeMonitor("testing")
        metric_file_path = tempfile.mktemp(".log")

        monitor_logger = scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo(1)")
        monitor_logger.openMetricLogForMonitor(metric_file_path,
                                               monitor_instance)
        scalyr_logging.getLogger(
            "scalyr_agent.builtin_monitors.foo").report_values(
                {"foo": 5}, monitor=monitor_instance)

        # The value should only appear in the metric log file and not the main one.
        self.assertLogFileContainsLineRegex(file_path=metric_file_path,
                                            expression="foo=5")
        self.assertLogFileDoesntContainsLineRegex(expression="foo=5")

        monitor_logger.closeMetricLog()
示例#34
0
 def setUp(self):
     super(ScalyrLoggingTest, self).setUp()
     self.__log_path = tempfile.mktemp(".log")
     scalyr_logging.set_log_destination(
         use_disk=True,
         logs_directory=os.path.dirname(self.__log_path),
         agent_log_file_path=self.__log_path,
     )
     self.__logger = scalyr_logging.getLogger("scalyr_agent.agent_main")
    def test_pass_in_module_with_metric(self):
        monitor_instance = ScalyrLoggingTest.FakeMonitor('testing')
        metric_file_path = tempfile.mktemp('.log')

        monitor_logger = scalyr_logging.getLogger(
            'scalyr_agent.builtin_monitors.foo(1)')
        monitor_logger.openMetricLogForMonitor(metric_file_path,
                                               monitor_instance)
        scalyr_logging.getLogger(
            'scalyr_agent.builtin_monitors.foo').report_values(
                {'foo': 5}, monitor=monitor_instance)

        # The value should only appear in the metric log file and not the main one.
        self.assertTrue(
            self.__log_contains('foo=5', file_path=metric_file_path))
        self.assertFalse(self.__log_contains('foo=5'))

        monitor_logger.closeMetricLog()
 def test_config_port_too_high(self):
     config = {
         "module": "scalyr_agent.builtin_monitors.syslog_monitor",
         "protocols": "udp:70000",
     }
     self.assertRaises(
         Exception,
         lambda: SyslogMonitor(
             config, scalyr_logging.getLogger("syslog_monitor[test]")),
     )
    def test_errors_for_monitor(self):
        monitor_instance = ScalyrLoggingTest.FakeMonitor('testing')
        metric_file_path = tempfile.mktemp('.log')

        monitor_logger = scalyr_logging.getLogger('scalyr_agent.builtin_monitors.foo(1)')
        monitor_logger.openMetricLogForMonitor(metric_file_path, monitor_instance)
        monitor_logger.error('Foo')

        self.assertEquals(monitor_instance.errors, 1)

        monitor_logger.closeMetricLog()
    def test_metric_logging_with_bad_name(self):
        monitor_instance = ScalyrLoggingTest.FakeMonitor('testing')
        metric_file_path = tempfile.mktemp('.log')

        monitor_logger = scalyr_logging.getLogger('scalyr_agent.builtin_monitors.foo(1)')
        monitor_logger.openMetricLogForMonitor(metric_file_path, monitor_instance)

        self.assertRaises(scalyr_logging.BadMetricOrFieldName, monitor_logger.emit_value, '1name', 5)
        self.assertRaises(scalyr_logging.BadMetricOrFieldName, monitor_logger.emit_value, 'name+hi', 5)
        self.assertRaises(scalyr_logging.BadMetricOrFieldName, monitor_logger.emit_value, 'name', 5, {'hi+': 6})

        monitor_logger.closeMetricLog()
    def test_run_multiple_servers( self ):
        config = {
            'module': 'scalyr_agent.builtin_monitors.syslog_monitor',
            'protocols': 'udp:8000, tcp:8001, udp:8002, tcp:8003',
        }
        self.monitor = SyslogMonitor( config, scalyr_logging.getLogger( "syslog_monitor[test]" ) )
        self.monitor.open_metric_log()

        self.monitor.start()

        time.sleep( 0.01 )

        udp = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
        self.sockets.append( udp )

        tcp1 = socket.socket()
        self.sockets.append( tcp1 )

        tcp2 = socket.socket()
        self.sockets.append( tcp2 )

        self.connect( tcp1, ('localhost', 8001) )
        self.connect( tcp2, ('localhost', 8003) )


        expected_udp1 = "UDP Test"
        udp.sendto( expected_udp1, ('localhost', 8000) )

        expected_udp2 = "UDP2 Test"
        udp.sendto( expected_udp2, ('localhost', 8002) )

        expected_tcp1 = "TCP Test\n"
        tcp1.sendall( expected_tcp1 )

        expected_tcp2 = "TCP2 Test\n"
        tcp2.sendall( expected_tcp2 )

        time.sleep( 1 )

        self.monitor.stop( wait_on_join=False )
        self.monitor = None

        self.handler.flush()
        actual = self.stream.getvalue().strip()

        expected_tcp1 = expected_tcp1.strip()
        expected_tcp2 = expected_tcp2.strip()

        self.assertTrue( expected_udp1 in actual, "Unable to find '%s' in output:\n\t %s" % (expected_udp1, actual)  )
        self.assertTrue( expected_udp2 in actual, "Unable to find '%s' in output:\n\t %s" % (expected_udp2, actual)  )
        self.assertTrue( expected_tcp1 in actual, "Unable to find '%s' in output:\n\t %s" % (expected_tcp1, actual)  )
        self.assertTrue( expected_tcp2 in actual, "Unable to find '%s' in output:\n\t %s" % (expected_tcp2, actual)  )
    def test_logging_to_metric_log(self):
        monitor_instance = ScalyrLoggingTest.FakeMonitor('testing')
        metric_file_path = tempfile.mktemp('.log')

        monitor_logger = scalyr_logging.getLogger('scalyr_agent.builtin_monitors.foo(1)')
        monitor_logger.openMetricLogForMonitor(metric_file_path, monitor_instance)
        monitor_logger.info('foobaz is fine', emit_to_metric_log=True)

        self.assertEquals(monitor_instance.reported_lines, 1)

        # The value should only appear in the metric log file and not the main one.
        self.assertTrue(self.__log_contains('foobaz is fine', file_path=metric_file_path))
        self.assertFalse(self.__log_contains('foobaz is fine'))

        monitor_logger.closeMetricLog()
    def test_rate_limit(self):
        self.__log_path = tempfile.mktemp('.log')
        scalyr_logging.set_log_destination(use_disk=True, logs_directory=os.path.dirname(self.__log_path),
                                           agent_log_file_path=self.__log_path, max_write_burst=250, log_write_rate=0)
        self.__logger = scalyr_logging.getLogger('scalyr_agent.agent_main')

        string_300 = ''

        for i in range(300):
            string_300 = '%sa' % string_300

        self.__logger.info('First message')
        self.assertTrue(self.__log_contains('First message'))

        self.__logger.info('Dropped message %s', string_300)
        self.assertFalse(self.__log_contains('Dropped message'))

        self.__logger.info('Second message')
        self.assertTrue(self.__log_contains('Second message'))
        self.assertTrue(self.__log_contains('Warning, skipped writing 1 log lines'))
    def test_limit_once_per_x_secs(self):
        log = scalyr_logging.getLogger('scalyr_agent.foo')
        log.info('First record', limit_once_per_x_secs=60.0, limit_key='foo', current_time=0.0)
        log.info('Second record', limit_once_per_x_secs=60.0, limit_key='foo', current_time=1.0)
        log.info('Third record', limit_once_per_x_secs=60.0, limit_key='foo', current_time=61.0)

        self.assertTrue(self.__log_contains('First record'))
        self.assertFalse(self.__log_contains('Second record'))
        self.assertTrue(self.__log_contains('Third record'))

        # Now test with different keys.
        log.info('First record', limit_once_per_x_secs=30.0, limit_key='foo', current_time=0.0)
        log.info('Second record', limit_once_per_x_secs=60.0, limit_key='bar', current_time=1.0)
        log.info('Third record', limit_once_per_x_secs=30.0, limit_key='foo', current_time=31.0)
        log.info('Fourth record', limit_once_per_x_secs=60.0, limit_key='bar', current_time=31.0)

        self.assertTrue(self.__log_contains('First record'))
        self.assertTrue(self.__log_contains('Second record'))
        self.assertTrue(self.__log_contains('Third record'))
        self.assertFalse(self.__log_contains('Fourth record'))
    def build_monitor(monitor_config, additional_python_paths):
        """Builds an instance of a ScalyrMonitor for the specified monitor configuration.

        @param monitor_config: The monitor configuration object for the monitor that should be created.  It will
            have keys such as 'module' that specifies the module containing the monitor, as well as others.
        @param additional_python_paths: A list of paths (separate by os.pathsep) to add to the PYTHONPATH when
            instantiating the module in case it needs to packages in other directories.

        @type monitor_config: dict
        @type additional_python_paths: str

        @return:  The appropriate ScalyrMonitor instance as controlled by the configuration.
        @rtype: scalyr_monitor.ScalyrMonitor
        """
        # Set up the logs to do the right thing.
        module_name = monitor_config['module']
        monitor_id = monitor_config['id']

        # Augment the PYTHONPATH if requested to locate the module.
        original_path = list(sys.path)

        # Also add in scalyr_agent/../monitors/local and scalyr_agent/../monitors/contrib to the Python path to search
        # for monitors.  (They are always in the parent directory of the scalyr_agent package.
        path_to_package_parent = os.path.dirname(get_package_root())
        sys.path.append(os.path.join(path_to_package_parent, 'monitors', 'local'))
        sys.path.append(os.path.join(path_to_package_parent, 'monitors', 'contrib'))

        # Add in the additional paths.
        if additional_python_paths is not None and len(additional_python_paths) > 0:
            for x in additional_python_paths.split(os.pathsep):
                sys.path.append(x)

        # Load monitor.
        try:
            monitor_class = MonitorsManager.__load_class_from_module(module_name)
        finally:
            # Be sure to reset the PYTHONPATH
            sys.path = original_path

        # Instantiate and initialize it.
        return monitor_class(monitor_config, scalyr_logging.getLogger("%s(%s)" % (module_name, monitor_id)))
    def build_monitor(monitor_config, additional_python_paths):
        """Builds an instance of a ScalyrMonitor for the specified monitor configuration.

        @param monitor_config: The monitor configuration object for the monitor that should be created.  It will
            have keys such as 'module' that specifies the module containing the monitor, as well as others.
        @param additional_python_paths: A list of paths (separate by os.pathsep) to add to the PYTHONPATH when
            instantiating the module in case it needs to packages in other directories.

        @type monitor_config: dict
        @type additional_python_paths: str

        @return:  The appropriate ScalyrMonitor instance as controlled by the configuration.
        @rtype: scalyr_monitor.ScalyrMonitor
        """
        # Set up the logs to do the right thing.
        module_name = monitor_config['module']
        monitor_id = monitor_config['id']

        # Load monitor.
        monitor_class = MonitorsManager.load_monitor(module_name, additional_python_paths)

        # Instantiate and initialize it.
        return monitor_class(monitor_config, scalyr_logging.getLogger("%s(%s)" % (module_name, monitor_id)))
示例#45
0
from __scalyr__ import scalyr_init

scalyr_init()

import scalyr_agent.scalyr_logging as scalyr_logging
import scalyr_agent.json_lib as json_lib
from scalyr_agent.log_watcher import LogWatcher

from scalyr_agent.monitors_manager import MonitorsManager
from scalyr_agent.scalyr_monitor import BadMonitorConfiguration

from scalyr_agent.configuration import Configuration
from scalyr_agent.platform_controller import PlatformController, DefaultPaths

log = scalyr_logging.getLogger('scalyr_agent.run_monitor')


def run_standalone_monitor(monitor_module, monitor_python_path, monitor_config, monitor_sample_interval,
                           monitor_debug_level, global_config_path):
    """Runs a single plugin monitor instance.

    @param monitor_module: The name of the python module implementing the monitor.
    @param monitor_python_path: The python path to search to find the module.
    @param monitor_config: The monitor configuration object.
    @param monitor_sample_interval: The default to use for the sample interval.
    @param monitor_debug_level: The debug level to use for logging.
    @param global_config_path:  The path to the agent.json global configuration file to use, or None if none was
        supplied.
    """
    scalyr_logging.set_log_destination(use_stdout=True)
 def test_initialize_monitor(self):
     monitor = ProcessMonitor(self.config_commandline, scalyr_logging.getLogger("syslog_monitor[test]"))
     self.assertEqual(monitor._ProcessMonitor__metrics_history, defaultdict(dict))
     self.assertEqual(monitor._ProcessMonitor__aggregated_metrics, {})
 def test_config_port_too_high(self):
     config = {
         'module': 'scalyr_agent.builtin_monitors.syslog_monitor',
         'protocols': 'udp:70000'
     }
     self.assertRaises(Exception, lambda: SyslogMonitor(config, scalyr_logging.getLogger("syslog_monitor[test]")))
 def test_config_protocol_invalid(self):
     config = {
         'module': 'scalyr_agent.builtin_monitors.syslog_monitor',
         'protocols': 'XXX'
     }
     self.assertRaises(Exception, lambda: SyslogMonitor(config, scalyr_logging.getLogger("syslog_monitor[test]")))
 def test_config_protocol_multiple_two(self):
     config = {
         'module': 'scalyr_agent.builtin_monitors.syslog_monitor',
         'protocols': 'tcp, udp'
     }
     self.assertNoException(lambda: SyslogMonitor(config, scalyr_logging.getLogger("syslog_monitor[test]")))
 def setUp(self):
     self.__log_path = tempfile.mktemp('.log')
     scalyr_logging.set_log_destination(use_disk=True, logs_directory=os.path.dirname(self.__log_path),
                                        agent_log_file_path=self.__log_path)
     self.__logger = scalyr_logging.getLogger('scalyr_agent.agent_main')
 def test_child_modules(self):
     child = scalyr_logging.getLogger('scalyr_agent.foo.bar')
     child.info('Child statement')
     self.assertTrue(self.__log_contains('Child statement'))
 def test_sibling_modules(self):
     child = scalyr_logging.getLogger('external_package.my_monitor')
     child.info('Sibling statement')
     self.assertTrue(self.__log_contains('Sibling statement'))
__author__ = '*****@*****.**'

import os
import threading
import time
import sys

import scalyr_agent.scalyr_logging as scalyr_logging
import scalyr_agent.util as scalyr_util

from scalyr_agent import json_lib
from scalyr_agent.util import StoppableThread
from scalyr_agent.log_processing import LogMatcher, LogFileProcessor
from scalyr_agent.agent_status import CopyingManagerStatus

log = scalyr_logging.getLogger(__name__)


class CopyingParameters(object):
    """Tracks the copying parameters that should be used for sending requests to Scalyr and adjusts them over time
    according to success and failures of requests.

    The copying parameters boil down to two parameters:  the maximum number of bytes that can be sent to Scalyr
    in a request (self.current_bytes_allowed_to_send), and the minimum amount of time to wait between requests
    (self.current_sleep_interval).

    This implements a truncated binary backoff algorithm.
    """
    def __init__(self, configuration):
        """Initialize the parameters based on the thresholds defined in the configuration file.