LangChain
Trace LangChain and LangGraph in Python and TypeScript.
LangChain and LangGraph are captured automatically — LLM calls, chains, tools, and retrievers all become spans, including LangGraph node boundaries and tool loops. A run self-roots, so just instrumenting renders a complete trace with no extra wrapper.
Prerequisites
pip install -U "neatlogs[langchain]" langchain-openaiUsage
import os
import neatlogs
neatlogs.init(
api_key=os.environ["NEATLOGS_API_KEY"],
workflow_name="langchain-demo",
instrumentations=["langchain"],
)
# Import LangChain AFTER init() so it's patched.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o")
print(llm.invoke("In one sentence, what is LangChain?").content)
neatlogs.flush()
neatlogs.shutdown()The instrumented run opens a WORKFLOW root automatically — even a bare llm.invoke() renders on its own. To group several calls (or your own @span functions) under one trace, wrap the entry point with a root; see Grouping calls into one trace.
For LangGraph, use the same setup — instrumentations=["langchain"] in Python (it captures graph execution), and the langchainHandler() callback in TypeScript. Pass instrumentations=["langgraph"] only if you need LangGraph-specific node/edge spans on top of the LLM spans.
Python note: for most LangGraph apps,
"langchain"is all you need — it captures calls throughlangchain_openai,langchain_anthropic, etc. automatically.
TypeScript / LangGraph note: attach
langchainHandler()to the model/LLM call (e.g. inside the LLM node), not tograph.invoke(). Passing it at the graph level can produce duplicate, noisy chain spans.