> ## Documentation Index
> Fetch the complete documentation index at: https://agent-observability-docs.splunk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Logging

> Learn about using the Splunk Agent Observability LangChain and LangGraph logging integration to log agent traces

The Splunk Agent Observability LangChain integration allows you to automatically log all LangChain and LangGraph interactions with LLMs, including prompts, responses, and performance evaluators. The Splunk Agent Observability SDK has a custom callback that is passed to LangChain or LangGraph.

> **[SplunkAOCallback - Python](https://agent-observability-docs.splunk.com/sdk-api/python/reference/handlers/langchain/handler.md)**
>
> The Python Splunk Agent Observability Synchronous LangChain SDK reference.

> **[SplunkAOAsyncCallback - Python](https://agent-observability-docs.splunk.com/sdk-api/python/reference/handlers/langchain/async_handler.md)**
>
> The Python Splunk Agent Observability Asynchronous LangChain SDK reference.

## Basic usage

The integration is based on the `SplunkAOCallback` class, which implements LangChain's callback interface. To use it, create an instance of the callback and pass it to your LangChain components:

```python Python theme={null}
from splunk_ao.handlers.langchain import SplunkAOCallback
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage

# Create a callback handler
callback = SplunkAOCallback()

# Initialize the LLM with the callback
llm = ChatOpenAI(model="gpt-4o", temperature=0.7, callbacks=[callback])

# Create a message with the user's query
messages = [
    HumanMessage(content="What is LangChain and how is it used with OpenAI?")
]

# Make the API call
response = llm.invoke(messages)

print(response.content)
```

The `SplunkAOCallback` captures various LangChain events, including:

* LLM starts and completions
* Chat model interactions
* Chain executions
* Tool calls
* Retriever operations
* Agent actions

For each of these events, the callback logs relevant information to Splunk Agent Observability, such as:

* Input prompts and messages
* Output responses
* Model information
* Timing data
* Token usage
* Error information (if any)

The SplunkAOCallback automatically handles nested chains and agents, creating a hierarchical trace that reflects the structure of your LangChain application.

### Asynchronous callbacks

In Python, there are separate callbacks for synchronous and asynchronous code. If you are using the asynchronous LangChain or LangGraph API, use the [`SplunkAOAsyncCallback` callback handler](https://agent-observability-docs.splunk.com/sdk-api/python/reference/handlers/langchain/async_handler).

```python Python theme={null}
import asyncio
from splunk_ao.handlers.langchain import SplunkAOAsyncCallback
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage

# Create a callback handler
callback = SplunkAOAsyncCallback()

# Initialize the LLM with the callback
llm = ChatOpenAI(model="gpt-4o", temperature=0.7, callbacks=[callback])

# Create a message with the user's query
messages = [
    HumanMessage(content="What is LangChain and how is it used with OpenAI?")
]

async def main():
    # Make the API call
    response = await llm.ainvoke(messages)
    print(response.content)

asyncio.run(main())
```

## Use a custom logger

When initializing the `SplunkAOCallback`, you can optionally specify a Splunk Agent Observability logger instance, either by creating a new logger, or by using the current logger from the Splunk Agent Observability context:

```python Python theme={null}
from splunk_ao import SplunkAOLogger
from splunk_ao.handlers.langchain import SplunkAOCallback

# Create a custom logger
logger = SplunkAOLogger(project="my-project", agent_stream="my-agent-stream")

# Create a callback with the custom logger
callback = SplunkAOCallback(
    splunk_ao_logger=logger,  # Optional custom logger
    start_new_trace=True,   # Whether to start a new trace for each chain
    flush_on_chain_end=True # Whether to flush traces when chains end
)
```

This is particularly useful if you want to call your LangChain code from inside a function [decorated with the `log` decorator](https://agent-observability-docs.splunk.com/sdk-api/logging/log-decorator/log-decorator), or from inside an [experiment](https://agent-observability-docs.splunk.com/sdk-api/third-party-integrations/langchain/experiments.md).

### Session and trace support

Every time you invoke a chain or an LLM call, a new session and trace is created. If you want to manually manage sessions or traces, you can do this using by passing a Splunk Agent Observability logger instance to the callback.

To add the chain or LLM call invocation as a new trace to an existing session, create the session first using the logger instance that was used to create the callback:

```python Python theme={null}
from splunk_ao import SplunkAOLogger
from splunk_ao.handlers.langchain import SplunkAOCallback

# Create a custom logger
logger = SplunkAOLogger(project="my-project", agent_stream="my-agent-stream")

# Create a callback with the custom logger
callback = SplunkAOCallback(
    splunk_ao_logger=logger
)

# Create a new session
logger.start_session(name="My new session")
```

To add the chain or LLM call invocation to an existing trace, ensure the trace is started, and set the `start_new_trace` parameter to `False` (Python).

```python Python theme={null}
from splunk_ao import SplunkAOLogger
from splunk_ao.handlers.langchain import SplunkAOCallback

# Create a custom logger
logger = SplunkAOLogger(project="my-project", agent_stream="my-agent-stream")

# Create a callback with the custom logger
callback = SplunkAOCallback(
    splunk_ao_logger=logger,
    start_new_trace=False
)

# Create a new session
logger.start_session(name="My new session")

# Add a trace and a span
logger.start_trace("My trace")
logger.add_workflow_span("Crew workflow")
```

## Use with LangChain chains

You can also use the callback with LangChain chains. Make sure to pass the callback to both the LLM and the chain.

```python Python theme={null}
from splunk_ao.handlers.langchain import SplunkAOAsyncCallback
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables.config import RunnableConfig

# Create a callback handler
callback = SplunkAOAsyncCallback()

# Create the model
llm = ChatOpenAI(model="gpt-4o", temperature=0.7, callbacks=[callback])

# Create a prompt template
prompt = ChatPromptTemplate.from_template("Tell me a joke about {topic}")

# Assemble the chain with the prompt, LLM, and output parser
chain = prompt | llm | StrOutputParser()

# Create a configuration for the runnable
# that includes the callback handler
config = RunnableConfig(
    callbacks=[callback]
)

# Invoke the chain with a topic and configuration
response = chain.invoke({"topic": "the Roman Empire"},
                        config=config)
print(response)
```

## Add metadata

You can add custom metadata and tags to your logs by including them in the `metadata` and `tags` parameters of a LangChain runnable configuration when invoking a chain or LLM.

```python Python theme={null}
# Create a configuration for the runnable
# that includes the callback handler and metadata
config = RunnableConfig(
    callbacks=[callback],
    metadata={
        "user_id": "user-123",
        "session_id": "session-456",
        "custom_field": "custom value",
    },
    tags=["my-tag"],
)

# Invoke the chain with a topic and configuration
response = chain.invoke({"topic": "the Roman Empire"}, config=config)
```

This metadata will be attached to the logs in Splunk Agent Observability, making it easier to filter and analyze your data.

![A chain node in a trace with metadata attached](https://mintcdn.com/agent-observability-docs/Y4gaVgpsSUs8MBdT/sdk-api/third-party-integrations/langchain/metadata.webp?fit=max\&auto=format\&n=Y4gaVgpsSUs8MBdT\&q=85\&s=be6178a35849a68c56e6f700377d0bd9)

## Best practices

1. **Pass callbacks consistently**: Make sure to pass the callback to all LangChain components (LLMs, chains, agents, etc.) to ensure complete logging.
2. **Include meaningful metadata**: Add relevant metadata to your invocations to make it easier to filter and analyze your logs.

## Next steps

### Basic logging components

> **[Splunk Agent Observability logger](https://agent-observability-docs.splunk.com/sdk-api/logging/splunk-ao-logger.md)**
>
> Log with full control over sessions, traces, and spans using the Splunk Agent Observability logger.

> **[Log decorator](https://agent-observability-docs.splunk.com/sdk-api/logging/log-decorator/log-decorator.md)**
>
> Quickly add logging to your code with the log decorator and wrapper.

> **[Splunk Agent Observability context](https://agent-observability-docs.splunk.com/sdk-api/logging/splunk-ao-context.md)**
>
> Manage logging using the Splunk Agent Observability context manager.

### Cookbooks

> **[Monitor LangChain Agents with Splunk Agent Observability](https://agent-observability-docs.splunk.com/cookbooks/use-cases/agent-langchain.md)**
>
> Learn how to build and monitor a LangChain AI Agent using Splunk Agent Observability for tracing and observability.

> **[Add evaluations to a multi-agent LangGraph application](https://agent-observability-docs.splunk.com/cookbooks/use-cases/multi-agent-langgraph/multi-agent-langgraph.md)**
>
> Learn how to add evaluations to a multi-agent LangGraph chat bot using Splunk Agent Observability


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.