示例#1
0
    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)
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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)
示例#7
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)
示例#8
0
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)
示例#9
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')
示例#10
0
    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')
示例#11
0
 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())
示例#12
0
    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, [])
示例#13
0
    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)
示例#16
0
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()
示例#17
0
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,
示例#18
0
    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:
示例#19
0
# 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)
示例#20
0
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'
])