Esempio n. 1
0
 def _get_resource(
     service_name: Optional[str],
     attributes: Optional[Dict[str, Union[str, bool, int, float]]],
 ) -> Resource:
     attributes = attributes or {}
     if service_name:
         attributes[_SERVICE_NAME_ATTR] = service_name
     attributes.update({
         _TELEMETRY_VERSION_ATTR: auto_instrumentation_version,
         _SPLUNK_DISTRO_VERSION_ATTR: __version__,
     })
     resource = Resource.create(attributes)
     if (resource.attributes.get(
             _SERVICE_NAME_ATTR,
             _DEFAULT_OTEL_SERVICE_NAME) == _DEFAULT_OTEL_SERVICE_NAME):
         logger.warning(_NO_SERVICE_NAME_WARNING)
         resource = resource.merge(
             Resource({_SERVICE_NAME_ATTR: _DEFAULT_SERVICE_NAME}))
     return resource
Esempio n. 2
0
    def _create_app(self):
        # instrumentation is handled by the instrument call
        resource = Resource.create({"key1": "value1", "key2": "value2"})
        result = self.create_tracer_provider(resource=resource)
        tracer_provider, exporter = result
        self.memory_exporter = exporter

        self._instrumentor.instrument(tracer_provider=tracer_provider)

        return self._create_starlette_app()
    def test_basic_wsgi_call(self):
        resource = Resource.create({"service-key": "service-value"})
        result = TestBase.create_tracer_provider(resource=resource)
        tracer_provider, exporter = result

        app = otel_wsgi.OpenTelemetryMiddleware(
            simple_wsgi, tracer_provider=tracer_provider
        )
        response = app(self.environ, self.start_response)
        self.validate_response(response, exporter)
    def test_unique_identifier(self):
        client = mock.Mock()
        exporter1 = CloudMonitoringMetricsExporter(
            project_id=self.project_id,
            client=client,
            add_unique_identifier=True,
        )
        exporter2 = CloudMonitoringMetricsExporter(
            project_id=self.project_id,
            client=client,
            add_unique_identifier=True,
        )
        exporter1.project_name = self.project_name
        exporter2.project_name = self.project_name

        client.create_metric_descriptor.return_value = MetricDescriptor(
            **{
                "name":
                None,
                "type":
                "custom.googleapis.com/OpenTelemetry/name",
                "display_name":
                "name",
                "description":
                "description",
                "labels": [
                    LabelDescriptor(key=UNIQUE_IDENTIFIER_KEY,
                                    value_type="STRING"),
                ],
                "metric_kind":
                "CUMULATIVE",
                "value_type":
                "DOUBLE",
            })

        sum_agg_one = SumAggregator()
        sum_agg_one.update(1)
        metric_record = ExportRecord(MockMetric(), (), sum_agg_one,
                                     Resource.create_empty())
        exporter1.export([metric_record])
        exporter2.export([metric_record])

        (
            first_call,
            second_call,
        ) = client.create_metric_descriptor.call_args_list
        self.assertEqual(first_call[0][1].labels[0].key, UNIQUE_IDENTIFIER_KEY)
        self.assertEqual(second_call[0][1].labels[0].key,
                         UNIQUE_IDENTIFIER_KEY)

        first_call, second_call = client.create_time_series.call_args_list
        self.assertNotEqual(
            first_call[0][1][0].metric.labels[UNIQUE_IDENTIFIER_KEY],
            second_call[0][1][0].metric.labels[UNIQUE_IDENTIFIER_KEY],
        )
Esempio n. 5
0
def configure_tracing(configuration: dict):
    # OTLP Exporter configuration
    if configuration['exporter'] == 'otlp':
        service_name = {'service.name': configuration['service_name']}
        resource = Resource(service_name)
        trace.set_tracer_provider(TracerProvider(resource=resource))
        exporter = OTLPSpanExporter(
            endpoint=configuration['exporter_endpoint'],
            insecure=configuration['exporter_insecure'])
        trace.get_tracer(__name__)
        span_processor = BatchExportSpanProcessor(exporter)
        trace.get_tracer_provider().add_span_processor(span_processor)

    # Jaeger HTTP Exporter configuration
    elif configuration['exporter'] == 'jaeger_http':
        exporter = JaegerSpanExporter(
            service_name=configuration['service_name'],
            collector_endpoint=configuration['exporter_endpoint'],
        )
        trace.set_tracer_provider(TracerProvider())
        trace.get_tracer(__name__)
        span_processor = BatchExportSpanProcessor(exporter)
        trace.get_tracer_provider().add_span_processor(span_processor)

    # Jaeger Thrifth Compact Exporter configuration
    elif configuration['exporter'] == 'jaeger_thrift':
        exporter = JaegerSpanExporter(
            service_name=configuration['service_name'],
            agent_host_name=configuration['exporter_host'],
            agent_port=configuration['exporter_port'],
        )
        trace.set_tracer_provider(TracerProvider())
        trace.get_tracer(__name__)
        span_processor = BatchExportSpanProcessor(exporter)
        trace.get_tracer_provider().add_span_processor(span_processor)

    # Zipkin Exporter configuration
    elif configuration['exporter'] == 'zipkin':
        exporter = ZipkinSpanExporter(
            service_name=configuration['service_name'],
            url=configuration['exporter_endpoint'])
        trace.set_tracer_provider(TracerProvider())
        trace.get_tracer(__name__)
        span_processor = BatchExportSpanProcessor(exporter)
        trace.get_tracer_provider().add_span_processor(span_processor)

    # Console Exporter configuration
    elif configuration['exporter'] == 'console':
        trace.set_tracer_provider(TracerProvider())
        trace.get_tracer_provider().add_span_processor(
            SimpleExportSpanProcessor(ConsoleSpanExporter()))
    else:
        raise ValueError(
            'Only Otlp, Jaeger Thrift/HTTP and Zipkin exporters are supported. '
            'Please check your configuration.')
 def test_extract_unsupported_gcp_resources(self):
     resource = Resource(
         labels={
             "cloud.account.id": "123",
             "host.id": "host",
             "extra_info": "extra",
             "not_gcp_resource": "value",
             "gcp.resource_type": "unsupported_gcp_resource",
             "cloud.provider": "gcp",
         })
     self.assertEqual(_extract_resources(resource), {})
Esempio n. 7
0
def post_fork(server, worker):
    server.log.info("Worker spawned (pid: %s)", worker.pid)

    resource = Resource.create(attributes={"service.name": "api-service"})

    trace.set_tracer_provider(TracerProvider(resource=resource))
    # This uses insecure connection for the purpose of example. Please see the
    # OTLP Exporter documentation for other options.
    span_processor = BatchSpanProcessor(
        OTLPSpanExporter(endpoint="localhost:4317", insecure=True))
    trace.get_tracer_provider().add_span_processor(span_processor)
 def test_extract_malformed_resources(self):
     # This resource doesn't have all the fields required for a gce_instance
     # Specifically its missing "host.id", "cloud.zone", "cloud.account.id"
     resource = Resource(
         labels={
             "gcp.resource_type": "gce_instance",
             "cloud.provider": "gcp",
         }
     )
     # Should throw when passed a malformed GCP resource dict
     self.assertRaises(KeyError, _extract_resources, resource)
Esempio n. 9
0
    def __init__(
        self,
        name: str,
        context: trace_api.SpanContext,
        parent: Optional[trace_api.SpanContext] = None,
        sampler: Optional[sampling.Sampler] = None,
        trace_config: None = None,  # TODO
        resource: Resource = Resource.create({}),
        attributes: types.Attributes = None,
        events: Sequence[Event] = None,
        links: Sequence[trace_api.Link] = (),
        kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL,
        span_processor: SpanProcessor = SpanProcessor(),
        instrumentation_info: InstrumentationInfo = None,
        record_exception: bool = True,
        set_status_on_exception: bool = True,
    ) -> None:
        super().__init__(
            name=name,
            context=context,
            parent=parent,
            kind=kind,
            resource=resource,
            instrumentation_info=instrumentation_info,
        )
        self._sampler = sampler
        self._trace_config = trace_config
        self._record_exception = record_exception
        self._set_status_on_exception = set_status_on_exception
        self._span_processor = span_processor
        self._lock = threading.Lock()

        _filter_attribute_values(attributes)
        if not attributes:
            self._attributes = self._new_attributes()
        else:
            self._attributes = BoundedDict.from_map(
                SPAN_ATTRIBUTE_COUNT_LIMIT, attributes
            )

        self._events = self._new_events()
        if events:
            for event in events:
                _filter_attribute_values(event.attributes)
                # pylint: disable=protected-access
                event._attributes = _create_immutable_attributes(
                    event.attributes
                )
                self._events.append(event)

        if links is None:
            self._links = self._new_links()
        else:
            self._links = BoundedList.from_seq(SPAN_LINK_COUNT_LIMIT, links)
    def __init__(
        self,
        name: str,
        context: trace_api.SpanContext,
        parent: Optional[trace_api.SpanContext] = None,
        sampler: Optional[sampling.Sampler] = None,
        trace_config: None = None,  # TODO
        resource: Resource = Resource.create({}),
        attributes: types.Attributes = None,  # TODO
        events: Sequence[Event] = None,  # TODO
        links: Sequence[trace_api.Link] = (),
        kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL,
        span_processor: SpanProcessor = SpanProcessor(),
        instrumentation_info: InstrumentationInfo = None,
        set_status_on_exception: bool = True,
    ) -> None:

        self.name = name
        self.context = context
        self.parent = parent
        self.sampler = sampler
        self.trace_config = trace_config
        self.resource = resource
        self.kind = kind
        self._set_status_on_exception = set_status_on_exception

        self.span_processor = span_processor
        self.status = None
        self._lock = threading.Lock()

        _filter_attribute_values(attributes)
        if not attributes:
            self.attributes = self._new_attributes()
        else:
            self.attributes = BoundedDict.from_map(MAX_NUM_ATTRIBUTES,
                                                   attributes)

        self.events = self._new_events()
        if events:
            for event in events:
                _filter_attribute_values(event.attributes)
                # pylint: disable=protected-access
                event._attributes = _create_immutable_attributes(
                    event.attributes)
                self.events.append(event)

        if links is None:
            self.links = self._new_links()
        else:
            self.links = BoundedList.from_seq(MAX_NUM_LINKS, links)

        self._end_time = None  # type: Optional[int]
        self._start_time = None  # type: Optional[int]
        self.instrumentation_info = instrumentation_info
 def test_extract_unsupported_provider_resources(self):
     # Resources with currently unsupported providers will be ignored
     resource = Resource(
         attributes={
             "cloud.account.id": "123",
             "host.id": "host",
             "extra_info": "extra",
             "not_gcp_resource": "value",
             "cloud.provider": "aws",
         })
     self.assertEqual(_extract_resources(resource), {})
Esempio n. 12
0
 def detect(self) -> "Resource":
     lambda_name = environ.get("AWS_LAMBDA_FUNCTION_NAME")
     aws_region = environ.get("AWS_REGION")
     function_version = environ.get("AWS_LAMBDA_FUNCTION_VERSION")
     env_resource_map = {
         "cloud.region": aws_region,
         "cloud.provider": "aws",
         "faas.name": lambda_name,
         "faas.version": function_version
     }
     return Resource(env_resource_map)
    def test_elasticache_client(self):
        elasticache = boto.elasticache.connect_to_region("us-west-2")

        elasticache.describe_cache_clusters()

        spans = self.memory_exporter.get_finished_spans()
        assert spans
        span = spans[0]
        self.assertEqual(span.resource,
                         Resource(attributes={"endpoint": "elasticcache"}))
        self.assertEqual(span.attributes["aws.region"], "us-west-2")
Esempio n. 14
0
 def test_valid_convert_to_timeseries(self):
     test_records = [
         ExportRecord(
             Counter("testname", "testdesc", "testunit", int, None),
             None,
             SumAggregator(),
             Resource({}),
         ),
         ExportRecord(
             Counter("testname", "testdesc", "testunit", int, None),
             None,
             MinMaxSumCountAggregator(),
             Resource({}),
         ),
         ExportRecord(
             Counter("testname", "testdesc", "testunit", int, None),
             None,
             HistogramAggregator(),
             Resource({}),
         ),
         ExportRecord(
             Counter("testname", "testdesc", "testunit", int, None),
             None,
             LastValueAggregator(),
             Resource({}),
         ),
         ExportRecord(
             Counter("testname", "testdesc", "testunit", int, None),
             None,
             ValueObserverAggregator(),
             Resource({}),
         ),
     ]
     for record in test_records:
         record.aggregator.update(5)
         record.aggregator.take_checkpoint()
     data = self.exporter._convert_to_timeseries(test_records)
     self.assertIsInstance(data, list)
     self.assertEqual(len(data), 13)
     for timeseries in data:
         self.assertIsInstance(timeseries, TimeSeries)
Esempio n. 15
0
 def __init__(
     self,
     instrumentation_info: "InstrumentationInfo",
     stateful: bool,
     resource: Resource = Resource.create_empty(),
 ):
     self.instrumentation_info = instrumentation_info
     self.metrics = set()
     self.observers = set()
     self.batcher = UngroupedBatcher(stateful)
     self.observers_lock = threading.Lock()
     self.resource = resource
Esempio n. 16
0
 def test_export_span_service_name(self):
     resource = Resource.create({SERVICE_NAME: "test"})
     span = trace._Span("test_span",
                        context=self.context,
                        resource=resource)
     span.start()
     span.end()
     client_mock = mock.Mock()
     exporter = JaegerExporter()
     exporter._grpc_client = client_mock
     exporter.export([span])
     self.assertEqual(exporter.service_name, "test")
Esempio n. 17
0
    def test_max_tag_value_length(self):
        span = trace._Span(
            name="span",
            resource=Resource(attributes={
                "key_resource":
                "some_resource some_resource some_more_resource"
            }),
            context=trace_api.SpanContext(
                trace_id=0x000000000000000000000000DEADBEEF,
                span_id=0x00000000DEADBEF0,
                is_remote=False,
            ),
        )

        span.start()
        span.set_attribute("key_bool", False)
        span.set_attribute("key_string", "hello_world hello_world hello_world")
        span.set_attribute("key_float", 111.22)
        span.set_attribute("key_int", 1100)
        span.set_attribute("key_tuple", ("tuple_element", "tuple_element2"))
        span.end()

        translate = Translate([span])

        # does not truncate by default
        # pylint: disable=protected-access
        spans = translate._translate(pb_translator.ProtobufTranslator("svc"))
        tags_by_keys = {
            tag.key: tag.v_str
            for tag in spans[0].tags
            if tag.v_type == model_pb2.ValueType.STRING
        }
        self.assertEqual("hello_world hello_world hello_world",
                         tags_by_keys["key_string"])
        self.assertEqual("('tuple_element', 'tuple_element2')",
                         tags_by_keys["key_tuple"])
        self.assertEqual(
            "some_resource some_resource some_more_resource",
            tags_by_keys["key_resource"],
        )

        # truncates when max_tag_value_length is passed
        # pylint: disable=protected-access
        spans = translate._translate(
            pb_translator.ProtobufTranslator("svc", max_tag_value_length=5))
        tags_by_keys = {
            tag.key: tag.v_str
            for tag in spans[0].tags
            if tag.v_type == model_pb2.ValueType.STRING
        }
        self.assertEqual("hello", tags_by_keys["key_string"])
        self.assertEqual("('tup", tags_by_keys["key_tuple"])
        self.assertEqual("some_", tags_by_keys["key_resource"])
 def setUpClass(cls):
     # pylint: disable=protected-access
     cls._resource_labels = {
         "key_with_str_value": "some string",
         "key_with_int_val": 321,
         "key_with_true": True,
     }
     metrics.set_meter_provider(
         MeterProvider(resource=Resource(cls._resource_labels)))
     cls._meter = metrics.get_meter(__name__)
     cls._labels = {"environment": "staging", "number": 321}
     cls._key_labels = get_dict_as_key(cls._labels)
Esempio n. 19
0
 def detect(self) -> "Resource":
     lambda_handler = os.environ.get("ORIG_HANDLER",
                                     os.environ.get("_HANDLER"))
     aws_region = os.environ["AWS_REGION"]
     env_resource_map = {
         "cloud.region": aws_region,
         "cloud.provider": "aws",
         "faas.name": lambda_handler,
         # faas.id is in lambda context, can to be extracted before lambda handler.
         # 'faas.id': self._ctx_invoked_function_arn,
     }
     return Resource(env_resource_map)
    def test_valid_export(self, mock_post):
        mock_post.return_value.configure_mock(**{"status_code": 200})
        test_metric = Counter("testname", "testdesc", "testunit", int, None)
        labels = get_dict_as_key({"environment": "testing"})
        record = ExportRecord(test_metric, labels, SumAggregator(),
                              Resource({}))
        result = self.exporter.export([record])
        self.assertIs(result, MetricsExportResult.SUCCESS)
        self.assertEqual(mock_post.call_count, 1)

        result = self.exporter.export([])
        self.assertIs(result, MetricsExportResult.SUCCESS)
Esempio n. 21
0
 def test_log_to_envelope_partA_default(self):
     exporter = self._exporter
     old_resource = self._log_data.log_record.resource
     resource = Resource({"service.name": "testServiceName"})
     self._log_data.log_record.resource = resource
     envelope = exporter._log_to_envelope(self._log_data)
     self.assertEqual(envelope.tags.get("ai.cloud.role"), "testServiceName")
     self.assertEqual(envelope.tags.get("ai.cloud.roleInstance"),
                      platform.node())
     self.assertEqual(envelope.tags.get("ai.internal.nodeName"),
                      envelope.tags.get("ai.cloud.roleInstance"))
     self._log_data.log_record.resource = old_resource
Esempio n. 22
0
def post_fork(server, worker):
    server.log.info("Worker spawned (pid: %s)", worker.pid)

    resource = Resource.create(attributes={"service.name": "job-server"})

    trace.set_tracer_provider(TracerProvider(resource=resource))
    span_processor = BatchSpanProcessor(
        OTLPSpanExporter(endpoint="https://api.honeycomb.io"))
    trace.get_tracer_provider().add_span_processor(span_processor)

    from opentelemetry.instrumentation.auto_instrumentation import (  # noqa: F401
        sitecustomize, )
    def setUp(self):
        super().setUp()
        resource = Resource.create({"service.name": "flask-api"})
        result = self.create_tracer_provider(resource=resource)
        tracer_provider, exporter = result
        self.memory_exporter = exporter

        self.app = Flask(__name__)

        FlaskInstrumentor().instrument_app(self.app,
                                           tracer_provider=tracer_provider)
        self._common_initialization()
 def test_extract_unsupported_gcp_resources(self):
     # Unsupported gcp resources will be ignored
     resource = Resource(
         attributes={
             "cloud.account.id": "123",
             "host.id": "host",
             "extra_info": "extra",
             "not_gcp_resource": "value",
             "gcp.resource_type": "unsupported_gcp_resource",
             "cloud.provider": "gcp",
         })
     self.assertEqual(_extract_resources(resource), {})
Esempio n. 25
0
 def __init__(
     self,
     sampler: sampling.Sampler = trace_api.sampling.ALWAYS_ON,
     resource: Resource = Resource.create_empty(),
     shutdown_on_exit: bool = True,
 ):
     self._active_span_processor = MultiSpanProcessor()
     self.resource = resource
     self.sampler = sampler
     self._atexit_handler = None
     if shutdown_on_exit:
         self._atexit_handler = atexit.register(self.shutdown)
Esempio n. 26
0
    def detect(self) -> "Resource":
        try:
            if not os.environ.get(
                "ECS_CONTAINER_METADATA_URI"
            ) and not os.environ.get("ECS_CONTAINER_METADATA_URI_V4"):
                raise RuntimeError(
                    "Missing ECS_CONTAINER_METADATA_URI therefore process is not on ECS."
                )

            container_id = ""
            try:
                with open(
                    "/proc/self/cgroup", encoding="utf8"
                ) as container_info_file:
                    for raw_line in container_info_file.readlines():
                        line = raw_line.strip()
                        # Subsequent IDs should be the same, exit if found one
                        if len(line) > _CONTAINER_ID_LENGTH:
                            container_id = line[-_CONTAINER_ID_LENGTH:]
                            break
            except FileNotFoundError as exception:
                logger.warning(
                    "Failed to get container ID on ECS: %s.", exception
                )

            return Resource(
                {
                    ResourceAttributes.CLOUD_PROVIDER: CloudProviderValues.AWS.value,
                    ResourceAttributes.CLOUD_PLATFORM: CloudPlatformValues.AWS_ECS.value,
                    ResourceAttributes.CONTAINER_NAME: socket.gethostname(),
                    ResourceAttributes.CONTAINER_ID: container_id,
                }
            )
        # pylint: disable=broad-except
        except Exception as exception:
            if self.raise_on_error:
                raise exception

            logger.warning("%s failed: %s", self.__class__.__name__, exception)
            return Resource.get_empty()
    def test_s3_put(self):
        s3 = boto.s3.connect_to_region("us-east-1")
        s3.create_bucket("mybucket")
        bucket = s3.get_bucket("mybucket")
        key = boto.s3.key.Key(bucket)
        key.key = "foo"
        key.set_contents_from_string("bar")

        spans = self.memory_exporter.get_finished_spans()
        assert spans
        # create bucket
        self.assertEqual(len(spans), 3)
        self.assertEqual(spans[0].attributes["aws.operation"], "create_bucket")
        assert_span_http_status_code(spans[0], 200)
        self.assertEqual(
            spans[0].resource,
            Resource(attributes={
                "endpoint": "s3",
                "http_method": "put"
            }),
        )
        # get bucket
        self.assertEqual(spans[1].attributes["aws.operation"], "head_bucket")
        self.assertEqual(
            spans[1].resource,
            Resource(attributes={
                "endpoint": "s3",
                "http_method": "head"
            }),
        )
        # put object
        self.assertEqual(spans[2].attributes["aws.operation"],
                         "_send_file_internal")
        self.assertEqual(
            spans[2].resource,
            Resource(attributes={
                "endpoint": "s3",
                "http_method": "put"
            }),
        )
Esempio n. 28
0
 def __init__(
     self,
     stateful=True,
     resource: Resource = Resource.create({}),
     shutdown_on_exit: bool = True,
 ):
     self.stateful = stateful
     self.resource = resource
     self._controllers = []
     self._exporters = set()
     self._atexit_handler = None
     if shutdown_on_exit:
         self._atexit_handler = atexit.register(self.shutdown)
def init_otel():
    global tracer, session_name, service_name, insecure
    LOGGER.debug('Init Otel : {}'.format(service_name))
    trace.set_tracer_provider(
        TracerProvider(resource=Resource.create({SERVICE_NAME:
                                                 service_name}), ))

    otel_exporter = OTLPSpanExporter(insecure=insecure)

    trace.get_tracer_provider().add_span_processor(
        BatchSpanProcessor(otel_exporter))

    tracer = trace.get_tracer(session_name)
Esempio n. 30
0
 def __init__(
     self,
     resource: Resource = Resource.create(),
     shutdown_on_exit: bool = True,
     multi_log_processor: Union[SynchronousMultiLogProcessor,
                                ConcurrentMultiLogProcessor] = None,
 ):
     self._resource = resource
     self._multi_log_processor = (multi_log_processor
                                  or SynchronousMultiLogProcessor())
     self._at_exit_handler = None
     if shutdown_on_exit:
         self._at_exit_handler = atexit.register(self.shutdown)