traceloop / traceloop/openllmetry

๐Ÿ› Bug Report: Spans being detached from Langchain parent traces

Open
#1,541 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
7.4k
Forks
1.1k
Avg merge
8d 14h
Merged PRs (30d)
2

Description

Which component is this bug for?

Langchain Instrumentation

๐Ÿ“œ Description

Calls to functions instrumented by other libraries get detached from the parent trace. This happens for example in Langchain chains which call a retriever which is instrumented by opentelemetry.instrumentation.sqlalchemy. The nominally child spans are created but are independent of each other and of the actual parent.

Occurs for both sync and async calls.

๐Ÿ‘Ÿ Reproduction steps

This code reproduces the issue given a local postgres server:

import os

from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_postgres import PGVector
from opentelemetry.sdk.trace.export import ConsoleSpanExporter
from traceloop.sdk import Traceloop


Traceloop.init(
    exporter=ConsoleSpanExporter(),
)

PROMPT_TEMPLATE = """
You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question.

Question: {question} 

Context: {context} 

Answer:
"""

qa_prompt = PromptTemplate.from_template(PROMPT_TEMPLATE)

llm = AzureChatOpenAI()

embeddings = OpenAIEmbeddings()

vectorstore = PGVector(
    connection=PGVector.connection_string_from_db_params(
        driver="psycopg",
        host="localhost",
        port=5432,
        database="vectors",
        user="postgres",
        password="localpassword"
    ),
    embeddings=embeddings,
)

def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

qa_chain = (
    {
        "context": vectorstore.as_retriever() | format_docs,
        "question": RunnablePassthrough(),
    }
    | qa_prompt | llm | StrOutputParser()
)

qa_chain.invoke("What are autonomous agents?")

๐Ÿ‘ Expected behavior

All spans in the chain should have the same trace_id and appropriate parent_id.

๐Ÿ‘Ž Actual Behavior with Screenshots

Example:

{
    "name": "RunnableAssign<filter>.langchain.task",
    "context": {
        "trace_id": "**0x2b1a7979f5725daf1a624b67a66c0d65**",
        "span_id": "0xff0ed485230f3387",
        "trace_state": "[]"
    },
    "kind": "SpanKind.INTERNAL",
    "parent_id": "**0x8e9d707a6ced4a3e**",
    "start_time": "2024-07-11T16:54:46.031626Z",
    "end_time": "2024-07-11T16:54:46.146668Z",
    "status": {
        "status_code": "UNSET"
    },
    "attributes": {
        "traceloop.span.kind": "task",
        "traceloop.entity.name": "RunnableAssign<filter>.langchain.task"
    },
    "events": [],
    "links": [],
    "resource": {
        "attributes": {
            "service.name": "dev"
        },
        "schema_url": ""
    }
}
{
    "name": "connect",
    "context": {
        "trace_id": "**0x8e897f889032d34c89fab768696dda50**",
        "span_id": "0x16564f54d9e75f4a",
        "trace_state": "[]"
    },
    "kind": "SpanKind.CLIENT",
    "parent_id": **null**,
    "start_time": "2024-07-11T16:54:46.158278Z",
    "end_time": "2024-07-11T16:54:46.178849Z",
    "status": {
        "status_code": "UNSET"
    },
    "attributes": {
        "net.peer.name": "localhost",
        "net.peer.port": 5432,
        "db.name": "postgres",
        "db.user": "postgres",
        "db.system": "postgresql"
    },
    "events": [],
    "links": [],
    "resource": {
        "attributes": {
            "service.name": "dev"
        },
        "schema_url": ""
    }
}
{
    "name": "connect",
    "context": {
        "trace_id": "**0x81bd9194f61397cbe0bd534c37f0ea35**",
        "span_id": "0x5b67b8e9ffad9bf1",
        "trace_state": "[]"
    },
    "kind": "SpanKind.CLIENT",
    "parent_id": **null**,
    "start_time": "2024-07-11T16:54:46.182237Z",
    "end_time": "2024-07-11T16:54:46.182272Z",
    "status": {
        "status_code": "UNSET"
    },
    "attributes": {
        "net.peer.name": "localhost",
        "net.peer.port": 5432,
        "db.name": "postgres",
        "db.user": "postgres",
        "db.system": "postgresql"
    },
    "events": [],
    "links": [],
    "resource": {
        "attributes": {
            "service.name": "dev"
        },
        "schema_url": ""
    }
}
{
    "name": "connect",
    "context": {
        "trace_id": "**0xee2ee041c775319c24a37d968f4afbf2**",
        "span_id": "0xdbc3250f693b6ec2",
        "trace_state": "[]"
    },
    "kind": "SpanKind.CLIENT",
    "parent_id": **null**,
    "start_time": "2024-07-11T16:54:46.189804Z",
    "end_time": "2024-07-11T16:54:46.189848Z",
    "status": {
        "status_code": "UNSET"
    },
    "attributes": {
        "net.peer.name": "localhost",
        "net.peer.port": 5432,
        "db.name": "postgres",
        "db.user": "postgres",
        "db.system": "postgresql"
    },
    "events": [],
    "links": [],
    "resource": {
        "attributes": {
            "service.name": "dev"
        },
        "schema_url": ""
    }
}
{
    "name": "connect",
    "context": {
        "trace_id": "**0x175f1f1a4b4a24a093615e2d6dc9be0c**",
        "span_id": "0xc96e709b49c7a085",
        "trace_state": "[]"
    },
    "kind": "SpanKind.CLIENT",
    "parent_id": **null**,
    "start_time": "2024-07-11T16:54:47.339822Z",
    "end_time": "2024-07-11T16:54:47.340088Z",
    "status": {
        "status_code": "UNSET"
    },
    "attributes": {
        "net.peer.name": "localhost",
        "net.peer.port": 5432,
        "db.name": "postgres",
        "db.user": "postgres",
        "db.system": "postgresql"
    },
    "events": [],
    "links": [],
    "resource": {
        "attributes": {
            "service.name": "dev"
        },
        "schema_url": ""
    }
}
{
    "name": "RunnableSequence.langchain.task",
    "context": {
        "trace_id": "**0x2b1a7979f5725daf1a624b67a66c0d65**",
        "span_id": "0x8e9d707a6ced4a3e",
        "trace_state": "[]"
    },
    "kind": "SpanKind.INTERNAL",
    "parent_id": "**0x73b5335f38792980**",
    "start_time": "2024-07-11T16:54:46.027813Z",
    "end_time": "2024-07-11T16:54:47.468602Z",
    "status": {
        "status_code": "UNSET"
    },
    "attributes": {
        "traceloop.span.kind": "task",
        "traceloop.entity.name": "RunnableSequence.langchain.task"
    },
    "events": [],
    "links": [],
    "resource": {
        "attributes": {
            "service.name": "dev"
        },
        "schema_url": ""
    }
}
๐Ÿค– Python Version

No response

๐Ÿ“ƒ Provide any additional context for the Bug.

Present in 0.25.3.

๐Ÿ‘€ Have you spent some time to check if this bug has been raised before?
  • I checked and didn't find similar issue
Are you willing to submit PR?

None

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up โ€” it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the provided Langchain reproduction with a local PostgreSQL server and inspect the Langchain instrumentation alongside sqlalchemy instrumentation. Check both synchronous and asynchronous calls, then verify that all spans share one trace_id and that database spans have the appropriate parent_id under the Langchain trace.

Written by the indexing model from the issue text.

Assessment

Tech stack
postgresql, python
Domain
observability
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.