summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/general/plugins/callback/opentelemetry.py
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/community/general/plugins/callback/opentelemetry.py')
-rw-r--r--ansible_collections/community/general/plugins/callback/opentelemetry.py65
1 files changed, 44 insertions, 21 deletions
diff --git a/ansible_collections/community/general/plugins/callback/opentelemetry.py b/ansible_collections/community/general/plugins/callback/opentelemetry.py
index e00e1d71a..492e42071 100644
--- a/ansible_collections/community/general/plugins/callback/opentelemetry.py
+++ b/ansible_collections/community/general/plugins/callback/opentelemetry.py
@@ -32,10 +32,10 @@ DOCUMENTATION = '''
enable_from_environment:
type: str
description:
- - Whether to enable this callback only if the given environment variable exists and it is set to C(true).
+ - Whether to enable this callback only if the given environment variable exists and it is set to V(true).
- This is handy when you use Configuration as Code and want to send distributed traces
if running in the CI rather when running Ansible locally.
- - For such, it evaluates the given I(enable_from_environment) value as environment variable
+ - For such, it evaluates the given O(enable_from_environment) value as environment variable
and if set to true this plugin will be enabled.
env:
- name: ANSIBLE_OPENTELEMETRY_ENABLE_FROM_ENVIRONMENT
@@ -73,6 +73,17 @@ DOCUMENTATION = '''
- section: callback_opentelemetry
key: disable_logs
version_added: 5.8.0
+ disable_attributes_in_logs:
+ default: false
+ type: bool
+ description:
+ - Disable populating span attributes to the logs.
+ env:
+ - name: ANSIBLE_OPENTELEMETRY_DISABLE_ATTRIBUTES_IN_LOGS
+ ini:
+ - section: callback_opentelemetry
+ key: disable_attributes_in_logs
+ version_added: 7.1.0
requirements:
- opentelemetry-api (Python library)
- opentelemetry-exporter-otlp (Python library)
@@ -244,7 +255,7 @@ 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):
+ def generate_distributed_traces(self, otel_service_name, ansible_playbook, tasks_data, status, traceparent, disable_logs, disable_attributes_in_logs):
""" generate distributed traces from the collected TaskData and HostData """
tasks = []
@@ -280,9 +291,9 @@ class OpenTelemetrySource(object):
for task in tasks:
for host_uuid, host_data in task.host_data.items():
with tracer.start_as_current_span(task.name, start_time=task.start, end_on_exit=False) as span:
- self.update_span_data(task, host_data, span, disable_logs)
+ self.update_span_data(task, host_data, span, disable_logs, disable_attributes_in_logs)
- def update_span_data(self, task_data, host_data, span, disable_logs):
+ def update_span_data(self, task_data, host_data, span, disable_logs, disable_attributes_in_logs):
""" update the span with the given TaskData and HostData """
name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)
@@ -315,39 +326,47 @@ class OpenTelemetrySource(object):
status = Status(status_code=StatusCode.UNSET)
span.set_status(status)
+
+ # Create the span and log attributes
+ attributes = {
+ "ansible.task.module": task_data.action,
+ "ansible.task.message": message,
+ "ansible.task.name": name,
+ "ansible.task.result": rc,
+ "ansible.task.host.name": host_data.name,
+ "ansible.task.host.status": host_data.status
+ }
if isinstance(task_data.args, dict) and "gather_facts" not in task_data.action:
names = tuple(self.transform_ansible_unicode_to_str(k) for k in task_data.args.keys())
values = tuple(self.transform_ansible_unicode_to_str(k) for k in task_data.args.values())
- self.set_span_attribute(span, ("ansible.task.args.name"), names)
- self.set_span_attribute(span, ("ansible.task.args.value"), values)
- self.set_span_attribute(span, "ansible.task.module", task_data.action)
- self.set_span_attribute(span, "ansible.task.message", message)
- self.set_span_attribute(span, "ansible.task.name", name)
- self.set_span_attribute(span, "ansible.task.result", rc)
- self.set_span_attribute(span, "ansible.task.host.name", host_data.name)
- self.set_span_attribute(span, "ansible.task.host.status", host_data.status)
+ attributes[("ansible.task.args.name")] = names
+ attributes[("ansible.task.args.value")] = values
+
+ self.set_span_attributes(span, attributes)
+
# This will allow to enrich the service map
self.add_attributes_for_service_map_if_possible(span, task_data)
# Send logs
if not disable_logs:
- span.add_event(task_data.dump)
- span.end(end_time=host_data.finish)
+ # This will avoid populating span attributes to the logs
+ span.add_event(task_data.dump, attributes={} if disable_attributes_in_logs else attributes)
+ span.end(end_time=host_data.finish)
- def set_span_attribute(self, span, attributeName, attributeValue):
- """ update the span attribute with the given attribute and value if not None """
+ def set_span_attributes(self, span, attributes):
+ """ update the span attributes with the given attributes if not None """
if span is None and self._display is not None:
self._display.warning('span object is None. Please double check if that is expected.')
else:
- if attributeValue is not None:
- span.set_attribute(attributeName, attributeValue)
+ if attributes is not None:
+ span.set_attributes(attributes)
def add_attributes_for_service_map_if_possible(self, span, task_data):
"""Update the span attributes with the service that the task interacted with, if possible."""
redacted_url = self.parse_and_redact_url_if_possible(task_data.args)
if redacted_url:
- self.set_span_attribute(span, "http.url", redacted_url.geturl())
+ span.set_attribute("http.url", redacted_url.geturl())
@staticmethod
def parse_and_redact_url_if_possible(args):
@@ -434,6 +453,7 @@ class CallbackModule(CallbackBase):
def __init__(self, display=None):
super(CallbackModule, self).__init__(display=display)
self.hide_task_arguments = None
+ self.disable_attributes_in_logs = None
self.disable_logs = None
self.otel_service_name = None
self.ansible_playbook = None
@@ -465,6 +485,8 @@ class CallbackModule(CallbackBase):
self.hide_task_arguments = self.get_option('hide_task_arguments')
+ self.disable_attributes_in_logs = self.get_option('disable_attributes_in_logs')
+
self.disable_logs = self.get_option('disable_logs')
self.otel_service_name = self.get_option('otel_service_name')
@@ -562,7 +584,8 @@ class CallbackModule(CallbackBase):
self.tasks_data,
status,
self.traceparent,
- self.disable_logs
+ self.disable_logs,
+ self.disable_attributes_in_logs
)
def v2_runner_on_async_failed(self, result, **kwargs):