From 6889e0478d8404250debaca37376185002f0d9d2 Mon Sep 17 00:00:00 2001 From: Wilfried ROSET Date: Wed, 15 May 2024 18:47:05 +0200 Subject: [PATCH] [opentelemetry][callback] Add support for http exporter (#8321) * [opentelemetry][callback] Add support for http exporter The previous version of the callback was supporting only the grpc exporter. This was counter intuitive as the documentation was mentioning ``. Users were left with a error similar to `Transient error StatusCode.UNAVAILABLE encountered while exporting traces to , retrying in 1s.` The following commit fix this situation by support both HTTP and GRPC via the standard environment variables and ansible.cfg See as well https://github.com/ansible-collections/community.general/issues/7888 Signed-off-by: Wilfried Roset * [opentelemetry][callback] Take into account review Signed-off-by: Wilfried Roset --------- Signed-off-by: Wilfried Roset --- .../8321-fix-opentelemetry-callback.yml | 2 + plugins/callback/opentelemetry.py | 41 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/8321-fix-opentelemetry-callback.yml diff --git a/changelogs/fragments/8321-fix-opentelemetry-callback.yml b/changelogs/fragments/8321-fix-opentelemetry-callback.yml new file mode 100644 index 0000000000..a02f12c6b9 --- /dev/null +++ b/changelogs/fragments/8321-fix-opentelemetry-callback.yml @@ -0,0 +1,2 @@ +minor_changes: + - opentelemetry - add support for HTTP trace_exporter and configures the behavior via ``OTEL_EXPORTER_OTLP_TRACES_PROTOCOL`` (https://github.com/ansible-collections/community.general/issues/7888, https://github.com/ansible-collections/community.general/pull/8321). diff --git a/plugins/callback/opentelemetry.py b/plugins/callback/opentelemetry.py index 492e420716..c3437b7306 100644 --- a/plugins/callback/opentelemetry.py +++ b/plugins/callback/opentelemetry.py @@ -84,6 +84,22 @@ DOCUMENTATION = ''' - section: callback_opentelemetry key: disable_attributes_in_logs version_added: 7.1.0 + otel_exporter_otlp_traces_protocol: + type: str + description: + - E(OTEL_EXPORTER_OTLP_TRACES_PROTOCOL) represents the the transport protocol for spans. + - See + U(https://opentelemetry-python.readthedocs.io/en/latest/sdk/environment_variables.html#envvar-OTEL_EXPORTER_OTLP_TRACES_PROTOCOL). + default: grpc + choices: + - grpc + - http/protobuf + env: + - name: OTEL_EXPORTER_OTLP_TRACES_PROTOCOL + ini: + - section: callback_opentelemetry + key: otel_exporter_otlp_traces_protocol + version_added: 9.0.0 requirements: - opentelemetry-api (Python library) - opentelemetry-exporter-otlp (Python library) @@ -124,7 +140,8 @@ from ansible.plugins.callback import CallbackBase try: from opentelemetry import trace from opentelemetry.trace import SpanKind - from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter + from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter as GRPCOTLPSpanExporter + from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as HTTPOTLPSpanExporter from opentelemetry.sdk.resources import SERVICE_NAME, Resource from opentelemetry.trace.status import Status, StatusCode from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator @@ -255,7 +272,15 @@ class OpenTelemetrySource(object): task.dump = dump task.add_host(HostData(host_uuid, host_name, status, result)) - def generate_distributed_traces(self, otel_service_name, ansible_playbook, tasks_data, status, traceparent, disable_logs, disable_attributes_in_logs): + def generate_distributed_traces(self, + otel_service_name, + ansible_playbook, + tasks_data, + status, + traceparent, + disable_logs, + disable_attributes_in_logs, + otel_exporter_otlp_traces_protocol): """ generate distributed traces from the collected TaskData and HostData """ tasks = [] @@ -271,7 +296,11 @@ class OpenTelemetrySource(object): ) ) - processor = BatchSpanProcessor(OTLPSpanExporter()) + processor = None + if otel_exporter_otlp_traces_protocol == 'grpc': + processor = BatchSpanProcessor(GRPCOTLPSpanExporter()) + else: + processor = BatchSpanProcessor(HTTPOTLPSpanExporter()) trace.get_tracer_provider().add_span_processor(processor) @@ -462,6 +491,7 @@ class CallbackModule(CallbackBase): self.errors = 0 self.disabled = False self.traceparent = False + self.otel_exporter_otlp_traces_protocol = None if OTEL_LIBRARY_IMPORT_ERROR: raise_from( @@ -497,6 +527,8 @@ class CallbackModule(CallbackBase): # See https://github.com/open-telemetry/opentelemetry-specification/issues/740 self.traceparent = self.get_option('traceparent') + self.otel_exporter_otlp_traces_protocol = self.get_option('otel_exporter_otlp_traces_protocol') + def v2_playbook_on_start(self, playbook): self.ansible_playbook = basename(playbook._file_name) @@ -585,7 +617,8 @@ class CallbackModule(CallbackBase): status, self.traceparent, self.disable_logs, - self.disable_attributes_in_logs + self.disable_attributes_in_logs, + self.otel_exporter_otlp_traces_protocol, ) def v2_runner_on_async_failed(self, result, **kwargs):