Create and yield an instrumentation span as the current span using proper context management. This function creates a span that will automatically be nested properly within any parent span based on the current execution context, using OpenTelemetry's context management to properly
(
operation_name: str, span_kind: str, version: Optional[int] = None, attributes: Optional[Dict[str, Any]] = None
)
| 76 | |
| 77 | @contextmanager |
| 78 | def _create_as_current_span( |
| 79 | operation_name: str, span_kind: str, version: Optional[int] = None, attributes: Optional[Dict[str, Any]] = None |
| 80 | ) -> Generator[Span, None, None]: |
| 81 | """ |
| 82 | Create and yield an instrumentation span as the current span using proper context management. |
| 83 | |
| 84 | This function creates a span that will automatically be nested properly |
| 85 | within any parent span based on the current execution context, using OpenTelemetry's |
| 86 | context management to properly handle span lifecycle. |
| 87 | |
| 88 | Args: |
| 89 | operation_name: Name of the operation being traced |
| 90 | span_kind: Type of operation (from SpanKind) |
| 91 | version: Optional version identifier for the operation |
| 92 | attributes: Optional dictionary of attributes to set on the span |
| 93 | |
| 94 | Yields: |
| 95 | A span with proper context that will be automatically closed when exiting the context |
| 96 | """ |
| 97 | # Log before we do anything |
| 98 | before_span = _get_current_span_info() |
| 99 | logger.debug(f"[DEBUG] BEFORE {operation_name}.{span_kind} - Current context: {before_span}") |
| 100 | |
| 101 | # Create span with proper naming convention |
| 102 | span_name = f"{operation_name}.{span_kind}" |
| 103 | |
| 104 | # Get tracer |
| 105 | otel_tracer = tracer.get_tracer() |
| 106 | |
| 107 | # Prepare attributes |
| 108 | if attributes is None: |
| 109 | attributes = {} |
| 110 | |
| 111 | # Add span kind to attributes |
| 112 | attributes[SpanAttributes.AGENTOPS_SPAN_KIND] = span_kind |
| 113 | |
| 114 | # Add standard attributes |
| 115 | attributes[SpanAttributes.OPERATION_NAME] = operation_name |
| 116 | if version is not None: |
| 117 | attributes[SpanAttributes.OPERATION_VERSION] = version |
| 118 | |
| 119 | # Get current context explicitly to debug it |
| 120 | current_context = context_api.get_current() |
| 121 | |
| 122 | # Use OpenTelemetry's context manager to properly handle span lifecycle |
| 123 | with otel_tracer.start_as_current_span(span_name, attributes=attributes, context=current_context) as span: |
| 124 | # Log after span creation |
| 125 | if hasattr(span, "get_span_context"): |
| 126 | span_ctx = span.get_span_context() |
| 127 | logger.debug( |
| 128 | f"[DEBUG] CREATED {span_name} - span_id: {span_ctx.span_id:x}, parent: {before_span.get('span_id', 'None')}" |
| 129 | ) |
| 130 | |
| 131 | yield span |
| 132 | |
| 133 | # Log after we're done |
| 134 | after_span = _get_current_span_info() |
| 135 | logger.debug(f"[DEBUG] AFTER {operation_name}.{span_kind} - Returned to context: {after_span}") |
no test coverage detected
searching dependent graphs…