Sign in
agent:
Auto Exec

Searches Jaeger for traces from specified services containing image-related paths in the last n minutes, sorted by duration.

path_filter example: (http.target or http.route or url.path contains /path_filter for eg: /api/checkout).

Limit the result by 5 rows.

Requires inputs: lookback_minutes (int), target_services (array), path_filter (str) and limit (int)

import requests import json from datetime import datetime, timedelta import time filtered_traces = [] trace_count = 0 # Get Jaeger URL from environment jaeger_url = getEnvVar('JAEGER_URL_OTEL') # Calculate time range (last 30 minutes) end_time = datetime.now() start_time = end_time - timedelta(minutes=lookback_minutes) # Convert to microseconds (Jaeger expects microseconds) start_time_us = int(start_time.timestamp() * 1000000) end_time_us = int(end_time.timestamp() * 1000000) print(f"Searching for traces from {start_time} to {end_time}") print(f"Target services: {target_services}") print(f"Path filter: {path_filter}") all_traces = [] # Search traces for each target service for service in target_services: print(f"\nSearching traces for service: {service}") # Construct the traces search URL traces_url = f"{jaeger_url}traces" params = { 'service': service, 'start': start_time_us, 'end': end_time_us, 'limit': 1000 # Get more traces to filter from } try: response = requests.get(traces_url, params=params, timeout=6) response.raise_for_status() traces_data = response.json() if 'data' in traces_data: traces = traces_data['data'] print(f"Found {len(traces)} traces for {service}") # Filter traces that contain the path filter in http fields for trace in traces: if 'spans' in trace: for span in trace['spans']: if 'tags' in span: # Check for http.target, http.route, or url.path containing /image http_fields = ['http.target', 'http.route', 'url.path'] path_found = False for tag in span['tags']: if tag.get('key') in http_fields: if path_filter in str(tag.get('value', '')): path_found = True break if path_found: # Calculate total trace duration trace_duration = 0 if trace['spans']: min_start = min(span.get('startTime', 0) for span in trace['spans']) max_end = max(span.get('startTime', 0) + span.get('duration', 0) for span in trace['spans']) trace_duration = max_end - min_start trace_info = { 'traceID': trace.get('traceID'), 'service': service, 'duration_us': trace_duration, 'duration_ms': round(trace_duration / 1000, 2), 'spans_count': len(trace['spans']), 'start_time': datetime.fromtimestamp(min_start / 1000000).isoformat() if trace['spans'] else None } # Find the operation name from root span root_spans = [s for s in trace['spans'] if not s.get('references')] if root_spans: trace_info['operation'] = root_spans[0].get('operationName', 'unknown') else: trace_info['operation'] = trace['spans'][0].get('operationName', 'unknown') all_traces.append(trace_info) break # Found matching span, no need to check other spans in this trace except requests.exceptions.RequestException as e: print(f"Error fetching traces for {service}: {e}") except Exception as e: print(f"Error processing traces for {service}: {e}") # Sort traces by duration descending all_traces.sort(key=lambda x: x['duration_us'], reverse=True) # Limit to top 50 filtered_traces = all_traces[:limit] trace_count = len(filtered_traces) print(f"\nFound {trace_count} traces matching criteria:") for i, trace in enumerate(filtered_traces[:10], 1): # Show first 10 for preview print(f"{i}. TraceID: {trace['traceID'][:16]}... | Service: {trace['service']} | Operation: {trace['operation']} | Duration: {trace['duration_ms']}ms") if trace_count > 10: print(f"... and {trace_count - 10} more traces") print(f"\nOutput Parameters:") print(f"filtered_traces: {json.dumps(filtered_traces, indent=2)}") print(f"trace_count: {trace_count}")
copied