def test_header_encoding(self): # The test is for detecting the encoding compatibility issue in # Python2 and Python3 and what flask does for encoding the headers. # This test case is expected to fail at the check_trace_id method # in SpanContext because it cannot match the pattern for trace_id, # And a new trace_id will generate for the context. flask_trace_header = 'traceparent' trace_id = "你好" span_id = '6e0c63257de34c92' flask_trace_id = '00-{}-{}-00'.format(trace_id, span_id) app = self.create_app() flask_middleware.FlaskMiddleware(app=app, sampler=samplers.AlwaysOnSampler()) context = app.test_request_context( path='/', headers={flask_trace_header: flask_trace_id}) with context: app.preprocess_request() tracer = execution_context.get_opencensus_tracer() self.assertIsNotNone(tracer) span = tracer.current_span() expected_attributes = { 'http.url': u'http://localhost/', 'http.method': 'GET', } self.assertEqual(span.attributes, expected_attributes) assert isinstance(span.parent_span, base.NullContextManager) span_context = tracer.span_context self.assertNotEqual(span_context.trace_id, trace_id)
def test__before_request(self): from opencensus.trace import execution_context flask_trace_header = 'traceparent' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' flask_trace_id = '00-{}-{}-00'.format(trace_id, span_id) app = self.create_app() flask_middleware.FlaskMiddleware(app=app, sampler=samplers.AlwaysOnSampler()) context = app.test_request_context( path='/wiki/Rabbit', headers={flask_trace_header: flask_trace_id}) with context: app.preprocess_request() tracer = execution_context.get_opencensus_tracer() self.assertIsNotNone(tracer) span = tracer.current_span() expected_attributes = { 'http.host': u'localhost', 'http.method': u'GET', 'http.path': u'/wiki/Rabbit', 'http.url': u'http://localhost/wiki/Rabbit', } self.assertEqual(span.span_kind, span_module.SpanKind.SERVER) self.assertEqual(span.attributes, expected_attributes) self.assertEqual(span.parent_span.span_id, span_id) span_context = tracer.span_context self.assertEqual(span_context.trace_id, trace_id)
def test__after_request_sampled(self): flask_trace_header = 'traceparent' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' flask_trace_id = '00-{}-{}-00'.format(trace_id, span_id) app = self.create_app() flask_middleware.FlaskMiddleware(app=app, sampler=samplers.AlwaysOnSampler()) context = app.test_request_context( path='/wiki/Rabbit', headers={flask_trace_header: flask_trace_id}) with context: app.preprocess_request() tracer = execution_context.get_opencensus_tracer() self.assertIsNotNone(tracer) span = tracer.current_span() rv = app.dispatch_request() app.finalize_request(rv) expected_attributes = { 'http.host': u'localhost', 'http.method': u'GET', 'http.path': u'/wiki/Rabbit', 'http.url': u'http://localhost/wiki/Rabbit', 'http.route': u'/wiki/<entry>', 'http.status_code': 200 } self.assertEqual(span.attributes, expected_attributes) assert isinstance(span.parent_span, base.NullContextManager)
def test_should_sample(self): from opencensus.trace import samplers sampler = samplers.AlwaysOnSampler() mock_context = mock.Mock() mock_context.trace_id = 'fake_id' should_sample = sampler.should_sample(mock_context) self.assertTrue(should_sample)
def __init__(self, trace_name): sampler = samplers.AlwaysOnSampler() je = JaegerExporter(service_name=trace_name, host_name="localhost", agent_port=6831, endpoint="/api/traces") self.tracer = Tracer(sampler=sampler, exporter=je)
def test_tracer(self): import json from opencensus.trace import file_exporter from opencensus.trace import samplers from opencensus.trace import tracer as tracer_module from opencensus.trace.propagation import google_cloud_format trace_id = 'f8739df974a4481f98748cd92b27177d' span_id = '6e0c63257de34c92' trace_option = 1 trace_header = '{}/{};o={}'.format( trace_id, int(span_id, 16), trace_option) sampler = samplers.AlwaysOnSampler() exporter = file_exporter.FileExporter() propagator = google_cloud_format.GoogleCloudFormatPropagator() span_context = propagator.from_header(header=trace_header) tracer = tracer_module.Tracer( span_context=span_context, sampler=sampler, exporter=exporter, propagator=propagator ) with tracer.span(name='root_span') as root: func_to_trace() parent_span_id = root.span_id with root.span(name='child_span'): func_to_trace() tracer.finish() file = open(file_exporter.DEFAULT_FILENAME, 'r') trace_json = json.loads(file.read()) spans = trace_json.get('spans') self.assertEqual(trace_json.get('traceId'), trace_id) self.assertEqual(len(spans), 2) self.assertSetEqual( {ss['displayName']['value'] for ss in spans}, {'child_span', 'root_span'}) for span in spans: if span['displayName']['value'] == 'root_span': self.assertEqual(span['parentSpanId'], span_id) self.assertEqual(span['childSpanCount'], 1) else: self.assertEqual(span['displayName']['value'], 'child_span') self.assertEqual(span['parentSpanId'], parent_span_id) self.assertEqual(span['childSpanCount'], 0)
def initialize_tracer(request: 'flask.Request') -> tracer.Tracer: if TRACE_PROPAGATE == "google": propagator = google_cloud_format.GoogleCloudFormatPropagator() else: propagator = trace_context_http_header_format.TraceContextPropagator() if TRACE_EXPORTER == "stackdriver": exporter = trace_exporter.StackdriverExporter(transport=AsyncTransport) sampler = samplers.AlwaysOnSampler() elif TRACE_EXPORTER == "log": exporter = logging_exporter.LoggingExporter( handler=py_logging.NullHandler(), transport=AsyncTransport) sampler = samplers.AlwaysOnSampler() elif TRACE_EXPORTER == "stdout": exporter = print_exporter.PrintExporter(transport=AsyncTransport) sampler = samplers.AlwaysOnSampler() else: exporter = print_exporter.PrintExporter(transport=AsyncTransport) sampler = samplers.AlwaysOffSampler() span_context = propagator.from_headers(request.headers) return tracer.Tracer(exporter=exporter, sampler=sampler, propagator=propagator, span_context=span_context)
def serve(): sampler = samplers.AlwaysOnSampler() exporter = stackdriver_exporter.StackdriverExporter() tracer_interceptor = server_interceptor.OpenCensusServerInterceptor( sampler, exporter) server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=(tracer_interceptor, )) hello_world_pb2_grpc.add_GreeterServicer_to_server(HelloWorld(), server) server.add_insecure_port('[::]:50051') server.start() try: while True: time.sleep(_ONE_DAY_IN_SECONDS) except KeyboardInterrupt: server.stop(0)
def test_teardown_include_exception(self): mock_exporter = mock.MagicMock() app = self.create_app() flask_middleware.FlaskMiddleware(app=app, exporter=mock_exporter, sampler=samplers.AlwaysOnSampler()) response = app.test_client().get('/error') self.assertEqual(response.status_code, 500) exported_spandata = mock_exporter.export.call_args[0][0][0] self.assertIsInstance(exported_spandata, span_data.SpanData) self.assertIsInstance(exported_spandata.status, status.Status) self.assertEqual(exported_spandata.status.code, code_pb2.UNKNOWN) self.assertEqual(exported_spandata.status.message, 'error')
def test_trace_decorator(self): mock_exporter = mock.MagicMock() tracer = tracer_module.Tracer(exporter=mock_exporter, sampler=samplers.AlwaysOnSampler()) return_value = "test" @tracer.trace_decorator() def test_decorator(): return return_value returned = test_decorator() self.assertEqual(returned, return_value) self.assertEqual(mock_exporter.export.call_count, 1) exported_spandata = mock_exporter.export.call_args[0][0][0] self.assertIsInstance(exported_spandata, span_data.SpanData) self.assertEqual(exported_spandata.name, 'test_decorator')
def __init__( self, app: ASGIApp, excludelist_paths=None, excludelist_hostnames=None, sampler=None, exporter=None, propagator=None, ) -> None: super().__init__(app) self.app = app self.excludelist_paths = excludelist_paths self.excludelist_hostnames = excludelist_hostnames self.sampler = sampler or samplers.AlwaysOnSampler() self.exporter = exporter or print_exporter.PrintExporter() self.propagator = ( propagator or trace_context_http_header_format.TraceContextPropagator())
def test_teardown_include_exception_and_traceback(self): mock_exporter = mock.MagicMock() app = self.create_app() app.config['TESTING'] = True flask_middleware.FlaskMiddleware(app=app, exporter=mock_exporter, sampler=samplers.AlwaysOnSampler()) with self.assertRaises(FlaskTestException): app.test_client().get('/error') exported_spandata = mock_exporter.export.call_args[0][0][0] self.assertIsInstance(exported_spandata, span_data.SpanData) self.assertIsInstance(exported_spandata.status, status.Status) self.assertEqual(exported_spandata.status.code, code_pb2.UNKNOWN) self.assertEqual(exported_spandata.status.message, 'error') self.assertIsInstance(exported_spandata.stack_trace, stack_trace.StackTrace) self.assertIsNotNone(exported_spandata.stack_trace.stack_trace_hash_id) self.assertNotEqual(exported_spandata.stack_trace.stack_frames, [])
def test_header_is_none(self): app = self.create_app() flask_middleware.FlaskMiddleware(app=app, sampler=samplers.AlwaysOnSampler()) context = app.test_request_context(path='/') with context: app.preprocess_request() tracer = execution_context.get_opencensus_tracer() self.assertIsNotNone(tracer) span = tracer.current_span() expected_attributes = { 'http.url': u'http://localhost/', 'http.method': 'GET', } self.assertEqual(span.attributes, expected_attributes) assert isinstance(span.parent_span, base.NullContextManager)
def test_invoke_method_with_tracer(self): tracer = Tracer(sampler=samplers.AlwaysOnSampler(), exporter=print_exporter.PrintExporter()) self.client = DaprClient(headers_callback=lambda: tracer.propagator. to_headers(tracer.span_context)) self.server.set_response(b"FOO") with tracer.span(name="test"): req = common_v1.StateItem(key='test') resp = self.client.invoke_method( self.app_id, self.method_name, http_verb='PUT', data=req, ) request_headers = self.server.get_request_headers() self.assertIn('Traceparent', request_headers) self.assertEqual(b'FOO', resp.data)
def test__before_request_blacklist(self): flask_trace_header = 'traceparent' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' flask_trace_id = '00-{}-{}-00'.format(trace_id, span_id) app = self.create_app() # Use the AlwaysOnSampler here to prove that the blacklist takes # precedence over the sampler flask_middleware.FlaskMiddleware(app=app, sampler=samplers.AlwaysOnSampler()) context = app.test_request_context( path='/_ah/health', headers={flask_trace_header: flask_trace_id}) with context: app.preprocess_request() tracer = execution_context.get_opencensus_tracer() assert isinstance(tracer, noop_tracer.NoopTracer) span = tracer.current_span() assert isinstance(span, BlankSpan)
def main(): sampler = samplers.AlwaysOnSampler() exporter = print_exporter.PrintExporter() tracer = Tracer(sampler=sampler, exporter=exporter) with tracer.span(name='root'): tracer.add_attribute_to_current_span(attribute_key='example key', attribute_value='example value') function_to_trace() with tracer.span(name='child'): function_to_trace() # Get the current tracer tracer = execution_context.get_opencensus_tracer() # Explicitly create spans tracer.start_span() # Get current span execution_context.get_current_span() # Explicitly end span tracer.end_span()
app.register_blueprint(reporting_endpoint_blueprint, url_prefix="/reporting") app.register_blueprint(export_blueprint, url_prefix="/export") app.register_blueprint(justice_counts_control, url_prefix="/justice_counts") if environment.in_gcp(): SQLAlchemyEngineManager.init_engines_for_server_postgres_instances() # Export traces and metrics to stackdriver if running in GCP if environment.in_gcp(): monitoring.register_stackdriver_exporter() trace_exporter = stackdriver_trace.StackdriverExporter( project_id=metadata.project_id(), transport=AsyncTransport ) trace_sampler = trace.CompositeSampler( { "/direct/process_job": samplers.AlwaysOnSampler(), # There are a lot of scraper requests, so they can use the default rate of 1 in 10k. "/scraper/": samplers.ProbabilitySampler(), "/scrape_aggregate_reports/": samplers.ProbabilitySampler(), }, # For other requests, trace 1 in 20. default_sampler=samplers.ProbabilitySampler(rate=0.05), ) else: trace_exporter = file_exporter.FileExporter(file_name="traces") trace_sampler = samplers.AlwaysOnSampler() middleware = FlaskMiddleware( app, excludelist_paths=["metadata", "computeMetadata"], # Don't trace metadata requests sampler=trace_sampler,
try: if "DISABLE_PROFILER" in os.environ: raise KeyError() else: logger.info("Profiler enabled.") initStackdriverProfiling() except KeyError: logger.info("Profiler disabled.") try: if "DISABLE_TRACING" in os.environ: raise KeyError() else: logger.info("Tracing enabled.") sampler = samplers.AlwaysOnSampler() exporter = stackdriver_exporter.StackdriverExporter( project_id=os.environ.get('GCP_PROJECT_ID'), transport=AsyncTransport) tracer_interceptor = server_interceptor.OpenCensusServerInterceptor( sampler, exporter) except (KeyError, DefaultCredentialsError): logger.info("Tracing disabled.") tracer_interceptor = server_interceptor.OpenCensusServerInterceptor() except Exception as e: logger.warn( f"Exception on Cloud Trace setup: {traceback.format_exc()}, tracing disabled." ) tracer_interceptor = server_interceptor.OpenCensusServerInterceptor() try:
# 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. from opencensus.trace import print_exporter, samplers from opencensus.trace.propagation import trace_context_http_header_format DEFAULT_PYRAMID_TRACER_CONFIG = { 'SAMPLER': samplers.AlwaysOnSampler(), 'EXPORTER': print_exporter.PrintExporter(), 'PROPAGATOR': trace_context_http_header_format.TraceContextPropagator(), # https://cloud.google.com/appengine/docs/flexible/python/ # how-instances-are-managed#health_checking 'BLACKLIST_PATHS': ['_ah/health'], } class PyramidTraceSettings(object): def __init__(self, registry): self.settings = registry.settings.get('OPENCENSUS', {}) self.settings = self.settings.get('TRACE', DEFAULT_PYRAMID_TRACER_CONFIG) _set_default_configs(self.settings, DEFAULT_PYRAMID_TRACER_CONFIG)
app.register_blueprint(calculation_data_storage_manager_blueprint, url_prefix='/calculation_data_storage_manager') app.register_blueprint(reporting_endpoint_blueprint, url_prefix='/reporting') app.register_blueprint(export_blueprint, url_prefix='/export') if environment.in_gae(): SQLAlchemyEngineManager.init_engines_for_server_postgres_instances() # Export traces and metrics to stackdriver if running on GAE if environment.in_gae(): monitoring.register_stackdriver_exporter() trace_exporter = stackdriver_trace.StackdriverExporter( project_id=metadata.project_id(), transport=AsyncTransport) trace_sampler = samplers.ProbabilitySampler(rate=0.05) # Default is 1 in 10k, trace 1 in 20 instead else: trace_exporter = file_exporter.FileExporter(file_name='traces') trace_sampler = samplers.AlwaysOnSampler() middleware = FlaskMiddleware( app, blacklist_paths=['metadata'], # Don't trace metadata requests sampler=trace_sampler, exporter=trace_exporter, propagator=google_cloud_format.GoogleCloudFormatPropagator()) config_integration.trace_integrations([ # TODO(#4283): The 'google_cloud_clientlibs' integration is currently not compatible with the 'proto-plus' objects # used by the 2.0.0 versions of the client libraries. Investigate best way to hydrate spans in traces for these # calls in the future. 'google_cloud_clientlibs', 'requests', 'sqlalchemy' ])