Accessing LangChain Spans in Async LangGraph: Need Assistance!
Subject: Accessing and Modifying Auto-Instrumented LangChain Spans in Async LangGraph - Help Needed! Hi everyone, I’m facing an issue trying to access and modify the auto-instrumented spans generated by LangChain within my asynchronous LangGraph workflow. I’m hoping someone can point me in the right direction. Problem: When I use trace.get_current_span() inside my data_retriever_node function, I’m getting a NonRecordingSpan with all zeros for trace and span IDs. This indicates I’m not accessing the actual LangChain-generated span, which I need to modify. Code Snippets: Initialization Code (set_trace_provider):
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace.exporter import OTLPSpanExporter
from opentelemetry.instrumentation.langchain import LangchainInstrumentor
from opentelemetry.sdk.resources import Resource
from opentelemetry.trace import SpanContext, TraceFlags, NonRecordingSpan
from opentelemetry.context import attach, detach
from openinference.instrumentation.openai import OpenAIInstrumentor
from phoenix.otel import register
import logging
import uuid
import random
import os
def set_trace_provider(service_name: str = "copilot", is_instrument_langchain_enable: bool = False, is_openai_instrument_enable: bool = False) -> None:
_tracer_provider = None
otlp_exporter_enpoint = os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT", None)
if is_instrument_langchain_enable or is_openai_instrument_enable:
_tracer_provider = register(project_name=service_name, set_global_tracer_provider=False)
else:
resource = Resource.create({"service.name": service_name})
_tracer_provider = TracerProvider(resource=resource)
grpc_exporter = OTLPSpanExporter(endpoint=otlp_exporter_enpoint,
insecure=os.getenv("OTEL_EXPORTER_OTLP_INSECURE", True))
_tracer_provider.add_span_processor(BatchSpanProcessor(grpc_exporter))
trace.set_tracer_provider(_tracer_provider)
if is_instrument_langchain_enable:
LangchainInstrumentor().instrument()
if is_openai_instrument_enable:
OpenAIInstrumentor().instrument(tracer_provider=_tracer_provider)
def gettracer(name: str = __name__) -> trace.Tracer:
return trace.get_tracer(name)Code where I’m trying to access the span (data_retriever_node):
from opentelemetry import trace
from opentelemetry.util.context import context_with_attributes
async def data_retriever_node(state: dict) -> dict:
# Trying to get current span
current_span = trace.get_current_span()
print("\n= Current Auto-instrumented Span =")
print(f"Span Type: {type(current_span)}")
print(f"Span Context: {current_span.get_span_context()}")
print("=")
tool_call = state["messages"][-1].tool_calls[0]
query = tool_call["args"]["query"]
metadata = {
"tool_query": query,
"tool_type": "data_retriever",
"tool_call_id": tool_call["id"]
}
with context_with_attributes(attributes=metadata):
# Rest of the code...
passOutput:
query: What are the top brands by sales?
= Current Auto-instrumented Span =
Span Type: <class 'opentelemetry.trace.span.NonRecordingSpan'>
Span Context: SpanContext(trace_id=0x00000000000000000000000000000000, span_id=0x0000000000000000, trace_flags=0x00, trace_state=[], is_remote=False)
=Question: How can I correctly access and modify the auto-instrumented LangChain span within my data_retriever_node function in this asynchronous LangGraph context? I need to add custom attributes to the existing spans, not create new ones. Additional Context:
LangChain auto-instrumentation is enabled.
The code runs in an asynchronous LangGraph environment.
I can see LangChain spans in my telemetry system, so the instrumentation is generally working.
I want to add custom attributes to the existing LangChain spans using context_with_attributes.
