Skip to content

Conversation

wrisa
Copy link
Owner

@wrisa wrisa commented Jun 17, 2025

Description

Instrument langchain invoking ChatOpenAI client. Produces spans, metrics and events.
Added tests for the same.

Note: some attributes string literals need addition to semcov.

Fixes # (issue)

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

  • Test A

Does This PR Require a Core Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

Copy link
Collaborator

@keith-decker keith-decker left a comment

Choose a reason for hiding this comment

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

Just some minor formatting issues for Google Python compliance.

I'm not sure how strict the reviewers will be on the Python for google compliance, but if they are, we'll have to update doc strings to match, and add return type annotations to all functions.

# See the License for the specific language governing permissions and
# limitations under the License.

__version__ = "0.0.1" No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

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

Files should have a newline at the end

span.set_attribute(
ErrorAttributes.ERROR_TYPE, type(error).__qualname__
)
self._end_span(run_id) No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

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

Files should have a newline at the end

TraceContextTextMapPropagator().inject(extra_headers, context=ctx)
kwargs["extra_headers"] = extra_headers

return wrapped(*args, **kwargs) No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

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

Files should have a newline at the end


python-dotenv[cli]

# For local development: `pip install -e /path/to/opentelemetry-instrumentation-langchain` No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

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

Files should have a newline at the end

LangChainInstrumentor().uninstrument()

if __name__ == "__main__":
main() No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

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

Files should have a newline at the end

# Change to 'false' to hide prompt and completion content
OTEL_INSTRUMENTATION_LANGCHAIN_CAPTURE_MESSAGE_CONTENT=true

OTEL_SERVICE_NAME=opentelemetry-python-langchain No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

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

Files should have a newline at the end

# Change to 'false' to hide prompt and completion content
OTEL_INSTRUMENTATION_LANGCHAIN_CAPTURE_MESSAGE_CONTENT=true

OTEL_SERVICE_NAME=opentelemetry-python-langchain No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

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

Files should have a newline at the end

from langchain_core.messages import HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI

import pytest
Copy link
Collaborator

Choose a reason for hiding this comment

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

Imports should be core first, then packages, then local

@pmcollins
Copy link

Hi Ridhima, thank you for taking this on. Some overall thoughts:

This PR is large at 24 files and 1700 lines, which is great because it's got lots of functionality needed by customers, but larger PRs are harder to review. Should we try to make it smaller? What are some strategies to do so? We could use this diff as a reference and build a from-scratch implementation in small increments.

However, because this PR is open against a fork of the upstream Contrib repo, if we go with an incremental approach, after we fine-tune, approve, and merge our small PRs against this fork, we're going to be almost back to square one, because our final implementation will need to get offered upstream as a PR to the original Contrib repo. And now we have to either attempt to get a large PR reviewed and merged in a timely manner, or upstream Contrib will ask us to break our diff into multiple small PRs again.

What do you think?


return span

def _end_span(self, run_id: UUID):

Choose a reason for hiding this comment

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

When I run this instrumentor locally, I don't see telemetry. I am seeing it start spans, but it doesn't end them -- this method never gets called for me.

@wrisa
Copy link
Owner Author

wrisa commented Jun 24, 2025

@pmcollins thanks for taking a look and providing your suggestions.
This change set has 2 types of files, project required base files(readme, pyproject.toml,. etc), instrumentation(span, metric and logs) and supporting utils.
To reduce the code size for reviews, I think of following 2 strategies,
Approach 1, we can create 4 PRs,
PR 1 - project files only
PR 2 - span support, split in one more PR for trace header injection functionality support
PR 3 - metrics support
PR 4 - logs support
Approach 2, we can have 3 PRs,
PR1 - project files with some functionality like logs support(less number of code lines than metrics code and span code)
PR2 - Metrics support
PR 3 - Span support, split in one more PR for trace header injection functionality support

Also what is recommended, PRs against fork or against actual repo? If former, can we merge one PR at a time all the way to upstream ?

@pmcollins
Copy link

Either one is fine with me -- as a reviewer I prefer a larger number of smaller PRs, so I would lean towards the first approach 😉. We can play it by ear.

We can review and merge code here against your fork to experiment and discuss ideas, but eventually we're going to have to open PRs against upstream Contrib. As you suggest, we could start with a skeletal PR of just the minimal project files, and open it against upstream Contrib. (I've never created a new instrumentation so it will be a learning experience for me as well.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants