Coverage for langsmith/_internal/otel/_otel_client.py: 17%
36 statements
« prev ^ index » next coverage.py v7.10.1, created at 2025-12-11 16:15 -0800
« prev ^ index » next coverage.py v7.10.1, created at 2025-12-11 16:15 -0800
1"""Client configuration for OpenTelemetry integration with LangSmith."""
3import os
4import warnings
5from typing import TYPE_CHECKING
7if TYPE_CHECKING:
8 try:
9 from opentelemetry.sdk.trace import TracerProvider # type: ignore[import]
10 except ImportError:
11 TracerProvider = object # type: ignore[assignment, misc]
13from langsmith import utils as ls_utils
16def _import_otel_client():
17 """Dynamically import OTEL client modules when needed."""
18 try:
19 from opentelemetry.exporter.otlp.proto.http.trace_exporter import ( # type: ignore[import]
20 OTLPSpanExporter,
21 )
22 from opentelemetry.sdk.resources import ( # type: ignore[import]
23 SERVICE_NAME,
24 Resource,
25 )
26 from opentelemetry.sdk.trace import TracerProvider # type: ignore[import]
27 from opentelemetry.sdk.trace.export import ( # type: ignore[import]
28 BatchSpanProcessor,
29 )
31 return (
32 OTLPSpanExporter,
33 SERVICE_NAME,
34 Resource,
35 TracerProvider,
36 BatchSpanProcessor,
37 )
38 except ImportError as e:
39 warnings.warn(
40 f"OTEL_ENABLED is set but OpenTelemetry packages are not installed: {e}"
41 )
42 return None
45def get_otlp_tracer_provider() -> "TracerProvider":
46 """Get the OTLP tracer provider for LangSmith.
48 This function creates a tracer provider that exports spans using the OTLP protocol
49 with LangSmith-specific defaults:
51 - OTEL_EXPORTER_OTLP_ENDPOINT: https://api.smith.langchain.com/otel
52 - OTEL_EXPORTER_OTLP_HEADERS: Contains x-api-key from LangSmith API key and
53 Langsmith-Project header if project is configured
55 These defaults can be overridden by setting the environment variables before
56 calling this function.
58 Returns:
59 TracerProvider: The OTLP tracer provider.
60 """
61 # Import OTEL modules dynamically
62 otel_imports = _import_otel_client()
63 if otel_imports is None:
64 raise ImportError(
65 "OpenTelemetry packages are required to use this function. "
66 "Please install with `pip install langsmith[otel]`"
67 )
68 (
69 OTLPSpanExporter,
70 SERVICE_NAME,
71 Resource,
72 TracerProvider,
73 BatchSpanProcessor,
74 ) = otel_imports
76 if "OTEL_EXPORTER_OTLP_ENDPOINT" not in os.environ:
77 ls_endpoint = ls_utils.get_api_url(None)
78 os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = f"{ls_endpoint}/otel"
80 # Configure headers with API key and project if available
81 if "OTEL_EXPORTER_OTLP_HEADERS" not in os.environ:
82 api_key = ls_utils.get_api_key(None)
83 headers = f"x-api-key={api_key}"
85 project = ls_utils.get_tracer_project()
86 if project:
87 headers += f",Langsmith-Project={project}"
89 os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = headers
91 service_name = os.environ.get("OTEL_SERVICE_NAME", "langsmith")
92 resource = Resource(
93 attributes={
94 SERVICE_NAME: service_name,
95 # Marker to identify LangSmith's internal provider
96 "langsmith.internal_provider": True,
97 }
98 )
100 tracer_provider = TracerProvider(resource=resource)
102 otlp_exporter = OTLPSpanExporter()
103 span_processor = BatchSpanProcessor(otlp_exporter)
104 tracer_provider.add_span_processor(span_processor)
106 return tracer_provider