Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions plugins/callback/opentelemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,29 @@ def finish_task(self, tasks_data, status, result, dump):
task.dump = dump
task.add_host(HostData(host_uuid, host_name, status, result))

def create_import_spans(self, tracer, imported_playbooks, disable_logs, disable_attributes_in_logs):
"""Create spans for imported playbooks as children of the current span"""
if not imported_playbooks:
return

for imported_playbook in imported_playbooks:
with tracer.start_as_current_span(
f"import_playbook: {imported_playbook}",
kind=SpanKind.CLIENT
) as import_span:
attributes = {
"ansible.import.type": "playbook",
"ansible.import.file": imported_playbook,
"ansible.import.status": "imported"
}
import_span.set_attributes(attributes)
import_span.set_status(Status(status_code=StatusCode.OK))

# Add log event if not disabled
if not disable_logs:
event_attributes = {} if disable_attributes_in_logs else attributes
import_span.add_event(f"Imported playbook: {imported_playbook}", attributes=event_attributes)

def generate_distributed_traces(
self,
otel_service_name,
Expand All @@ -267,6 +290,7 @@ def generate_distributed_traces(
disable_attributes_in_logs,
otel_exporter_otlp_traces_protocol,
store_spans_in_file,
imported_playbooks=None,
):
"""generate distributed traces from the collected TaskData and HostData"""

Expand Down Expand Up @@ -308,6 +332,10 @@ def generate_distributed_traces(
if self.ip_address is not None:
parent.set_attribute("ansible.host.ip", self.ip_address)
parent.set_attribute("ansible.host.user", self.user)

# Create import spans for imported playbooks
self.create_import_spans(tracer, imported_playbooks, disable_logs, disable_attributes_in_logs)

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:
Expand Down Expand Up @@ -494,8 +522,10 @@ def __init__(self, display=None):
self.disable_logs = None
self.otel_service_name = None
self.ansible_playbook = None
self.main_playbook = None
self.play_name = None
self.tasks_data = None
self.imported_playbooks = []
self.errors = 0
self.disabled = False
self.traceparent = False
Expand Down Expand Up @@ -555,10 +585,26 @@ def dump_results(self, task, result):

def v2_playbook_on_start(self, playbook):
self.ansible_playbook = basename(playbook._file_name)
if self.main_playbook is None:
self.main_playbook = playbook._file_name

def v2_playbook_on_play_start(self, play):
self.play_name = play.get_name()

# Check if this play is from an imported playbook
if hasattr(play, 'get_path'):
play_path = play.get_path()

# If the play path is different from main playbook, it's imported
if play_path and play_path != self.main_playbook:
# Extract just the filename without line number
play_file = play_path.split(':')[0] if ':' in play_path else play_path
imported_playbook_name = basename(play_file)

# Store for later span creation
if imported_playbook_name not in self.imported_playbooks:
self.imported_playbooks.append(imported_playbook_name)

def v2_runner_on_no_hosts(self, task):
self.opentelemetry.start_task(self.tasks_data, self.hide_task_arguments, self.play_name, task)

Expand Down Expand Up @@ -610,6 +656,7 @@ def v2_playbook_on_stats(self, stats):
self.disable_attributes_in_logs,
self.otel_exporter_otlp_traces_protocol,
self.store_spans_in_file,
self.imported_playbooks,
)

if self.store_spans_in_file:
Expand Down
Loading