def test_constructor_by_environment_variables(self): """Test using Environment Variables.""" # pylint: disable=protected-access Configuration._reset() service = "my-opentelemetry-jaeger" collector_endpoint = "localhost:14250" env_patch = patch.dict( "os.environ", { "OTEL_EXPORTER_JAEGER_ENDPOINT": collector_endpoint, "OTEL_EXPORTER_JAEGER_CERTIFICATE": os.path.dirname(__file__) + "/certs/cred.cert", }, ) env_patch.start() exporter = JaegerSpanExporter( service_name=service, transport_format="protobuf" ) self.assertEqual(exporter.service_name, service) self.assertIsNotNone(exporter._collector_grpc_client) self.assertEqual(exporter.collector_endpoint, collector_endpoint) self.assertIsNotNone(exporter.credentials) env_patch.stop()
def test_non_default_propagators(self, mock_iter_entry_points, mock_compositehttppropagator): Configuration._reset() def iter_entry_points_mock(_, propagator): return iter([ Mock(**{ "load.side_effect": [Mock(**{"side_effect": [propagator]})] }) ]) mock_iter_entry_points.configure_mock( **{"side_effect": iter_entry_points_mock}) def test_propagators(propagators): self.assertEqual(propagators, ["a", "b", "c"]) mock_compositehttppropagator.configure_mock( **{"side_effect": test_propagators}) import opentelemetry.propagators reload(opentelemetry.propagators)
def test_getattr(self) -> None: # literal access self.assertIsNone(Configuration().XYZ) # dynamic access self.assertIsNone(getattr(Configuration(), "XYZ")) self.assertIsNone(Configuration().get("XYZ", None))
def _get_insecure(param): if param is not None: return param insecure_env = Configuration().get("EXPORTER_JAEGER_INSECURE", None) if insecure_env is not None: return insecure_env.lower() == "true" return DEFAULT_INSECURE
def test_traced_request_attrs(self) -> None: cfg = Configuration() request_attrs = cfg._traced_request_attrs("webframework") self.assertEqual(len(request_attrs), 2) self.assertIn("content_type", request_attrs) self.assertIn("keep_alive", request_attrs) self.assertNotIn("authorization", request_attrs)
def setUp(self): super().setUp() setup_test_environment() _django_instrumentor.instrument() Configuration._reset() # pylint: disable=protected-access self.env_patch = patch.dict( "os.environ", { "OTEL_PYTHON_DJANGO_EXCLUDED_URLS": "http://testserver/excluded_arg/123,excluded_noarg", "OTEL_PYTHON_DJANGO_TRACED_REQUEST_ATTRS": "path_info,content_type,non_existing_variable", }, ) self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.django.middleware._DjangoMiddleware._excluded_urls", Configuration()._excluded_urls("django"), ) self.traced_patch = patch( "opentelemetry.instrumentation.django.middleware._DjangoMiddleware._traced_request_attrs", Configuration()._traced_request_attrs("django"), ) self.exclude_patch.start() self.traced_patch.start()
def test_integer(self) -> None: # pylint: disable=no-member self.assertIsInstance(Configuration().POSITIVE_INTEGER, int) self.assertEqual(Configuration().POSITIVE_INTEGER, 123) self.assertIsInstance(Configuration().NEGATIVE_INTEGER, int) self.assertEqual(Configuration().NEGATIVE_INTEGER, -123) self.assertEqual(Configuration().NON_INTEGER, "-12z3")
def setUp(self): # pylint: disable=arguments-differ self.exporter = OTLPMetricsExporter(insecure=True) self.resource = SDKResource(OrderedDict([("a", 1), ("b", False)])) self.meter = MeterProvider(resource=self.resource,).get_meter( "name", "version" ) Configuration._reset() # pylint: disable=protected-access
def setUp(self): super().setUp() FalconInstrumentor().instrument() self.app = make_app() # pylint: disable=protected-access Configuration()._reset() self.env_patch = patch.dict( "os.environ", { "OTEL_PYTHON_FALCON_EXCLUDED_URLS": "ping", "OTEL_PYTHON_FALCON_TRACED_REQUEST_ATTRS": "query_string", }, ) self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.falcon._excluded_urls", Configuration()._excluded_urls("falcon"), ) middleware = self.app._middleware[0][ # pylint:disable=W0212 0 ].__self__ self.traced_patch = patch.object( middleware, "_traced_request_attrs", Configuration()._traced_request_attrs("falcon"), ) self.exclude_patch.start() self.traced_patch.start()
def __init__( self, service_name: str, url: str = None, ipv4: Optional[str] = None, ipv6: Optional[str] = None, retry: Optional[str] = DEFAULT_RETRY, max_tag_value_length: Optional[int] = DEFAULT_MAX_TAG_VALUE_LENGTH, transport_format: Union[TRANSPORT_FORMAT_JSON, TRANSPORT_FORMAT_PROTOBUF, None] = None, ): self.service_name = service_name if url is None: self.url = Configuration().EXPORTER_ZIPKIN_ENDPOINT or DEFAULT_URL else: self.url = url self.port = urlparse(self.url).port self.ipv4 = ipv4 self.ipv6 = ipv6 self.retry = retry self.max_tag_value_length = max_tag_value_length if transport_format is None: self.transport_format = ( Configuration().EXPORTER_ZIPKIN_TRANSPORT_FORMAT or TRANSPORT_FORMAT_JSON) else: self.transport_format = transport_format
def test_environment_variables(self): # type: ignore self.assertEqual( Configuration().meter_provider, "meter_provider" ) # pylint: disable=no-member self.assertEqual( Configuration().tracer_provider, "tracer_provider" ) # pylint: disable=no-member
def test_excluded_urls(self) -> None: cfg = Configuration() excluded_urls = cfg._excluded_urls("webframework") self.assertTrue(excluded_urls.url_disabled("/healthzz")) self.assertTrue(excluded_urls.url_disabled("/path")) self.assertTrue(excluded_urls.url_disabled("/issues/123/view")) self.assertFalse(excluded_urls.url_disabled("/issues")) self.assertFalse(excluded_urls.url_disabled("/hello"))
def test_environment_variables( # type: ignore self, mock_iter_entry_points # pylint: disable=unused-argument ): # type: ignore self.assertEqual(Configuration().tracer_provider, "default_tracer_provider") # pylint: disable=no-member self.assertEqual(Configuration().meter_provider, "overridden_meter_provider") # pylint: disable=no-member
def test_boolean(self) -> None: self.assertIsInstance( Configuration().TRUE, bool ) # pylint: disable=no-member self.assertIsInstance( Configuration().FALSE, bool ) # pylint: disable=no-member self.assertTrue(Configuration().TRUE) # pylint: disable=no-member self.assertFalse(Configuration().FALSE) # pylint: disable=no-member
def __init__( self, span_exporter: SpanExporter, max_queue_size: int = None, schedule_delay_millis: float = None, max_export_batch_size: int = None, export_timeout_millis: float = None, ): if max_queue_size is None: max_queue_size = Configuration().get("BSP_MAX_QUEUE_SIZE", 2048) if schedule_delay_millis is None: schedule_delay_millis = Configuration().get( "BSP_SCHEDULE_DELAY_MILLIS", 5000) if max_export_batch_size is None: max_export_batch_size = Configuration().get( "BSP_MAX_EXPORT_BATCH_SIZE", 512) if export_timeout_millis is None: export_timeout_millis = Configuration().get( "BSP_EXPORT_TIMEOUT_MILLIS", 30000) if max_queue_size <= 0: raise ValueError("max_queue_size must be a positive integer.") if schedule_delay_millis <= 0: raise ValueError("schedule_delay_millis must be positive.") if max_export_batch_size <= 0: raise ValueError( "max_export_batch_size must be a positive integer.") if max_export_batch_size > max_queue_size: raise ValueError( "max_export_batch_size must be less than or equal to max_queue_size." ) self.span_exporter = span_exporter self.queue = collections.deque( [], max_queue_size) # type: typing.Deque[Span] self.worker_thread = threading.Thread(target=self.worker, daemon=True) self.condition = threading.Condition(threading.Lock()) self._flush_request = None # type: typing.Optional[_FlushRequest] self.schedule_delay_millis = schedule_delay_millis self.max_export_batch_size = max_export_batch_size self.max_queue_size = max_queue_size self.export_timeout_millis = export_timeout_millis self.done = False # flag that indicates that spans are being dropped self._spans_dropped = False # precallocated list to send spans to exporter self.spans_list = [ None ] * self.max_export_batch_size # type: typing.List[typing.Optional[Span]] self.worker_thread.start()
def test_trace_init_custom_ids_generator(self, mock_iter_entry_points): mock_iter_entry_points.configure_mock(return_value=[ IterEntryPoint("custom_ids_generator", CustomIdsGenerator) ]) Configuration._reset() ids_generator_name = _get_ids_generator() ids_generator = _import_ids_generator(ids_generator_name) _init_tracing({}, ids_generator) provider = self.set_provider_mock.call_args[0][0] self.assertIsInstance(provider.ids_generator, CustomIdsGenerator)
def test_float(self) -> None: self.assertEqual( Configuration().POSITIVE_FLOAT, 123.123 ) # pylint: disable=no-member self.assertEqual( Configuration().NEGATIVE_FLOAT, -123.123 ) # pylint: disable=no-member self.assertEqual( Configuration().NON_FLOAT, "-12z3.123" ) # pylint: disable=no-member
def test_integer(self): self.assertEqual( Configuration().POSITIVE_INTEGER, 123 ) # pylint: disable=no-member self.assertEqual( Configuration().NEGATIVE_INTEGER, -123 ) # pylint: disable=no-member self.assertEqual( Configuration().NON_INTEGER, "-12z3" ) # pylint: disable=no-member
def setUp(self): tracer_provider = TracerProvider() self.exporter = OTLPSpanExporter(insecure=True) tracer_provider.add_span_processor( SimpleExportSpanProcessor(self.exporter) ) self.tracer = tracer_provider.get_tracer(__name__) self.server = server(ThreadPoolExecutor(max_workers=10)) self.server.add_insecure_port("[::]:55680") self.server.start() event_mock = Mock( **{ "timestamp": 1591240820506462784, "attributes": OrderedDict([("a", 1), ("b", False)]), } ) type(event_mock).name = PropertyMock(return_value="a") self.span = _Span( "a", context=Mock( **{ "trace_state": OrderedDict([("a", "b"), ("c", "d")]), "span_id": 10217189687419569865, "trace_id": 67545097771067222548457157018666467027, } ), resource=SDKResource(OrderedDict([("a", 1), ("b", False)])), parent=Mock(**{"span_id": 12345}), attributes=OrderedDict([("a", 1), ("b", True)]), events=[event_mock], links=[ Mock( **{ "context.trace_id": 1, "context.span_id": 2, "attributes": OrderedDict([("a", 1), ("b", False)]), "kind": OTLPSpan.SpanKind.SPAN_KIND_INTERNAL, # pylint: disable=no-member } ) ], instrumentation_info=InstrumentationInfo( name="name", version="version" ), ) self.span.start() self.span.end() Configuration._reset() # pylint: disable=protected-access
def test_trace_init_default(self): environ["OTEL_SERVICE_NAME"] = "my-test-service" Configuration._reset() _init_tracing({"zipkin": Exporter}, RandomIdsGenerator) self.assertEqual(self.set_provider_mock.call_count, 1) provider = self.set_provider_mock.call_args[0][0] self.assertIsInstance(provider, Provider) self.assertIsInstance(provider.ids_generator, RandomIdsGenerator) self.assertIsInstance(provider.processor, Processor) self.assertIsInstance(provider.processor.exporter, Exporter) self.assertEqual(provider.processor.exporter.service_name, "my-test-service")
def setUp(self): # create and save span to be used in tests context = trace_api.SpanContext( trace_id=0x000000000000000000000000DEADBEEF, span_id=0x00000000DEADBEF0, is_remote=False, ) self._test_span = trace._Span("test_span", context=context) self._test_span.start() self._test_span.end() # pylint: disable=protected-access Configuration._reset()
def _get_exporter_names() -> Sequence[str]: exporter = Configuration().EXPORTER or EXPORTER_OTLP if exporter.lower().strip() == "none": return [] names = [] for exp in exporter.split(","): name = exp.strip() if name == EXPORTER_OTLP: names.append(EXPORTER_OTLP_SPAN) names.append(EXPORTER_OTLP_METRIC) else: names.append(name) return names
def test_environment_variables(self) -> None: self.assertEqual( Configuration().METER_PROVIDER, "meter_provider" ) # pylint: disable=no-member self.assertEqual( Configuration().TRACER_PROVIDER, "tracer_provider" ) # pylint: disable=no-member self.assertEqual( Configuration().OThER, "other" ) # pylint: disable=no-member self.assertEqual( Configuration().OTHER_7, "other_7" ) # pylint: disable=no-member self.assertIsNone(Configuration().TRACEX_PROVIDER)
def test_reset(self) -> None: environ_patcher = patch.dict( "os.environ", {"OPENTELEMETRY_PYTHON_TRACER_PROVIDER": "tracer_provider"}, ) environ_patcher.start() self.assertEqual(Configuration().TRACER_PROVIDER, "tracer_provider") # pylint: disable=no-member environ_patcher.stop() Configuration._reset() self.assertIsNone(Configuration().TRACER_PROVIDER) # pylint: disable=no-member
def test_constructor_by_environment_variables(self): """Test the constructor using Environment Variables.""" service = "my-opentelemetry-jaeger" agent_host_name = "opentelemetry.io" agent_port = "6831" collector_endpoint = "https://opentelemetry.io:15875" username = "******" password = "******" auth = (username, password) environ_patcher = mock.patch.dict( "os.environ", { "OTEL_EXPORTER_JAEGER_AGENT_HOST": agent_host_name, "OTEL_EXPORTER_JAEGER_AGENT_PORT": agent_port, "OTEL_EXPORTER_JAEGER_ENDPOINT": collector_endpoint, "OTEL_EXPORTER_JAEGER_USER": username, "OTEL_EXPORTER_JAEGER_PASSWORD": password, }, ) environ_patcher.start() exporter = jaeger_exporter.JaegerSpanExporter(service_name=service) self.assertEqual(exporter.service_name, service) self.assertEqual(exporter.agent_host_name, agent_host_name) self.assertEqual(exporter.agent_port, int(agent_port)) self.assertTrue(exporter.collector is not None) self.assertEqual(exporter.collector_endpoint, collector_endpoint) self.assertEqual(exporter.collector.auth, auth) # property should not construct new object collector = exporter.collector self.assertEqual(exporter.collector, collector) # property should construct new object # pylint: disable=protected-access exporter._collector = None exporter.username = None exporter.password = None self.assertNotEqual(exporter.collector, collector) self.assertTrue(exporter.collector.auth is None) environ_patcher.stop() Configuration._reset()
def setUp(self): super().setUp() Configuration()._reset() self.env_patch = patch.dict( "os.environ", {"OTEL_PYTHON_FASTAPI_EXCLUDED_URLS": "/exclude/123,healthzz"}, ) self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.fastapi._excluded_urls", Configuration()._excluded_urls("fastapi"), ) self.exclude_patch.start() self._instrumentor = otel_fastapi.FastAPIInstrumentor() self._app = self._create_app() self._client = TestClient(self._app)
def _get_credentials(param): if param is not None: return param creds_env = Configuration().get("EXPORTER_JAEGER_CERTIFICATE", None) if creds_env: return _load_credential_from_file(creds_env) return ssl_channel_credentials()
def _instrument(self, **kwargs): # FIXME this is probably a pattern that will show up in the rest of the # ext. Find a better way of implementing this. # FIXME Probably the evaluation of strings into boolean values can be # built inside the Configuration class itself with the magic method # __bool__ if Configuration().DJANGO_INSTRUMENT is False: return # This can not be solved, but is an inherent problem of this approach: # the order of middleware entries matters, and here you have no control # on that: # https://docs.djangoproject.com/en/3.0/topics/http/middleware/#activating-middleware # https://docs.djangoproject.com/en/3.0/ref/middleware/#middleware-ordering settings_middleware = getattr(settings, "MIDDLEWARE", []) # Django allows to specify middlewares as a tuple, so we convert this tuple to a # list, otherwise we wouldn't be able to call append/remove if isinstance(settings_middleware, tuple): settings_middleware = list(settings_middleware) settings_middleware.insert(0, self._opentelemetry_middleware) self.init_metrics( __name__, __version__, ) metric_recorder = HTTPMetricRecorder(self.meter, HTTPMetricType.SERVER) setattr(settings, "OTEL_METRIC_RECORDER", metric_recorder) setattr(settings, "MIDDLEWARE", settings_middleware)
def setUp(self): super().setUp() Configuration()._reset() self.env_patch = patch.dict( "os.environ", {"OTEL_PYTHON_STARLETTE_EXCLUDED_URLS": "/exclude/123,healthzz"}, ) self.env_patch.start() self.exclude_patch = patch( "opentelemetry.instrumentation.starlette._excluded_urls", Configuration()._excluded_urls("starlette"), ) self.exclude_patch.start() self._instrumentor = otel_starlette.StarletteInstrumentor() self._app = self._create_app() self._client = TestClient(self._app)
def __init__( self, service_name: str, agent_host_name: Optional[str] = None, agent_port: Optional[int] = None, collector_endpoint: Optional[str] = None, username: Optional[str] = None, password: Optional[str] = None, insecure: Optional[bool] = None, credentials: Optional[ChannelCredentials] = None, transport_format: Optional[str] = None, ): self.service_name = service_name self.agent_host_name = _parameter_setter( param=agent_host_name, env_variable=Configuration().EXPORTER_JAEGER_AGENT_HOST, default=DEFAULT_AGENT_HOST_NAME, ) self.agent_port = _parameter_setter( param=agent_port, env_variable=Configuration().EXPORTER_JAEGER_AGENT_PORT, default=DEFAULT_AGENT_PORT, ) self._agent_client = AgentClientUDP(host_name=self.agent_host_name, port=self.agent_port) self.collector_endpoint = _parameter_setter( param=collector_endpoint, env_variable=Configuration().EXPORTER_JAEGER_ENDPOINT, default=None, ) self.username = _parameter_setter( param=username, env_variable=Configuration().EXPORTER_JAEGER_USER, default=None, ) self.password = _parameter_setter( param=password, env_variable=Configuration().EXPORTER_JAEGER_PASSWORD, default=None, ) self._collector = None self._grpc_client = None self.insecure = util._get_insecure(insecure) self.credentials = util._get_credentials(credentials) self.transport_format = (transport_format.lower() if transport_format else TRANSPORT_FORMAT_THRIFT)