[PRO-973] basic o11y around anthropic api calls (#22)

add some otel initialization, pointing at honeycomb + a function to wrap other functions with spans.  use that function to wrap `callAnthropic` and add some context (number of messages sent, token usage, along with some metadata should we ever support other providers.)

The honeycomb api key/dataset are to be passed via env vars `HONEYCOMB_API_KEY` and `HONEYCOMB_DATASET` respectively.
This commit is contained in:
Chris Toshok 2025-02-18 10:06:20 -08:00 committed by GitHub
parent 20bb97c0c5
commit af4c405620
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 443 additions and 42 deletions

View File

@ -55,7 +55,7 @@ TOGETHER_API_KEY=
#Get your Hyperbolics API Key at https://app.hyperbolic.xyz/settings
#baseURL="https://api.hyperbolic.xyz/v1/chat/completions"
HYPERBOLIC_API_KEY=
HYPERBOLIC_API_BASE_URL=
HYPERBOLIC_API_BASE_URL=
# Get your Mistral API Key by following these instructions -
# https://console.mistral.ai/api-keys/
@ -78,7 +78,7 @@ LMSTUDIO_API_BASE_URL=
# You only need this environment variable set if you want to use xAI models
XAI_API_KEY=
# Get your Perplexity API Key here -
# Get your Perplexity API Key here -
# https://www.perplexity.ai/settings/api
# You only need this environment variable set if you want to use Perplexity models
PERPLEXITY_API_KEY=
@ -98,9 +98,13 @@ AWS_BEDROCK_CONFIG=
VITE_LOG_LEVEL=debug
# Example Context Values for qwen2.5-coder:32b
#
#
# DEFAULT_NUM_CTX=32768 # Consumes 36GB of VRAM
# DEFAULT_NUM_CTX=24576 # Consumes 32GB of VRAM
# DEFAULT_NUM_CTX=12288 # Consumes 26GB of VRAM
# DEFAULT_NUM_CTX=6144 # Consumes 24GB of VRAM
DEFAULT_NUM_CTX=
# set these to enable opentelemetry
HONEYCOMB_API_KEY=
HONEYCOMB_DATASET=

View File

@ -5,7 +5,9 @@ import type { ContentBlockParam, MessageParam } from "@anthropic-ai/sdk/resource
import type { FileMap } from "./stream-text";
import { StreamingMessageParser } from "~/lib/runtime/message-parser";
import { extractRelativePath } from "~/utils/diff";
import { wrapWithSpan, getCurrentSpan } from "~/lib/.server/otel";
const Model = "claude-3-5-sonnet-20241022";
const MaxMessageTokens = 8192;
function convertContentToAnthropic(content: any): ContentBlockParam[] {
@ -47,52 +49,78 @@ export interface AnthropicCall {
promptTokens: number;
}
async function callAnthropic(apiKey: string, systemPrompt: string, messages: MessageParam[]): Promise<AnthropicCall> {
const anthropic = new Anthropic({ apiKey });
const callAnthropic = wrapWithSpan(
{
name: "llm-call",
attrs: {
"llm.provider": "anthropic",
"llm.model": Model,
},
},
console.log("************************************************");
console.log("AnthropicMessageSend");
console.log("Message system:");
console.log(systemPrompt);
for (const message of messages) {
console.log(`Message ${message.role}:`);
console.log(flatMessageContent(message.content));
}
console.log("************************************************");
// eslint-disable-next-line prefer-arrow-callback
async function callAnthropic(apiKey: string, systemPrompt: string, messages: MessageParam[]): Promise<AnthropicCall> {
const span = getCurrentSpan();
span?.setAttributes({
"llm.chat.calls": 1, // so we can SUM(llm.chat.calls) without doing a COUNT + filter
"llm.chat.num_messages": messages.length,
});
const response = await anthropic.messages.create({
model: "claude-3-5-sonnet-20241022",
messages,
max_tokens: MaxMessageTokens,
system: systemPrompt,
});
const anthropic = new Anthropic({ apiKey });
let responseText = "";
for (const content of response.content) {
if (content.type === "text") {
responseText += content.text;
} else {
console.log("AnthropicUnknownResponse", JSON.stringify(content, null, 2));
console.log("************************************************");
console.log("AnthropicMessageSend");
console.log("Message system:");
console.log(systemPrompt);
for (const message of messages) {
console.log(`Message ${message.role}:`);
console.log(flatMessageContent(message.content));
}
}
console.log("************************************************");
const completionTokens = response.usage.output_tokens;
const promptTokens = response.usage.input_tokens;
const response = await anthropic.messages.create({
model: "claude-3-5-sonnet-20241022",
messages,
max_tokens: MaxMessageTokens,
system: systemPrompt,
});
console.log("************************************************");
console.log("AnthropicMessageResponse:");
console.log(responseText);
console.log("AnthropicTokens", completionTokens + promptTokens);
console.log("************************************************");
let responseText = "";
for (const content of response.content) {
if (content.type === "text") {
responseText += content.text;
} else {
console.log("AnthropicUnknownResponse", JSON.stringify(content, null, 2));
}
}
return {
systemPrompt,
messages,
responseText,
completionTokens,
promptTokens,
};
}
const completionTokens = response.usage.output_tokens;
const promptTokens = response.usage.input_tokens;
span?.setAttributes({
"llm.chat.prompt_tokens": promptTokens,
"llm.chat.completion_tokens": completionTokens,
// to save us needing to worry about a derived column
"llm.chat.total_tokens": completionTokens + promptTokens,
});
console.log("************************************************");
console.log("AnthropicMessageResponse:");
console.log(responseText);
console.log("AnthropicTokens", completionTokens + promptTokens);
console.log("************************************************");
return {
systemPrompt,
messages,
responseText,
completionTokens,
promptTokens,
};
},
);
function getFileContents(files: FileMap, path: string): string {
for (const [filePath, file] of Object.entries(files)) {

98
app/lib/.server/otel.ts Normal file
View File

@ -0,0 +1,98 @@
import { Resource } from '@opentelemetry/resources';
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { ZoneContextManager } from '@opentelemetry/context-zone';
import { SpanStatusCode, type Attributes, context, trace } from '@opentelemetry/api';
function initializeOpenTelemetry() {
const honeycombApiKey = process.env.HONEYCOMB_API_KEY;
const honeycombDataset = process.env.HONEYCOMB_DATASET;
if (!honeycombApiKey || !honeycombDataset) {
console.warn('OpenTelemetry initialization skipped: HONEYCOMB_API_KEY and/or HONEYCOMB_DATASET not set');
return trace.getTracerProvider().getTracer('nut-server');
}
console.warn('Initializing OpenTelemetry');
const exporter = new OTLPTraceExporter({
url: 'https://api.honeycomb.io/v1/traces',
headers: {
'x-honeycomb-team': honeycombApiKey,
'x-honeycomb-dataset': honeycombDataset,
},
});
const resource = new Resource({
[ATTR_SERVICE_NAME]: 'nut.server',
});
const provider = new WebTracerProvider({
resource,
spanProcessors: [new SimpleSpanProcessor(exporter), new SimpleSpanProcessor(new ConsoleSpanExporter())],
});
provider.register({
contextManager: new ZoneContextManager(),
});
return provider.getTracer('nut-server');
}
const tracer = initializeOpenTelemetry();
class NormalizedError extends Error {
value: unknown;
constructor(value: unknown) {
super();
this.value = value;
}
}
export function normalizeError(err: unknown): Error {
return err instanceof Error ? err : new NormalizedError(err);
}
type SpanOptions = {
name: string;
attrs?: Attributes;
};
export function wrapWithSpan<Args extends any[], T>(
opts: SpanOptions,
fn: (...args: Args) => Promise<T>,
): (...args: Args) => Promise<T> {
return async (...args: Args) => {
return tracer.startActiveSpan(opts.name, async (span) => {
if (opts.attrs) {
span.setAttributes(opts.attrs);
}
try {
const rv = await fn(...args);
span.setStatus({
code: SpanStatusCode.OK,
});
return rv;
} catch (e) {
const err = normalizeError(e);
span.setStatus({
code: SpanStatusCode.ERROR,
});
span.recordException(err);
throw e;
} finally {
span.end();
}
});
};
}
export function getCurrentSpan() {
return trace.getSpan(context.active());
}

View File

@ -60,6 +60,13 @@
"@octokit/rest": "^21.0.2",
"@octokit/types": "^13.6.2",
"@openrouter/ai-sdk-provider": "^0.0.5",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/context-zone": "^1.30.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.57.1",
"@opentelemetry/resources": "^1.30.1",
"@opentelemetry/sdk-trace-base": "^1.30.1",
"@opentelemetry/sdk-trace-web": "^1.30.1",
"@opentelemetry/semantic-conventions": "^1.30.0",
"@radix-ui/react-context-menu": "^2.2.2",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-dropdown-menu": "^2.1.2",

View File

@ -101,6 +101,27 @@ importers:
'@openrouter/ai-sdk-provider':
specifier: ^0.0.5
version: 0.0.5(zod@3.23.8)
'@opentelemetry/api':
specifier: ^1.9.0
version: 1.9.0
'@opentelemetry/context-zone':
specifier: ^1.30.1
version: 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/exporter-trace-otlp-http':
specifier: ^0.57.1
version: 0.57.1(@opentelemetry/api@1.9.0)
'@opentelemetry/resources':
specifier: ^1.30.1
version: 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base':
specifier: ^1.30.1
version: 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-web':
specifier: ^1.30.1
version: 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions':
specifier: ^1.30.0
version: 1.30.0
'@radix-ui/react-context-menu':
specifier: ^2.2.2
version: 2.2.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -1641,10 +1662,87 @@ packages:
peerDependencies:
zod: ^3.0.0
'@opentelemetry/api-logs@0.57.1':
resolution: {integrity: sha512-I4PHczeujhQAQv6ZBzqHYEUiggZL4IdSMixtVD3EYqbdrjujE7kRfI5QohjlPoJm8BvenoW5YaTMWRrbpot6tg==}
engines: {node: '>=14'}
'@opentelemetry/api@1.9.0':
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
engines: {node: '>=8.0.0'}
'@opentelemetry/context-zone-peer-dep@1.30.1':
resolution: {integrity: sha512-8oJQR+MBblY5WGOm26AOBLogN+FoO26QEZssH9WJd1qSD7ABMefq9qyGyN9xilFFl2ABPHgcMzkfYb8vx9JBEA==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
zone.js: ^0.10.2 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0
'@opentelemetry/context-zone@1.30.1':
resolution: {integrity: sha512-N6CACt5sxXD6XzS2jJPqstNJZ/QFqeW56IiKfHb6hYOelCXVvYfxheF7byAeRXa7+N8rmXUP7aRdupALXP5hdQ==}
engines: {node: '>=14'}
'@opentelemetry/core@1.30.1':
resolution: {integrity: sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/exporter-trace-otlp-http@0.57.1':
resolution: {integrity: sha512-43dLEjlf6JGxpVt9RaRlJAvjHG1wGsbAuNd67RIDy/95zfKk2aNovtiGUgFdS/kcvgvS90upIUbgn0xUd9JjMg==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/otlp-exporter-base@0.57.1':
resolution: {integrity: sha512-GNBJAEYfeiYJQ3O2dvXgiNZ/qjWrBxSb1L1s7iV/jKBRGMN3Nv+miTk2SLeEobF5E5ZK4rVcHKlBZ71bPVIv/g==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/otlp-transformer@0.57.1':
resolution: {integrity: sha512-EX67y+ukNNfFrOLyjYGw8AMy0JPIlEX1dW60SGUNZWW2hSQyyolX7EqFuHP5LtXLjJHNfzx5SMBVQ3owaQCNDw==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/resources@1.30.1':
resolution: {integrity: sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/sdk-logs@0.57.1':
resolution: {integrity: sha512-jGdObb/BGWu6Peo3cL3skx/Rl1Ak/wDDO3vpPrrThGbqE7isvkCsX6uE+OAt8Ayjm9YC8UGkohWbLR09JmM0FA==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.4.0 <1.10.0'
'@opentelemetry/sdk-metrics@1.30.1':
resolution: {integrity: sha512-q9zcZ0Okl8jRgmy7eNW3Ku1XSgg3sDLa5evHZpCwjspw7E8Is4K/haRPDJrBcX3YSn/Y7gUvFnByNYEKQNbNog==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.3.0 <1.10.0'
'@opentelemetry/sdk-trace-base@1.30.1':
resolution: {integrity: sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/sdk-trace-web@1.30.1':
resolution: {integrity: sha512-AUo2e+1uyTGMB36VlbvBqnCogVzQhpC7dRcVVdCrt+cFHLpFRRJcd45J2obGTgs0XiAwNLyq5bhkW3JF2NZA+A==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/semantic-conventions@1.28.0':
resolution: {integrity: sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==}
engines: {node: '>=14'}
'@opentelemetry/semantic-conventions@1.30.0':
resolution: {integrity: sha512-4VlGgo32k2EQ2wcCY3vEU28A0O13aOtHz3Xt2/2U5FAh9EfhD6t6DqL5Z6yAnRCntbTFDU4YfbpyzSlHNWycPw==}
engines: {node: '>=14'}
'@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
@ -1656,6 +1754,36 @@ packages:
'@polka/url@1.0.0-next.28':
resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==}
'@protobufjs/aspromise@1.1.2':
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
'@protobufjs/base64@1.1.2':
resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
'@protobufjs/codegen@2.0.4':
resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==}
'@protobufjs/eventemitter@1.1.0':
resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
'@protobufjs/fetch@1.1.0':
resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==}
'@protobufjs/float@1.0.2':
resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
'@protobufjs/inquire@1.1.0':
resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==}
'@protobufjs/path@1.1.2':
resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
'@protobufjs/pool@1.1.0':
resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
'@protobufjs/utf8@1.1.0':
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
'@radix-ui/primitive@1.1.0':
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
@ -4151,6 +4279,9 @@ packages:
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
engines: {node: '>=10'}
long@5.3.0:
resolution: {integrity: sha512-5vvY5yF1zF/kXk+L94FRiTDa1Znom46UjPCH6/XbSvS8zBKMFBHTJk8KDMqJ+2J6QezQFi7k1k8v21ClJYHPaw==}
longest-streak@3.1.0:
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
@ -4971,6 +5102,10 @@ packages:
property-information@6.5.0:
resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
protobufjs@7.4.0:
resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==}
engines: {node: '>=12.0.0'}
proxy-addr@2.0.7:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
@ -6188,6 +6323,9 @@ packages:
zod@3.23.8:
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
zone.js@0.15.0:
resolution: {integrity: sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==}
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
@ -7750,8 +7888,92 @@ snapshots:
'@ai-sdk/provider-utils': 1.0.2(zod@3.23.8)
zod: 3.23.8
'@opentelemetry/api-logs@0.57.1':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/api@1.9.0': {}
'@opentelemetry/context-zone-peer-dep@1.30.1(@opentelemetry/api@1.9.0)(zone.js@0.15.0)':
dependencies:
'@opentelemetry/api': 1.9.0
zone.js: 0.15.0
'@opentelemetry/context-zone@1.30.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/context-zone-peer-dep': 1.30.1(@opentelemetry/api@1.9.0)(zone.js@0.15.0)
zone.js: 0.15.0
transitivePeerDependencies:
- '@opentelemetry/api'
'@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/semantic-conventions': 1.28.0
'@opentelemetry/exporter-trace-otlp-http@0.57.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/otlp-exporter-base': 0.57.1(@opentelemetry/api@1.9.0)
'@opentelemetry/otlp-transformer': 0.57.1(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/otlp-exporter-base@0.57.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/otlp-transformer': 0.57.1(@opentelemetry/api@1.9.0)
'@opentelemetry/otlp-transformer@0.57.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/api-logs': 0.57.1
'@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-logs': 0.57.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-metrics': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0)
protobufjs: 7.4.0
'@opentelemetry/resources@1.30.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.28.0
'@opentelemetry/sdk-logs@0.57.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/api-logs': 0.57.1
'@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-metrics@1.30.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.28.0
'@opentelemetry/sdk-trace-web@1.30.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.28.0
'@opentelemetry/semantic-conventions@1.28.0': {}
'@opentelemetry/semantic-conventions@1.30.0': {}
'@pkgjs/parseargs@0.11.0':
optional: true
@ -7759,6 +7981,29 @@ snapshots:
'@polka/url@1.0.0-next.28': {}
'@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':
dependencies:
'@protobufjs/aspromise': 1.1.2
'@protobufjs/inquire': 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': {}
'@radix-ui/primitive@1.1.0': {}
'@radix-ui/react-arrow@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
@ -10706,6 +10951,8 @@ snapshots:
chalk: 4.1.2
is-unicode-supported: 0.1.0
long@5.3.0: {}
longest-streak@3.1.0: {}
loose-envify@1.4.0:
@ -11916,6 +12163,21 @@ snapshots:
property-information@6.5.0: {}
protobufjs@7.4.0:
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/node': 22.10.1
long: 5.3.0
proxy-addr@2.0.7:
dependencies:
forwarded: 0.2.0
@ -13236,4 +13498,6 @@ snapshots:
zod@3.23.8: {}
zone.js@0.15.0: {}
zwitch@2.0.4: {}