def setUp(self): thread_patch = mock.patch("threading.Thread", autospec=True) thread_patch.start() self.addCleanup(thread_patch.stop) configurator = Configurator() configurator.add_route("example", "/example", request_method="GET") configurator.add_view(example_application, route_name="example", renderer="json") configurator.add_route("local_test", "/local_test", request_method="GET") configurator.add_view(local_parent_trace_within_context, route_name="local_test", renderer="json") self.client = make_client("test-service") self.observer = TraceBaseplateObserver(self.client) self.baseplate = Baseplate() self.baseplate.register(self.observer) self.baseplate_configurator = BaseplateConfigurator( self.baseplate, trust_trace_headers=True, ) configurator.include(self.baseplate_configurator.includeme) app = configurator.make_wsgi_app() self.local_span_ids = [] self.local_span_observers = [] self.test_app = webtest.TestApp(app)
def test_should_sample_utilizes_sampled_setting(self): client = make_client("test-service", sample_rate=0) baseplate_observer = TraceBaseplateObserver(client) span_with_sampled_flag = Span('test-id', 'test-parent', 'test-span-id', True, 0, "test", self.mock_context) self.assertTrue( baseplate_observer.should_sample(span_with_sampled_flag))
def configure_tracing(self, tracing_client, *args, **kwargs): """Collect and send span information for request tracing. When configured, this will send tracing information automatically collected by Baseplate to the configured distributed tracing service. :param baseplate.diagnostics.tracing.TracingClient tracing_client: Tracing client to send request traces to. """ # pylint: disable=cyclic-import from baseplate.diagnostics.tracing import make_client, TraceBaseplateObserver, TracingClient # the first parameter was service_name before, so if it's not a client # object we'll act like this is the old-style invocation and use the # first parameter as service_name instead, passing on the old arguments if not isinstance(tracing_client, TracingClient): warn_deprecated( "Passing tracing configuration directly to " "configure_tracing is deprecated in favor of " "using baseplate.tracing_client_from_config and " "passing the constructed client on." ) tracing_client = make_client(tracing_client, *args, **kwargs) self.register(TraceBaseplateObserver(tracing_client))
def test_configure_tracing_with_defaults_new_style(self): baseplate = Baseplate() self.assertEqual(0, len(baseplate.observers)) client = make_client("test") baseplate.configure_tracing(client) self.assertEqual(1, len(baseplate.observers)) tracing_observer = baseplate.observers[0] self.assertEqual('test', tracing_observer.service_name)
def test_remote_recorder_setup(self): client = make_client( "test-service", tracing_endpoint=Endpoint("test:1111")) baseplate_observer = TraceBaseplateObserver(client) self.assertTrue( isinstance(baseplate_observer.recorder, RemoteRecorder) )
def test_configure_tracing_with_defaults_new_style(self): baseplate = Baseplate() self.assertEqual(0, len(baseplate.observers)) client = make_client("test") baseplate.configure_tracing(client) self.assertEqual(1, len(baseplate.observers)) tracing_observer = baseplate.observers[0] self.assertEqual('test',tracing_observer.service_name)
def test_should_sample_utilizes_sample_rate(self): client = make_client("test-service", sample_rate=1) baseplate_observer = TraceBaseplateObserver(client) span = Span('test-id', 'test-parent', 'test-span-id', None, 0, "test", self.mock_context) self.assertTrue(baseplate_observer.should_sample(span)) baseplate_observer.sample_rate = 0 self.assertFalse(baseplate_observer.should_sample(span))
def test_no_tracing_without_sampling(self): client = make_client("test-service", sample_rate=0) baseplate_observer = TraceBaseplateObserver(client) context_mock = mock.Mock() span = ServerSpan('test-id', 'test-parent-id', 'test-span-id', False, 0, 'test', self.mock_context) baseplate_observer.on_server_span_created(context_mock, span) self.assertEqual(len(span.observers), 0)
def test_register_server_span_observer(self): client = make_client("test-service") baseplate_observer = TraceBaseplateObserver(client) context_mock = mock.Mock() span = ServerSpan('test-id', 'test-parent-id', 'test-span-id', True, 0, 'test', self.mock_context) baseplate_observer.on_server_span_created(context_mock, span) self.assertEqual(len(span.observers), 1) self.assertEqual(type(span.observers[0]), TraceServerSpanObserver)
def test_should_sample_utilizes_force_sampling(self): client = make_client("test-service", sample_rate=0) baseplate_observer = TraceBaseplateObserver(client) span_with_forced = Span('test-id', 'test-parent', 'test-span-id', False, 1, "test", self.mock_context) span_without_forced = Span('test-id', 'test-parent', 'test-span-id', False, 0, "test", self.mock_context) self.assertTrue(baseplate_observer.should_sample(span_with_forced)) self.assertFalse(baseplate_observer.should_sample(span_without_forced))
def test_should_sample_utilizes_sampled_setting(self): client = make_client("test-service", sample_rate=0) baseplate_observer = TraceBaseplateObserver(client) span_with_sampled_flag = Span('test-id', 'test-parent', 'test-span-id', True, 0, "test", self.mock_context) self.assertTrue( baseplate_observer.should_sample(span_with_sampled_flag) )
def setUp(self): configurator = Configurator() configurator.add_route("example", "/example", request_method="GET") configurator.add_view( example_application, route_name="example", renderer="json") self.client = make_client("test-service") self.observer = TraceBaseplateObserver(self.client) self.baseplate = Baseplate() self.baseplate.register(self.observer) self.baseplate_configurator = BaseplateConfigurator( self.baseplate, trust_trace_headers=True, ) configurator.include(self.baseplate_configurator.includeme) app = configurator.make_wsgi_app() self.test_app = webtest.TestApp(app)
def setUp(self): configurator = Configurator() configurator.add_route("example", "/example", request_method="GET") configurator.add_view(example_application, route_name="example", renderer="json") self.client = make_client("test-service") self.observer = TraceBaseplateObserver(self.client) self.baseplate = Baseplate() self.baseplate.register(self.observer) self.baseplate_configurator = BaseplateConfigurator( self.baseplate, trust_trace_headers=True, ) configurator.include(self.baseplate_configurator.includeme) app = configurator.make_wsgi_app() self.test_app = webtest.TestApp(app)
def test_should_sample_utilizes_force_sampling(self): client = make_client("test-service", sample_rate=0) baseplate_observer = TraceBaseplateObserver(client) span_with_forced = Span('test-id', 'test-parent', 'test-span-id', False, 1, "test", self.mock_context) span_without_forced = Span('test-id', 'test-parent', 'test-span-id', False, 0, "test", self.mock_context) self.assertTrue( baseplate_observer.should_sample(span_with_forced) ) self.assertFalse( baseplate_observer.should_sample(span_without_forced) )
def tracing_client_from_config( raw_config: config.RawConfig, log_if_unconfigured: bool = True) -> tracing.TracingClient: """Configure and return a tracing client. This expects one configuration option and can take many optional ones: ``tracing.service_name`` The name for the service this observer is registered to. ``tracing.endpoint`` (optional) (Deprecated in favor of the sidecar model.) Destination to record span data. ``tracing.queue_name`` (optional) Name of POSIX queue where spans are recorded ``tracing.max_span_queue_size`` (optional) Span processing queue limit. ``tracing.num_span_workers`` (optional) Number of worker threads for span processing. ``tracing.span_batch_interval`` (optional) Wait time for span processing in seconds. ``tracing.num_conns`` (optional) Pool size for remote recorder connection pool. ``tracing.sample_rate`` (optional) Percentage of unsampled requests to record traces for (e.g. "37%") :param dict raw_config: The application configuration which should have settings for the tracing client. :param bool log_if_unconfigured: When the client is not configured, should trace spans be logged or discarded silently? :return: A configured client. :rtype: :py:class:`baseplate.diagnostics.tracing.TracingClient` """ cfg = config.parse_config( raw_config, { "tracing": { "service_name": config.String, "endpoint": config.Optional(config.Endpoint), "queue_name": config.Optional(config.String), "max_span_queue_size": config.Optional(config.Integer, default=50000), "num_span_workers": config.Optional(config.Integer, default=5), "span_batch_interval": config.Optional(config.Timespan, default=config.Timespan("500 milliseconds")), "num_conns": config.Optional(config.Integer, default=100), "sample_rate": config.Optional(config.Fallback(config.Percent, config.Float), default=0.1), } }, ) # pylint: disable=maybe-no-member return tracing.make_client( service_name=cfg.tracing.service_name, tracing_endpoint=cfg.tracing.endpoint, tracing_queue_name=cfg.tracing.queue_name, max_span_queue_size=cfg.tracing.max_span_queue_size, num_span_workers=cfg.tracing.num_span_workers, span_batch_interval=cfg.tracing.span_batch_interval.total_seconds(), num_conns=cfg.tracing.num_conns, sample_rate=cfg.tracing.sample_rate, log_if_unconfigured=log_if_unconfigured, )
def test_null_recorder_setup(self): client = make_client("test-service", log_if_unconfigured=False) baseplate_observer = TraceBaseplateObserver(client) self.assertEqual(type(baseplate_observer.recorder), NullRecorder)
def test_logging_recorder_setup(self): client = make_client("test-service") baseplate_observer = TraceBaseplateObserver(client) self.assertEqual(type(baseplate_observer.recorder), LoggingRecorder)
def test_sets_hostname(self): client = make_client("test-service") baseplate_observer = TraceBaseplateObserver(client) self.assertIsNotNone(baseplate_observer.hostname)