Skip to content

langchain instrumentor PR #448

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 39 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1f549b0
migrated from local to this repository
haneric00 Aug 5, 2025
9dab168
formatted using black
haneric00 Aug 5, 2025
13944b3
deleted comment
haneric00 Aug 5, 2025
31b875f
running tox and isort to format imports
haneric00 Aug 5, 2025
8475d99
more fixing from linting instructions
haneric00 Aug 5, 2025
4ecaf95
changes made according to linter:
haneric00 Aug 5, 2025
5d7d17d
removed more than 15 local vars from testing file and changed return …
haneric00 Aug 5, 2025
142b99f
removed 2 lcoal vars
haneric00 Aug 5, 2025
8a4e6d5
ran black to reformat
haneric00 Aug 5, 2025
7a8c2dd
changed to hopefully finally have acceptable number of local vars
haneric00 Aug 5, 2025
2b1e66f
refactored to fit Johnny's PR
haneric00 Aug 6, 2025
e27abb0
adding to dev-requirements langchain core and langchain and langgraph
haneric00 Aug 6, 2025
54365b8
langgraph to dev reqs
haneric00 Aug 6, 2025
70dea80
trying to get my PR to build, modifying dev reqs
haneric00 Aug 6, 2025
b8b8636
update pyproject.toml
haneric00 Aug 6, 2025
ab44b5a
update langchain-aws version (version conflict resolution)
haneric00 Aug 6, 2025
829a5c3
updated package versiosn to what I have locally
haneric00 Aug 6, 2025
69a7873
addressed python 3.9 issue and added duckduckgo search to the pyproje…
haneric00 Aug 6, 2025
354fdbb
add 1 line install pytest-asyncio, for async tests
haneric00 Aug 6, 2025
da0c624
added more dependencies to pyproject.toml, added another test file fo…
haneric00 Aug 6, 2025
18e85bd
added 1 more test file for code coverage
haneric00 Aug 6, 2025
23e0f2c
converted another test file to mock
haneric00 Aug 7, 2025
d19e256
added test skipping if no AWS keys are found
haneric00 Aug 7, 2025
5d671b0
added 1 more test file + fixed a bug in the uninstrument method
haneric00 Aug 7, 2025
310024b
added some more tests for code coverage
haneric00 Aug 7, 2025
373afcb
added some more tests and added skipping for one existing failing tes…
haneric00 Aug 7, 2025
a0f7622
silly mistake, missing import os
haneric00 Aug 7, 2025
8fea513
added version reqs to dev reqs
haneric00 Aug 7, 2025
a606ec9
changed botocore version because linter is failing to resolve depende…
haneric00 Aug 7, 2025
b347ff8
fixing dev requirements and pyproject inconsistencies (deleting unnec…
haneric00 Aug 7, 2025
5578c2f
deleted an unecessary pyproject.toml
haneric00 Aug 7, 2025
e325abf
deleted unused test files and hopefully correctly added the command t…
haneric00 Aug 7, 2025
3a08423
hopefully modified to skip my long line correctly
haneric00 Aug 7, 2025
cadd51b
formatted for linter
haneric00 Aug 7, 2025
1071ac7
fixed according to linter
haneric00 Aug 7, 2025
a7b929a
changed var names according to linter
haneric00 Aug 7, 2025
5ac2d75
skipping langgraph test file due to pylint recursion issue
haneric00 Aug 7, 2025
b44a041
refactored file format of langchain instrumentor, addressed PR commen…
haneric00 Aug 12, 2025
d38ade7
delete commented out imports
haneric00 Aug 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions aws-opentelemetry-distro/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ dependencies = [
"opentelemetry-instrumentation-urllib3 == 0.54b1",
"opentelemetry-instrumentation-wsgi == 0.54b1",
"opentelemetry-instrumentation-cassandra == 0.54b1",
"langchain == 0.3.27",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not need some of these dependencies here.

For example, why do we need duckduckgo-search?

"langchain-core == 0.3.72",
"langchain-aws == 0.2.15",
"langchain-community == 0.3.27",
"langgraph == 0.6.3",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For instrumentation libraries, we normally don't add dependencies for the library we're instrumenting directly. For example, see the pyproject.toml in the upstream instrumentor.

The reason for this is because we only want to instrument a customer's library if they have it installed. Otherwise, our instrumentation logic will just not run.

"duckduckgo-search == 8.1.1",
"pytest-asyncio == 0.21.0",
"pytest-vcr == 1.0.2",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should add these in the main dependencies since they are just for testing. For example, we don't like pytest here either.

]

[project.optional-dependencies]
Expand All @@ -95,6 +103,9 @@ test = []
[project.entry-points.opentelemetry_configurator]
aws_configurator = "amazon.opentelemetry.distro.aws_opentelemetry_configurator:AwsOpenTelemetryConfigurator"

[project.entry-points.opentelemetry_instrumentor]
langchain = "amazon.opentelemetry.distro.instrumentation.mcp.instrumentation:McpInstrumentor"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo?

amazon.opentelemetry.distro.instrumentation.mcp.instrumentation:McpInstrumentor

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, thanks for looking


[project.entry-points.opentelemetry_distro]
aws_distro = "amazon.opentelemetry.distro.aws_opentelemetry_distro:AwsOpenTelemetryDistro"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# pylint: disable=no-self-use

from typing import Collection

from wrapt import wrap_function_wrapper

from amazon.opentelemetry.distro.opentelemetry.instrumentation.langchain_v2.callback_handler import (
OpenTelemetryCallbackHandler,
)
from amazon.opentelemetry.distro.opentelemetry.instrumentation.langchain_v2.version import __version__
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
from opentelemetry.instrumentation.utils import unwrap
from opentelemetry.trace import get_tracer

__all__ = ["OpenTelemetryCallbackHandler"]

_instruments = ("langchain >= 0.1.0",)


class LangChainInstrumentor(BaseInstrumentor):

def instrumentation_dependencies(self) -> Collection[str]:
return _instruments

def _instrument(self, **kwargs):
tracer_provider = kwargs.get("tracer_provider")
tracer = get_tracer(__name__, __version__, tracer_provider)

otel_callback_handler = OpenTelemetryCallbackHandler(tracer)

wrap_function_wrapper(
module="langchain_core.callbacks",
name="BaseCallbackManager.__init__",
wrapper=_BaseCallbackManagerInitWrapper(otel_callback_handler),
)

def _uninstrument(self, **kwargs):
unwrap("langchain_core.callbacks", "BaseCallbackManager.__init__")
if hasattr(self, "_wrapped"):
for module, name in self._wrapped:
unwrap(module, name)
self.handler = None


class _BaseCallbackManagerInitWrapper:
def __init__(self, callback_handler: "OpenTelemetryCallbackHandler"):
self.callback_handler = callback_handler
self._wrapped = []

def __call__(
self,
wrapped,
instance,
args,
kwargs,
) -> None:
wrapped(*args, **kwargs)
for handler in instance.inheritable_handlers:
if isinstance(handler, OpenTelemetryCallbackHandler):
return None

instance.add_handler(self.callback_handler, True)
return None
Loading
Loading