Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
448898a
Port OTEL to JS
jacoblee93 Jun 23, 2025
cebcdc2
Implement in traceable
jacoblee93 Jun 23, 2025
5c0be2f
Fix tests
jacoblee93 Jun 23, 2025
24ff81c
Implement OTEL translator and client, plumb into traceable
jacoblee93 Jun 25, 2025
8cfaac6
More progress
jacoblee93 Jun 25, 2025
a6d3458
Progress
jacoblee93 Jun 26, 2025
7e6247e
Simplify by creating span in traceable directly
jacoblee93 Jun 26, 2025
ba9fa3f
Refactor
jacoblee93 Jun 26, 2025
fa639f3
Fix lint
jacoblee93 Jun 26, 2025
cd9570b
Split out OTEL deps
jacoblee93 Jun 26, 2025
b1cb3c9
remove unused
jacoblee93 Jun 26, 2025
dc8ffbe
Merge branch 'main' of github.com:langchain-ai/langsmith-sdk into jac…
jacoblee93 Jun 26, 2025
fa549b4
Isolate types
jacoblee93 Jun 26, 2025
2894cb7
Fix deps
jacoblee93 Jun 26, 2025
c4a2fa9
Lint
jacoblee93 Jun 26, 2025
5de6792
Add entrypoint
jacoblee93 Jun 26, 2025
d7d12af
Format
jacoblee93 Jun 26, 2025
428ca53
Fix awaitPendingTraceBatches()
jacoblee93 Jun 26, 2025
70724bc
Don't use LangSmith exporter if tracing is disabled, adds more tests
jacoblee93 Jun 26, 2025
c0e7d13
Fix build
jacoblee93 Jun 26, 2025
6210c51
Remove unused import
jacoblee93 Jun 26, 2025
5d77bc4
Fix
jacoblee93 Jun 26, 2025
738998a
Call result callback if tracing is not enabled
jacoblee93 Jun 26, 2025
ade8a9a
Avoid populating span map with already ended spans
jacoblee93 Jun 27, 2025
d5b7a10
Simplify logic and setup
jacoblee93 Jun 28, 2025
1215e92
Export defaults
jacoblee93 Jun 28, 2025
dc563e8
Names
jacoblee93 Jun 28, 2025
96ffde6
Make setup code imperative, move defaults into exporter
jacoblee93 Jun 29, 2025
bc434a7
Add docstring
jacoblee93 Jun 29, 2025
86f67ab
Update docstring
jacoblee93 Jun 29, 2025
bf67dfb
Allow passing in a context manager on setup
jacoblee93 Jun 30, 2025
ddc8582
Merge branch 'main' of github.com:langchain-ai/langsmith-sdk into jac…
jacoblee93 Jun 30, 2025
31104e8
Version bump
jacoblee93 Jun 30, 2025
c20d305
Add extra check for OTEL
jacoblee93 Jun 30, 2025
159c029
Fix
jacoblee93 Jun 30, 2025
57daafc
Remove unused method
jacoblee93 Jun 30, 2025
1cf3d53
Fix lint
jacoblee93 Jun 30, 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
5 changes: 4 additions & 1 deletion js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@
"zod": "^3.23.8"
},
"peerDependencies": {
"openai": "*"
"openai": "*",
"@opentelemetry/api": "^1.9.0",
Comment thread
jacoblee93 marked this conversation as resolved.
Outdated
"@opentelemetry/exporter-trace-otlp-proto": "^0.202.0",
"@opentelemetry/sdk-trace-base": "^2.0.1"
},
"peerDependenciesMeta": {
"openai": {
Expand Down
1 change: 1 addition & 0 deletions js/src/_internal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./otel/index.js";
85 changes: 85 additions & 0 deletions js/src/_internal/otel/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { type TracerProvider as OTELTracerProvider } from "@opentelemetry/api";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
import {
BatchSpanProcessor,
BasicTracerProvider,
} from "@opentelemetry/sdk-trace-base";

import {
getEnvironmentVariable,
setEnvironmentVariable,
} from "../../utils/env.js";

const HAS_OTEL = getEnvironmentVariable("OTEL_ENABLED") === "true";

/**
* Convert headers string in format "name=value,name2=value2" to object
*/
function parseHeadersString(headersStr: string): Record<string, string> {
const headers: Record<string, string> = {};
if (!headersStr) return headers;

headersStr.split(",").forEach((pair) => {
const [name, ...valueParts] = pair.split("=");
if (name && valueParts.length > 0) {
headers[name.trim()] = valueParts.join("=").trim();
}
});

return headers;
}

export function getOTLPTracerProvider(): OTELTracerProvider {
if (!HAS_OTEL) {
Comment thread
jacoblee93 marked this conversation as resolved.
Outdated
throw new Error(
"OpenTelemetry packages are required to use this function. " +
"Please install the required OpenTelemetry packages."
);
}

// Set LangSmith-specific defaults if not already set in environment
if (!getEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")) {
const lsEndpoint =
getEnvironmentVariable("LANGSMITH_ENDPOINT") ||
getEnvironmentVariable("LANGCHAIN_ENDPOINT") ||
"https://api.smith.langchain.com";
setEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT", `${lsEndpoint}/otel`);
}

// Configure headers with API key and project if available
if (!getEnvironmentVariable("OTEL_EXPORTER_OTLP_HEADERS")) {
const apiKey =
getEnvironmentVariable("LANGSMITH_API_KEY") ||
getEnvironmentVariable("LANGCHAIN_API_KEY");

if (!apiKey) {
throw new Error(
"LANGSMITH_API_KEY or LANGCHAIN_API_KEY environment variable is required"
);
}

let headers = `x-api-key=${apiKey}`;

const project =
getEnvironmentVariable("LANGSMITH_PROJECT") ||
getEnvironmentVariable("LANGCHAIN_PROJECT");
if (project) {
headers += `,Langsmith-Project=${project}`;
}

setEnvironmentVariable("OTEL_EXPORTER_OTLP_HEADERS", headers);
}

const headersStr = getEnvironmentVariable("OTEL_EXPORTER_OTLP_HEADERS") || "";
const headersObj = parseHeadersString(headersStr);

const langsmithSpanExporter = new OTLPTraceExporter({
url: getEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT"),
headers: headersObj,
});
const spanProcessor = new BatchSpanProcessor(langsmithSpanExporter);

return new BasicTracerProvider({
spanProcessors: [spanProcessor],
});
}
3 changes: 3 additions & 0 deletions js/src/_internal/otel/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./client.js";
export * from "./translator.js";
export * from "./utils.js";
Loading
Loading