From b9e6bae5c9630331f11a881aa703053b1d6e0b53 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 01:47:00 +0000 Subject: [PATCH 1/2] feat: Add Google Cloud destination support This commit adds support for the Google Cloud destination of OpenLLMetry JS. - Adds the `@google-cloud/opentelemetry-cloud-trace-exporter` dependency. - Modifies the `InitializeOptions` interface to include a `gcpProjectId` property. - Updates the tracing initialization logic to use the Google Cloud exporter when a `gcpProjectId` is provided. --- packages/traceloop-sdk/package.json | 1 + .../initialize-options.interface.ts | 6 + .../traceloop-sdk/src/lib/tracing/index.ts | 11 +- pnpm-lock.yaml | 160 ++++++++++++++++++ 4 files changed, 174 insertions(+), 4 deletions(-) diff --git a/packages/traceloop-sdk/package.json b/packages/traceloop-sdk/package.json index 26d24fbb..cc72088a 100644 --- a/packages/traceloop-sdk/package.json +++ b/packages/traceloop-sdk/package.json @@ -75,6 +75,7 @@ "@traceloop/instrumentation-pinecone": "workspace:*", "@traceloop/instrumentation-qdrant": "workspace:*", "@traceloop/instrumentation-together": "workspace:*", + "@google-cloud/opentelemetry-cloud-trace-exporter": "^1.0.0", "@traceloop/instrumentation-vertexai": "workspace:*", "@types/nunjucks": "^3.2.6", "cross-fetch": "^4.1.0", diff --git a/packages/traceloop-sdk/src/lib/interfaces/initialize-options.interface.ts b/packages/traceloop-sdk/src/lib/interfaces/initialize-options.interface.ts index e6ce6c22..ebac023e 100644 --- a/packages/traceloop-sdk/src/lib/interfaces/initialize-options.interface.ts +++ b/packages/traceloop-sdk/src/lib/interfaces/initialize-options.interface.ts @@ -141,4 +141,10 @@ export interface InitializeOptions { * Defaults to the TRACELOOP_EXP_SLUG environment variable. */ experimentSlug?: string; + + /** + * The Google Cloud Project ID for sending traces data. Optional. + * This is used to configure the Google Cloud Trace Exporter. + */ + gcpProjectId?: string; } diff --git a/packages/traceloop-sdk/src/lib/tracing/index.ts b/packages/traceloop-sdk/src/lib/tracing/index.ts index 986e15d9..c705796e 100644 --- a/packages/traceloop-sdk/src/lib/tracing/index.ts +++ b/packages/traceloop-sdk/src/lib/tracing/index.ts @@ -2,6 +2,7 @@ import { NodeSDK } from "@opentelemetry/sdk-node"; import { SpanProcessor } from "@opentelemetry/sdk-trace-node"; import { context, diag } from "@opentelemetry/api"; import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto"; +import { TraceExporter as GcpTraceExporter } from "@google-cloud/opentelemetry-cloud-trace-exporter"; import { Resource } from "@opentelemetry/resources"; import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions"; import { Instrumentation } from "@opentelemetry/instrumentation"; @@ -286,10 +287,12 @@ export const startTracing = (options: InitializeOptions) => { const traceExporter = options.exporter ?? - new OTLPTraceExporter({ - url: `${options.baseUrl}/v1/traces`, - headers, - }); + (options.gcpProjectId + ? new GcpTraceExporter({ projectId: options.gcpProjectId }) + : new OTLPTraceExporter({ + url: `${options.baseUrl}/v1/traces`, + headers, + })); _spanProcessor = createSpanProcessor({ apiKey: options.apiKey, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6dacfb9..a571d4f4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -758,6 +758,9 @@ importers: packages/traceloop-sdk: dependencies: + '@google-cloud/opentelemetry-cloud-trace-exporter': + specifier: ^1.0.0 + version: 1.2.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.36.0)(encoding@0.1.13)(supports-color@10.0.0) '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.0 @@ -2067,6 +2070,22 @@ packages: resolution: {integrity: sha512-7Bmh3kkM+pSiHfoHM/RwsA23I4ISjkwxiPw4XXuw8IfmINsmpKCL5eTMSOFHImOi02dCrDfIMCTLPNwhXkuuTA==} engines: {node: '>=18'} + '@google-cloud/opentelemetry-cloud-trace-exporter@1.2.0': + resolution: {integrity: sha512-73rikv8RTZmQvLwCREPceFVG/H2KyWMF3ggj7nBLR4RJwn+ZBQTaZ2A4d+hVU4M8+d7A9LApqG33ZfGk7lnQDQ==} + engines: {node: '>=10'} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + '@opentelemetry/core': ^1.0.0 + '@opentelemetry/resources': ^1.0.0 + '@opentelemetry/sdk-trace-base': ^1.0.0 + + '@google-cloud/opentelemetry-resource-util@1.2.0': + resolution: {integrity: sha512-1NCk5o4mJEMgeJaCjffwAsbdrfRepFJ0ZbfSQ3eS4IyqnUZn5wyX027xtk7lNy0RBJF7lyhQwxtN7sSbtvp+YA==} + engines: {node: '>=10'} + peerDependencies: + '@opentelemetry/resources': ^1.0.0 + '@opentelemetry/semantic-conventions': ^1.0.0 + '@google-cloud/vertexai@1.10.0': resolution: {integrity: sha512-HqYqoivNtkq59po8m7KI0n+lWKdz4kabENncYQXZCX/hBWJfXtKAfR/2nUQsP+TwSfHKoA7zDL2RrJYIv/j3VQ==} engines: {node: '>=18.0.0'} @@ -5158,6 +5177,9 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-text-encoding@1.0.6: + resolution: {integrity: sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==} + fast-uri@3.0.6: resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} @@ -5340,6 +5362,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gaxios@4.3.3: + resolution: {integrity: sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==} + engines: {node: '>=10'} + gaxios@6.7.1: resolution: {integrity: sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==} engines: {node: '>=14'} @@ -5348,6 +5374,10 @@ packages: resolution: {integrity: sha512-Odju3uBUJyVCkW64nLD4wKLhbh93bh6vIg/ZIXkWiLPBrdgtc65+tls/qml+un3pr6JqYVFDZbbmLDQT68rTOQ==} engines: {node: '>=18'} + gcp-metadata@4.3.1: + resolution: {integrity: sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==} + engines: {node: '>=10'} + gcp-metadata@6.1.1: resolution: {integrity: sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==} engines: {node: '>=14'} @@ -5469,6 +5499,10 @@ packages: resolution: {integrity: sha512-GspVjZj1RbyRWpQ9FbAXMKjFGzZwDKnUHi66JJ+tcjcu5/xYAP1pdlWotCuIkMwjfVsxxDvsGZXGLzRt72D0sQ==} engines: {node: '>=18'} + google-auth-library@7.14.1: + resolution: {integrity: sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==} + engines: {node: '>=10'} + google-auth-library@9.15.1: resolution: {integrity: sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==} engines: {node: '>=14'} @@ -5489,6 +5523,16 @@ packages: resolution: {integrity: sha512-rcX58I7nqpu4mbKztFeOAObbomBbHU2oIb/d3tJfF3dizGSApqtSwYJigGCooHdnMyQBIw8BrWyK96w3YXgr6A==} engines: {node: '>=14'} + google-p12-pem@3.1.4: + resolution: {integrity: sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==} + engines: {node: '>=10'} + deprecated: Package is no longer maintained + hasBin: true + + google-proto-files@2.5.2: + resolution: {integrity: sha512-++IfDghgAWRk2Hz3KJ8qMtLkXxrY8QlhyBjMYoNieGlYKcGyWZ5J26S9Zk8dCnVRt9NBcYSYg6GfQCrpmfNeJg==} + engines: {node: '>=10'} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -5508,6 +5552,10 @@ packages: resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + gtoken@5.3.2: + resolution: {integrity: sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==} + engines: {node: '>=10'} + gtoken@7.1.0: resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==} engines: {node: '>=14.0.0'} @@ -6198,6 +6246,9 @@ packages: resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} engines: {node: '>= 0.6.0'} + long@4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + long@5.3.2: resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} @@ -6491,6 +6542,10 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + node-gyp-build@4.8.4: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true @@ -7054,6 +7109,10 @@ packages: resolution: {integrity: sha512-Rug90pDIefARAG9MgaFjd0yR/YP4bN3Fov00kckXMjTZa0x86c4WoWfCQFdSeWi9DvRXjhfLlPDIvODB5LOTfg==} engines: {node: '>=18'} + protobufjs@6.11.4: + resolution: {integrity: sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==} + hasBin: true + protobufjs@7.5.3: resolution: {integrity: sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==} engines: {node: '>=12.0.0'} @@ -7903,6 +7962,10 @@ packages: walk-up-path@3.0.1: resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + walkdir@0.4.1: + resolution: {integrity: sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==} + engines: {node: '>=6.0.0'} + wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} @@ -9909,6 +9972,27 @@ snapshots: transitivePeerDependencies: - supports-color + '@google-cloud/opentelemetry-cloud-trace-exporter@1.2.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.36.0)(encoding@0.1.13)(supports-color@10.0.0)': + dependencies: + '@google-cloud/opentelemetry-resource-util': 1.2.0(@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.36.0) + '@grpc/grpc-js': 1.13.4 + '@grpc/proto-loader': 0.7.15 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + google-auth-library: 7.14.1(encoding@0.1.13)(supports-color@10.0.0) + google-proto-files: 2.5.2 + transitivePeerDependencies: + - '@opentelemetry/semantic-conventions' + - encoding + - supports-color + + '@google-cloud/opentelemetry-resource-util@1.2.0(@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.36.0)': + dependencies: + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.36.0 + '@google-cloud/vertexai@1.10.0(encoding@0.1.13)(supports-color@10.0.0)': dependencies: google-auth-library: 9.15.1(encoding@0.1.13)(supports-color@10.0.0) @@ -13405,6 +13489,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-text-encoding@1.0.6: {} + fast-uri@3.0.6: {} fast-xml-parser@5.2.5: @@ -13602,6 +13688,17 @@ snapshots: function-bind@1.1.2: {} + gaxios@4.3.3(encoding@0.1.13)(supports-color@10.0.0): + dependencies: + abort-controller: 3.0.0 + extend: 3.0.2 + https-proxy-agent: 5.0.1(supports-color@10.0.0) + is-stream: 2.0.1 + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + - supports-color + gaxios@6.7.1(encoding@0.1.13)(supports-color@10.0.0): dependencies: extend: 3.0.2 @@ -13621,6 +13718,14 @@ snapshots: transitivePeerDependencies: - supports-color + gcp-metadata@4.3.1(encoding@0.1.13)(supports-color@10.0.0): + dependencies: + gaxios: 4.3.3(encoding@0.1.13)(supports-color@10.0.0) + json-bigint: 1.0.0 + transitivePeerDependencies: + - encoding + - supports-color + gcp-metadata@6.1.1(encoding@0.1.13)(supports-color@10.0.0): dependencies: gaxios: 6.7.1(encoding@0.1.13)(supports-color@10.0.0) @@ -13785,6 +13890,21 @@ snapshots: transitivePeerDependencies: - supports-color + google-auth-library@7.14.1(encoding@0.1.13)(supports-color@10.0.0): + dependencies: + arrify: 2.0.1 + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + fast-text-encoding: 1.0.6 + gaxios: 4.3.3(encoding@0.1.13)(supports-color@10.0.0) + gcp-metadata: 4.3.1(encoding@0.1.13)(supports-color@10.0.0) + gtoken: 5.3.2(encoding@0.1.13)(supports-color@10.0.0) + jws: 4.0.0 + lru-cache: 6.0.0 + transitivePeerDependencies: + - encoding + - supports-color + google-auth-library@9.15.1(encoding@0.1.13)(supports-color@10.0.0): dependencies: base64-js: 1.5.1 @@ -13835,6 +13955,15 @@ snapshots: google-logging-utils@1.1.1: {} + google-p12-pem@3.1.4: + dependencies: + node-forge: 1.3.1 + + google-proto-files@2.5.2: + dependencies: + protobufjs: 6.11.4 + walkdir: 0.4.1 + gopd@1.2.0: {} graceful-fs@4.2.11: {} @@ -13851,6 +13980,15 @@ snapshots: graphql@16.11.0: {} + gtoken@5.3.2(encoding@0.1.13)(supports-color@10.0.0): + dependencies: + gaxios: 4.3.3(encoding@0.1.13)(supports-color@10.0.0) + google-p12-pem: 3.1.4 + jws: 4.0.0 + transitivePeerDependencies: + - encoding + - supports-color + gtoken@7.1.0(encoding@0.1.13)(supports-color@10.0.0): dependencies: gaxios: 6.7.1(encoding@0.1.13)(supports-color@10.0.0) @@ -14703,6 +14841,8 @@ snapshots: loglevel@1.9.2: {} + long@4.0.0: {} + long@5.3.2: {} longest@2.0.1: {} @@ -14996,6 +15136,8 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + node-forge@1.3.1: {} + node-gyp-build@4.8.4: {} node-gyp@10.3.1: @@ -15688,6 +15830,22 @@ snapshots: dependencies: protobufjs: 7.5.3 + protobufjs@6.11.4: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.2 + '@types/node': 24.0.15 + long: 4.0.0 + protobufjs@7.5.3: dependencies: '@protobufjs/aspromise': 1.1.2 @@ -16571,6 +16729,8 @@ snapshots: walk-up-path@3.0.1: {} + walkdir@0.4.1: {} + wcwidth@1.0.1: dependencies: defaults: 1.0.4 From a6af3acfb6c9cd330a60d0cda3181ef088a5e837 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 04:47:44 +0000 Subject: [PATCH 2/2] feat: Add Google Cloud destination support This commit adds support for the Google Cloud destination of OpenLLMetry JS. - Adds the `@google-cloud/opentelemetry-cloud-trace-exporter` dependency. - Modifies the `InitializeOptions` interface to include a `gcpProjectId` property. - Updates the tracing initialization logic to use the Google Cloud exporter when a `gcpProjectId` is provided. - Fixes a bug where the OTLP exporter was not using the computed `baseUrl`. --- packages/traceloop-sdk/src/lib/tracing/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/traceloop-sdk/src/lib/tracing/index.ts b/packages/traceloop-sdk/src/lib/tracing/index.ts index c705796e..33981be6 100644 --- a/packages/traceloop-sdk/src/lib/tracing/index.ts +++ b/packages/traceloop-sdk/src/lib/tracing/index.ts @@ -290,7 +290,7 @@ export const startTracing = (options: InitializeOptions) => { (options.gcpProjectId ? new GcpTraceExporter({ projectId: options.gcpProjectId }) : new OTLPTraceExporter({ - url: `${options.baseUrl}/v1/traces`, + url: `${baseUrl}/v1/traces`, headers, }));