From c22dbe96a788eadaf56df61a5855e77af4c8ce51 Mon Sep 17 00:00:00 2001 From: nicktrn <55853254+nicktrn@users.noreply.github.com> Date: Fri, 29 Aug 2025 18:02:39 +0100 Subject: [PATCH 1/4] feat(webapp): upgrade otel packages and add more metrics --- apps/webapp/app/env.server.ts | 2 + .../asyncResourceAttributes.server.ts | 263 --------- .../telemetry/compactMetricExporter.server.ts | 153 ++++++ .../app/v3/telemetry/loggerExporter.server.ts | 10 +- apps/webapp/app/v3/tracer.server.ts | 317 +++++++++-- apps/webapp/package.json | 35 +- apps/webapp/test/utils/tracing.ts | 7 +- pnpm-lock.yaml | 520 ++++++++---------- 8 files changed, 678 insertions(+), 629 deletions(-) delete mode 100644 apps/webapp/app/v3/telemetry/asyncResourceAttributes.server.ts create mode 100644 apps/webapp/app/v3/telemetry/compactMetricExporter.server.ts diff --git a/apps/webapp/app/env.server.ts b/apps/webapp/app/env.server.ts index a1e8854dbe..b3d69e1760 100644 --- a/apps/webapp/app/env.server.ts +++ b/apps/webapp/app/env.server.ts @@ -352,6 +352,8 @@ const EnvironmentSchema = z.object({ INTERNAL_OTEL_METRIC_EXPORTER_AUTH_HEADERS: z.string().optional(), INTERNAL_OTEL_METRIC_EXPORTER_ENABLED: z.string().default("0"), INTERNAL_OTEL_METRIC_EXPORTER_INTERVAL_MS: z.coerce.number().int().default(30_000), + INTERNAL_OTEL_HOST_METRICS_ENABLED: BoolEnv.default(true), + INTERNAL_OTEL_NODEJS_METRICS_ENABLED: BoolEnv.default(true), ORG_SLACK_INTEGRATION_CLIENT_ID: z.string().optional(), ORG_SLACK_INTEGRATION_CLIENT_SECRET: z.string().optional(), diff --git a/apps/webapp/app/v3/telemetry/asyncResourceAttributes.server.ts b/apps/webapp/app/v3/telemetry/asyncResourceAttributes.server.ts deleted file mode 100644 index d05503de9c..0000000000 --- a/apps/webapp/app/v3/telemetry/asyncResourceAttributes.server.ts +++ /dev/null @@ -1,263 +0,0 @@ -import { z } from "zod"; -import type { ResourceAttributes } from "@opentelemetry/resources"; -import { - SEMRESATTRS_AWS_ECS_CLUSTER_ARN, - SEMRESATTRS_AWS_ECS_CONTAINER_ARN, - SEMRESATTRS_AWS_ECS_LAUNCHTYPE, - SEMRESATTRS_AWS_ECS_TASK_ARN, - SEMRESATTRS_AWS_ECS_TASK_FAMILY, - SEMRESATTRS_AWS_ECS_TASK_REVISION, - SEMRESATTRS_AWS_LOG_GROUP_NAMES, - SEMRESATTRS_AWS_LOG_STREAM_NAMES, - SEMRESATTRS_CLOUD_AVAILABILITY_ZONE, - SEMRESATTRS_CLOUD_PLATFORM, - SEMRESATTRS_CLOUD_PROVIDER, - SEMRESATTRS_CLOUD_REGION, - SEMRESATTRS_CONTAINER_NAME, - SEMRESATTRS_CONTAINER_ID, - SEMRESATTRS_CONTAINER_IMAGE_NAME, - SEMRESATTRS_CONTAINER_IMAGE_TAG, - CLOUDPLATFORMVALUES_AWS_ECS, - CLOUDPROVIDERVALUES_AWS, -} from "@opentelemetry/semantic-conventions"; -import { tryCatch } from "@trigger.dev/core/utils"; -import { logger } from "~/services/logger.server"; - -// Minimal schema for ECS task metadata -const ECSTaskMetadataSchema = z.object({ - Cluster: z.string().optional(), - TaskARN: z.string().optional(), - Family: z.string().optional(), - Revision: z.string().optional(), - AvailabilityZone: z.string().optional(), - LaunchType: z.string().optional(), - ServiceName: z.string().optional(), -}); - -const ECSLogOptions = z.object({ - "awslogs-group": z.string().optional(), - "awslogs-region": z.string().optional(), - "awslogs-stream": z.string().optional(), - mode: z.string().optional(), -}); - -// Minimal schema for container metadata -const ECSContainerMetadataSchema = z.object({ - DockerId: z.string().optional(), - Name: z.string().optional(), - Image: z.string().optional(), - ImageID: z.string().optional(), - ContainerARN: z.string().optional(), - LogOptions: ECSLogOptions.optional(), -}); - -// Cache for ECS metadata to avoid repeated fetches -let ecsMetadataCache: ResourceAttributes | null = null; - -/** - * Fetches ECS task metadata from the v4 endpoint - */ -async function fetchECSTaskMetadata(metadataUri: string): Promise { - const [error, response] = await tryCatch( - fetch(`${metadataUri}/task`, { - signal: AbortSignal.timeout(5000), - }) - ); - - if (error) { - logger.warn("Failed to fetch ECS task metadata", { error }); - return {}; - } - - if (!response.ok) { - logger.warn("ECS task metadata fetch failed", { status: response.status }); - return {}; - } - - const [jsonError, taskJson] = await tryCatch(response.json()); - if (jsonError) { - logger.warn("Failed to parse ECS task metadata", { error: jsonError }); - return {}; - } - - const parseResult = ECSTaskMetadataSchema.safeParse(taskJson); - if (!parseResult.success) { - logger.warn("ECS task metadata validation issues", { issues: parseResult.error.issues }); - return {}; - } - - const taskData = parseResult.data; - const attributes: ResourceAttributes = {}; - - if (taskData.TaskARN) { - attributes[SEMRESATTRS_AWS_ECS_TASK_ARN] = taskData.TaskARN; - } - - if (taskData.Cluster) { - attributes[SEMRESATTRS_AWS_ECS_CLUSTER_ARN] = taskData.Cluster; - } - - if (taskData.LaunchType) { - attributes[SEMRESATTRS_AWS_ECS_LAUNCHTYPE] = taskData.LaunchType; - } - - if (taskData.Family) { - attributes[SEMRESATTRS_AWS_ECS_TASK_FAMILY] = taskData.Family; - } - - if (taskData.Revision) { - attributes[SEMRESATTRS_AWS_ECS_TASK_REVISION] = taskData.Revision; - } - - if (taskData.AvailabilityZone) { - attributes[SEMRESATTRS_CLOUD_AVAILABILITY_ZONE] = taskData.AvailabilityZone; - } - - if (taskData.ServiceName) { - // Custom attribute for ECS service name - attributes["aws.ecs.service.name"] = taskData.ServiceName; - } - - return attributes; -} - -/** - * Fetches ECS container metadata from the v4 endpoint - */ -async function fetchECSContainerMetadata(metadataUri: string): Promise { - const [error, response] = await tryCatch( - fetch(metadataUri, { - signal: AbortSignal.timeout(5000), - }) - ); - - if (error) { - logger.warn("Failed to fetch ECS container metadata", { error }); - return {}; - } - - if (!response.ok) { - logger.warn("ECS container metadata fetch failed", { status: response.status }); - return {}; - } - - const [jsonError, containerJson] = await tryCatch(response.json()); - if (jsonError) { - logger.warn("Failed to parse ECS container metadata", { error: jsonError }); - return {}; - } - - const parseResult = ECSContainerMetadataSchema.safeParse(containerJson); - if (!parseResult.success) { - logger.warn("ECS container metadata validation issues", { issues: parseResult.error.issues }); - return {}; - } - - const containerData = parseResult.data; - const attributes: ResourceAttributes = {}; - - if (containerData.Name) { - attributes[SEMRESATTRS_CONTAINER_NAME] = containerData.Name; - } - - if (containerData.DockerId) { - attributes[SEMRESATTRS_CONTAINER_ID] = containerData.DockerId; - } - - if (containerData.Image) { - const [name, tag] = containerData.Image.split(":"); - - if (name) { - attributes[SEMRESATTRS_CONTAINER_IMAGE_NAME] = name; - } - - if (tag) { - attributes[SEMRESATTRS_CONTAINER_IMAGE_TAG] = tag; - } - } - - if (containerData.ImageID) { - // Custom attribute for image ID - attributes["container.image.id"] = containerData.ImageID; - } - - if (containerData.ContainerARN) { - attributes[SEMRESATTRS_AWS_ECS_CONTAINER_ARN] = containerData.ContainerARN; - } - - const logOptions = containerData.LogOptions; - if (logOptions?.["awslogs-group"]) { - attributes[SEMRESATTRS_AWS_LOG_GROUP_NAMES] = [logOptions["awslogs-group"]]; - } - if (logOptions?.["awslogs-stream"]) { - attributes[SEMRESATTRS_AWS_LOG_STREAM_NAMES] = [logOptions["awslogs-stream"]]; - } - if (logOptions?.mode) { - // Custom attribute for log mode - attributes["aws.log.mode"] = [logOptions.mode]; - } - - return attributes; -} - -/** - * Fetches ECS metadata from the Task Metadata Endpoint V4 - * Returns resource attributes for OpenTelemetry - */ -async function fetchECSMetadata(metadataUri: string): Promise { - // Return cached metadata if available - if (ecsMetadataCache !== null) { - return ecsMetadataCache; - } - - if (!metadataUri) { - // Not running in ECS - ecsMetadataCache = {}; - return ecsMetadataCache; - } - - // Fetch task metadata and CloudWatch logs config in parallel - const [taskAttributes, containerAttributes] = await Promise.all([ - fetchECSTaskMetadata(metadataUri), - fetchECSContainerMetadata(metadataUri), - ]); - - const attributes: ResourceAttributes = { - [SEMRESATTRS_CLOUD_PROVIDER]: CLOUDPROVIDERVALUES_AWS, - [SEMRESATTRS_CLOUD_PLATFORM]: CLOUDPLATFORMVALUES_AWS_ECS, - ...taskAttributes, - ...containerAttributes, - }; - - const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION; - if (region) { - attributes[SEMRESATTRS_CLOUD_REGION] = region; - } - - logger.info("🔦 Fetched ECS metadata", { attributes }); - - ecsMetadataCache = attributes; - return attributes; -} - -/** - * Fetches async resource attributes - * Designed to be used with the Resource constructor's asyncAttributesPromise parameter - * - * Usage: - * ``` - * new Resource( - * { [SEMRESATTRS_SERVICE_NAME]: 'my-service' }, - * getAsyncResourceAttributes() - * ) - * ``` - */ -export async function getAsyncResourceAttributes(): Promise { - const metadataUri = process.env.ECS_CONTAINER_METADATA_URI_V4; - - if (!metadataUri) { - return {}; - } - - return fetchECSMetadata(metadataUri); -} diff --git a/apps/webapp/app/v3/telemetry/compactMetricExporter.server.ts b/apps/webapp/app/v3/telemetry/compactMetricExporter.server.ts new file mode 100644 index 0000000000..c5e97dbb28 --- /dev/null +++ b/apps/webapp/app/v3/telemetry/compactMetricExporter.server.ts @@ -0,0 +1,153 @@ +import { type ExportResult, ExportResultCode } from "@opentelemetry/core"; +import type { + PushMetricExporter, + ResourceMetrics, + MetricData, + DataPoint, + Histogram, + ExponentialHistogram, +} from "@opentelemetry/sdk-metrics"; + +/** + * Compact metric exporter that logs metrics in a single-line format + * Similar to Prometheus text format for better readability + */ +export class CompactMetricExporter implements PushMetricExporter { + /** + * Export metrics in a compact format + */ + export(metrics: ResourceMetrics, resultCallback: (result: ExportResult) => void): void { + try { + this._exportMetrics(metrics); + resultCallback({ code: ExportResultCode.SUCCESS }); + } catch (error) { + resultCallback({ + code: ExportResultCode.FAILED, + error: error instanceof Error ? error : new Error(String(error)), + }); + } + } + + /** + * Shutdown the exporter + */ + async shutdown(): Promise { + return Promise.resolve(); + } + + /** + * Force flush any buffered data + */ + async forceFlush(): Promise { + return Promise.resolve(); + } + + /** + * Process and log metrics in compact format + */ + private _exportMetrics(resourceMetrics: ResourceMetrics): void { + for (const scopeMetric of resourceMetrics.scopeMetrics) { + for (const metric of scopeMetric.metrics) { + this._exportMetric(metric); + } + } + } + + /** + * Export a single metric + */ + private _exportMetric(metric: MetricData): void { + const metricName = metric.descriptor.name; + + for (const dataPoint of metric.dataPoints) { + const formattedLine = this._formatDataPoint(metricName, dataPoint); + if (formattedLine) { + console.log(formattedLine); + } + } + } + + /** + * Format a data point into a single line + */ + private _formatDataPoint( + metricName: string, + dataPoint: DataPoint | DataPoint | DataPoint + ): string | null { + // Extract attributes/labels + const labels = this._formatLabels(dataPoint.attributes); + + // Extract value based on data point type + const value = this._extractValue(dataPoint); + + if (value === null || value === undefined) { + return null; + } + + // Format as: metric_name{label1="value1",label2="value2"} = value + if (labels) { + return `${metricName}{${labels}} = ${value}`; + } + + return `${metricName} = ${value}`; + } + + /** + * Format attributes as Prometheus-style labels + */ + private _formatLabels(attributes: Record): string { + const entries = Object.entries(attributes); + if (entries.length === 0) { + return ""; + } + + return entries.map(([key, value]) => `${key}="${String(value)}"`).join(","); + } + + /** + * Extract the numeric value from a data point + */ + private _extractValue( + dataPoint: DataPoint | DataPoint | DataPoint + ): number | null { + const value = dataPoint.value; + + // Check if value is a simple number (Gauge, Sum, UpDownSum) + if (typeof value === "number") { + return value; + } + + // Check if value is a Histogram or ExponentialHistogram + if (this._isHistogram(value) || this._isExponentialHistogram(value)) { + return value.sum ?? null; + } + + return null; + } + + /** + * Type guard for Histogram + */ + private _isHistogram(value: unknown): value is Histogram { + return ( + value !== null && + typeof value === "object" && + "sum" in value && + "count" in value && + "buckets" in value + ); + } + + /** + * Type guard for ExponentialHistogram + */ + private _isExponentialHistogram(value: unknown): value is ExponentialHistogram { + return ( + value !== null && + typeof value === "object" && + "sum" in value && + "count" in value && + "scale" in value + ); + } +} diff --git a/apps/webapp/app/v3/telemetry/loggerExporter.server.ts b/apps/webapp/app/v3/telemetry/loggerExporter.server.ts index 691665c204..236ad1d5cf 100644 --- a/apps/webapp/app/v3/telemetry/loggerExporter.server.ts +++ b/apps/webapp/app/v3/telemetry/loggerExporter.server.ts @@ -14,8 +14,8 @@ * limitations under the License. */ -import { ExportResult, ExportResultCode, hrTimeToMicroseconds } from "@opentelemetry/core"; -import { ReadableSpan, SpanExporter } from "@opentelemetry/sdk-trace-base"; +import { type ExportResult, ExportResultCode, hrTimeToMicroseconds } from "@opentelemetry/core"; +import type { ReadableSpan, SpanExporter } from "@opentelemetry/sdk-trace-base"; export class LoggerSpanExporter implements SpanExporter { /** @@ -47,11 +47,13 @@ export class LoggerSpanExporter implements SpanExporter { * @param span */ private _exportInfo(span: ReadableSpan) { + const parentSpanId = span.parentSpanContext?.spanId; + return { traceId: span.spanContext().traceId, parentId: - span.parentSpanId && span.parentSpanId !== "" && span.parentSpanId !== "0000000000000000" - ? span.parentSpanId + parentSpanId && parentSpanId !== "" && parentSpanId !== "0000000000000000" + ? parentSpanId : undefined, traceState: span.spanContext().traceState?.serialize(), message: span.name, diff --git a/apps/webapp/app/v3/tracer.server.ts b/apps/webapp/app/v3/tracer.server.ts index 40004abe8b..fb332ceb80 100644 --- a/apps/webapp/app/v3/tracer.server.ts +++ b/apps/webapp/app/v3/tracer.server.ts @@ -1,18 +1,17 @@ import { - Attributes, - Context, + type Attributes, + type Context, DiagConsoleLogger, DiagLogLevel, - Link, - Span, - SpanKind, - SpanOptions, + type Link, + type Span, + type SpanKind, + type SpanOptions, SpanStatusCode, - Tracer, diag, trace, metrics, - Meter, + type Meter, } from "@opentelemetry/api"; import { logs, SeverityNumber } from "@opentelemetry/api-logs"; import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; @@ -21,44 +20,44 @@ import { BatchLogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs import { type Instrumentation, registerInstrumentations } from "@opentelemetry/instrumentation"; import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express"; import { HttpInstrumentation } from "@opentelemetry/instrumentation-http"; -import { - MeterProvider, - ConsoleMetricExporter, - PeriodicExportingMetricReader, -} from "@opentelemetry/sdk-metrics"; +import { MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics"; import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto"; -import { Resource } from "@opentelemetry/resources"; import { BatchSpanProcessor, ParentBasedSampler, - Sampler, + type Sampler, SamplingDecision, - SamplingResult, + type SamplingResult, SimpleSpanProcessor, + type SpanProcessor, TraceIdRatioBasedSampler, } from "@opentelemetry/sdk-trace-base"; import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; -import { - SEMRESATTRS_SERVICE_INSTANCE_ID, - SEMRESATTRS_SERVICE_NAME, - SEMRESATTRS_HOST_NAME, -} from "@opentelemetry/semantic-conventions"; +import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions"; import { PrismaInstrumentation } from "@prisma/instrumentation"; +import { HostMetrics } from "@opentelemetry/host-metrics"; +import { AwsInstrumentation } from "@opentelemetry/instrumentation-aws-sdk"; +import { awsEcsDetector, awsEc2Detector } from "@opentelemetry/resource-detector-aws"; +import { + detectResources, + resourceFromAttributes, + serviceInstanceIdDetector, + osDetector, + hostDetector, + processDetector, +} from "@opentelemetry/resources"; import { env } from "~/env.server"; -import { AuthenticatedEnvironment } from "~/services/apiAuth.server"; +import type { AuthenticatedEnvironment } from "~/services/apiAuth.server"; import { singleton } from "~/utils/singleton"; import { LoggerSpanExporter } from "./telemetry/loggerExporter.server"; +import { CompactMetricExporter } from "./telemetry/compactMetricExporter.server"; import { logger } from "~/services/logger.server"; import { flattenAttributes } from "@trigger.dev/core/v3"; -import { randomUUID } from "node:crypto"; import { prisma } from "~/db.server"; -import { hostname } from "node:os"; -import { getAsyncResourceAttributes } from "./telemetry/asyncResourceAttributes.server"; +import { metricsRegister } from "~/metrics.server"; export const SEMINTATTRS_FORCE_RECORDING = "forceRecording"; -const SERVICE_INSTANCE_ID = randomUUID(); - class CustomWebappSampler implements Sampler { constructor(private readonly _baseSampler: Sampler) {} @@ -172,14 +171,22 @@ export async function emitWarnLog(message: string, params: Record m.name === "nodejs_active_handles"); + const activeHandlesTotal = metrics.find((m) => m.name === "nodejs_active_handles_total"); + + // Get request metrics with types + const activeRequests = metrics.find((m) => m.name === "nodejs_active_requests"); + const activeRequestsTotal = metrics.find((m) => m.name === "nodejs_active_requests_total"); + + // Event loop metrics + const eventLoopLagMin = metrics.find((m) => m.name === "nodejs_eventloop_lag_min_seconds"); + const eventLoopLagMax = metrics.find((m) => m.name === "nodejs_eventloop_lag_max_seconds"); + const eventLoopLagMean = metrics.find((m) => m.name === "nodejs_eventloop_lag_mean_seconds"); + const eventLoopLagP50 = metrics.find((m) => m.name === "nodejs_eventloop_lag_p50_seconds"); + const eventLoopLagP90 = metrics.find((m) => m.name === "nodejs_eventloop_lag_p90_seconds"); + const eventLoopLagP99 = metrics.find((m) => m.name === "nodejs_eventloop_lag_p99_seconds"); + + // Extract handle types + const handlesByType: Record = {}; + if (activeHandles?.values) { + for (const value of activeHandles.values) { + const type = value.labels?.type; + if (type) { + handlesByType[type] = value.value; + } + } + } + + // Extract request types + const requestsByType: Record = {}; + if (activeRequests?.values) { + for (const value of activeRequests.values) { + const type = value.labels?.type; + if (type) { + requestsByType[type] = value.value; + } + } + } + + return { + threadpoolSize: uvThreadpoolSize, + handlesByType, + handlesTotal: activeHandlesTotal?.values?.[0]?.value ?? 0, + requestsByType, + requestsTotal: activeRequestsTotal?.values?.[0]?.value ?? 0, + eventLoop: { + min: eventLoopLagMin?.values?.[0]?.value ?? 0, + max: eventLoopLagMax?.values?.[0]?.value ?? 0, + mean: eventLoopLagMean?.values?.[0]?.value ?? 0, + p50: eventLoopLagP50?.values?.[0]?.value ?? 0, + p90: eventLoopLagP90?.values?.[0]?.value ?? 0, + p99: eventLoopLagP99?.values?.[0]?.value ?? 0, + }, + }; + } + + meter.addBatchObservableCallback( + async (res) => { + const { + threadpoolSize, + handlesByType, + handlesTotal, + requestsByType, + requestsTotal, + eventLoop, + } = await readNodeMetrics(); + + // Observe UV threadpool size + res.observe(uvThreadpoolSizeGauge, threadpoolSize); + + // Observe handle metrics by type + for (const [type, count] of Object.entries(handlesByType)) { + res.observe(activeHandlesGauge, count, { type }); + } + res.observe(activeHandlesTotalGauge, handlesTotal); + + // Observe request metrics by type + for (const [type, count] of Object.entries(requestsByType)) { + res.observe(activeRequestsGauge, count, { type }); + } + res.observe(activeRequestsTotalGauge, requestsTotal); + + // Observe event loop metrics + res.observe(eventLoopLagMinGauge, eventLoop.min); + res.observe(eventLoopLagMaxGauge, eventLoop.max); + res.observe(eventLoopLagMeanGauge, eventLoop.mean); + res.observe(eventLoopLagP50Gauge, eventLoop.p50); + res.observe(eventLoopLagP90Gauge, eventLoop.p90); + res.observe(eventLoopLagP99Gauge, eventLoop.p99); + }, + [ + uvThreadpoolSizeGauge, + activeHandlesGauge, + activeHandlesTotalGauge, + activeRequestsGauge, + activeRequestsTotalGauge, + eventLoopLagMinGauge, + eventLoopLagMaxGauge, + eventLoopLagMeanGauge, + eventLoopLagP50Gauge, + eventLoopLagP90Gauge, + eventLoopLagP99Gauge, + ] + ); +} + +function configureHostMetrics({ meterProvider }: { meterProvider: MeterProvider }) { + if (!env.INTERNAL_OTEL_HOST_METRICS_ENABLED) { + return; + } + + console.log("🔦 Metrics: Host metrics enabled (CPU, memory, network)"); + + const hostMetrics = new HostMetrics({ meterProvider }); + + hostMetrics.start(); +} + const SemanticEnvResources = { ENV_ID: "$trigger.env.id", ENV_TYPE: "$trigger.env.type", @@ -423,6 +619,7 @@ function createMetricsExporter() { headers, }); } else { - return new ConsoleMetricExporter(); + console.log(`🔦 Tracer: Compact metric exporter enabled`); + return new CompactMetricExporter(); } } diff --git a/apps/webapp/package.json b/apps/webapp/package.json index f3a2315636..8c48dac819 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -53,8 +53,8 @@ "@electric-sql/react": "^0.3.5", "@headlessui/react": "^1.7.8", "@heroicons/react": "^2.0.12", - "@internal/redis": "workspace:*", "@internal/cache": "workspace:*", + "@internal/redis": "workspace:*", "@internal/run-engine": "workspace:*", "@internal/schedule-engine": "workspace:*", "@internal/tracing": "workspace:*", @@ -63,21 +63,24 @@ "@kapaai/react-sdk": "^0.1.3", "@lezer/highlight": "^1.1.6", "@opentelemetry/api": "1.9.0", - "@opentelemetry/api-logs": "0.52.1", - "@opentelemetry/core": "1.25.1", - "@opentelemetry/exporter-logs-otlp-http": "0.52.1", - "@opentelemetry/exporter-metrics-otlp-proto": "0.52.1", - "@opentelemetry/exporter-trace-otlp-http": "0.52.1", - "@opentelemetry/instrumentation": "0.52.1", - "@opentelemetry/instrumentation-express": "^0.36.1", - "@opentelemetry/instrumentation-http": "0.52.1", - "@opentelemetry/resources": "1.25.1", - "@opentelemetry/sdk-logs": "0.52.1", - "@opentelemetry/sdk-metrics": "1.25.1", - "@opentelemetry/sdk-node": "0.52.1", - "@opentelemetry/sdk-trace-base": "1.25.1", - "@opentelemetry/sdk-trace-node": "1.25.1", - "@opentelemetry/semantic-conventions": "1.25.1", + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/exporter-logs-otlp-http": "0.203.0", + "@opentelemetry/exporter-metrics-otlp-proto": "0.203.0", + "@opentelemetry/exporter-trace-otlp-http": "0.203.0", + "@opentelemetry/host-metrics": "^0.36.0", + "@opentelemetry/instrumentation": "0.203.0", + "@opentelemetry/instrumentation-aws-sdk": "^0.57.0", + "@opentelemetry/instrumentation-express": "^0.52.0", + "@opentelemetry/instrumentation-http": "0.203.0", + "@opentelemetry/resource-detector-aws": "^2.3.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-logs": "0.203.0", + "@opentelemetry/sdk-metrics": "2.0.1", + "@opentelemetry/sdk-node": "0.203.0", + "@opentelemetry/sdk-trace-base": "2.0.1", + "@opentelemetry/sdk-trace-node": "2.0.1", + "@opentelemetry/semantic-conventions": "1.36.0", "@popperjs/core": "^2.11.8", "@prisma/instrumentation": "^6.14.0", "@radix-ui/react-accordion": "^1.2.11", diff --git a/apps/webapp/test/utils/tracing.ts b/apps/webapp/test/utils/tracing.ts index 591e27120a..33b821abe7 100644 --- a/apps/webapp/test/utils/tracing.ts +++ b/apps/webapp/test/utils/tracing.ts @@ -1,12 +1,13 @@ import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; import { InMemorySpanExporter, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base"; -import { context, trace } from "@opentelemetry/api"; +import { trace } from "@opentelemetry/api"; export function createInMemoryTracing() { // Initialize the tracer provider and exporter - const provider = new NodeTracerProvider(); const exporter = new InMemorySpanExporter(); - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); + const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(exporter)], + }); provider.register(); // Retrieve the tracer diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 997cfa877a..c4ddc72986 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -297,50 +297,59 @@ importers: specifier: 1.9.0 version: 1.9.0 '@opentelemetry/api-logs': - specifier: 0.52.1 - version: 0.52.1 + specifier: 0.203.0 + version: 0.203.0 '@opentelemetry/core': - specifier: 1.25.1 - version: 1.25.1(@opentelemetry/api@1.9.0) + specifier: 2.0.1 + version: 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-logs-otlp-http': - specifier: 0.52.1 - version: 0.52.1(@opentelemetry/api@1.9.0) + specifier: 0.203.0 + version: 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-metrics-otlp-proto': - specifier: 0.52.1 - version: 0.52.1(@opentelemetry/api@1.9.0) + specifier: 0.203.0 + version: 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-trace-otlp-http': - specifier: 0.52.1 - version: 0.52.1(@opentelemetry/api@1.9.0) + specifier: 0.203.0 + version: 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/host-metrics': + specifier: ^0.36.0 + version: 0.36.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': - specifier: 0.52.1 - version: 0.52.1(@opentelemetry/api@1.9.0) + specifier: 0.203.0 + version: 0.203.0(@opentelemetry/api@1.9.0)(supports-color@10.0.0) + '@opentelemetry/instrumentation-aws-sdk': + specifier: ^0.57.0 + version: 0.57.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-express': - specifier: ^0.36.1 - version: 0.36.1(@opentelemetry/api@1.9.0) + specifier: ^0.52.0 + version: 0.52.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-http': - specifier: 0.52.1 - version: 0.52.1(@opentelemetry/api@1.9.0) + specifier: 0.203.0 + version: 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-aws': + specifier: ^2.3.0 + version: 2.3.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': - specifier: 1.25.1 - version: 1.25.1(@opentelemetry/api@1.9.0) + specifier: 2.0.1 + version: 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-logs': - specifier: 0.52.1 - version: 0.52.1(@opentelemetry/api@1.9.0) + specifier: 0.203.0 + version: 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': - specifier: 1.25.1 - version: 1.25.1(@opentelemetry/api@1.9.0) + specifier: 2.0.1 + version: 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-node': - specifier: 0.52.1 - version: 0.52.1(@opentelemetry/api@1.9.0) + specifier: 0.203.0 + version: 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': - specifier: 1.25.1 - version: 1.25.1(@opentelemetry/api@1.9.0) + specifier: 2.0.1 + version: 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-node': - specifier: 1.25.1 - version: 1.25.1(@opentelemetry/api@1.9.0) + specifier: 2.0.1 + version: 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': - specifier: 1.25.1 - version: 1.25.1 + specifier: 1.36.0 + version: 1.36.0 '@popperjs/core': specifier: ^2.11.8 version: 2.11.8 @@ -2006,7 +2015,7 @@ importers: version: link:../../packages/trigger-sdk '@vercel/otel': specifier: ^1.13.0 - version: 1.13.0(@opentelemetry/api-logs@0.203.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.203.0)(@opentelemetry/resources@1.25.1)(@opentelemetry/sdk-logs@0.203.0)(@opentelemetry/sdk-metrics@1.25.1)(@opentelemetry/sdk-trace-base@1.25.1) + version: 1.13.0(@opentelemetry/api-logs@0.203.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.203.0)(@opentelemetry/resources@1.30.1)(@opentelemetry/sdk-logs@0.203.0)(@opentelemetry/sdk-metrics@1.30.0)(@opentelemetry/sdk-trace-base@1.30.1) '@vercel/postgres': specifier: ^0.10.0 version: 0.10.0 @@ -8552,13 +8561,6 @@ packages: '@opentelemetry/api': 1.9.0 dev: false - /@opentelemetry/api-logs@0.49.1: - resolution: {integrity: sha512-kaNl/T7WzyMUQHQlVq7q0oV4Kev6+0xFwqzofryC66jgGMacd0QH5TwfpbUwSTby+SdAdprAe5UKMvBw4tKS5Q==} - engines: {node: '>=14'} - dependencies: - '@opentelemetry/api': 1.9.0 - dev: false - /@opentelemetry/api-logs@0.52.1: resolution: {integrity: sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==} engines: {node: '>=14'} @@ -8589,15 +8591,6 @@ packages: resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} - /@opentelemetry/context-async-hooks@1.25.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-UW/ge9zjvAEmRWVapOP0qyCvPulWU6cQxGxDbWEFfGOj1VBBZAuOqTo3X6yWmDTD3Xe15ysCZChHncr2xFMIfQ==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - dependencies: - '@opentelemetry/api': 1.9.0 - dev: false - /@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==} engines: {node: '>=14'} @@ -8656,6 +8649,21 @@ packages: '@opentelemetry/semantic-conventions': 1.36.0 dev: false + /@opentelemetry/exporter-logs-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-g/2Y2noc/l96zmM+g0LdeuyYKINyBwN6FJySoU15LHPLcMN/1a0wNk2SegwKcxrRdE7Xsm7fkIR5n6XFe3QpPw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@grpc/grpc-js': 1.12.6 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) + dev: false + /@opentelemetry/exporter-logs-otlp-http@0.203.0(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-s0hys1ljqlMTbXx2XiplmMJg9wG570Z5lH7wMvrZX6lcODI56sG4HL03jklF63tBeyNwK2RV1/ntXGo3HgG4Qw==} engines: {node: ^18.19.0 || >=20.6.0} @@ -8670,90 +8678,108 @@ packages: '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/exporter-logs-otlp-http@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-qKgywId2DbdowPZpOBXQKp0B8DfhfIArmSic15z13Nk/JAOccBUQdPwDjDnjsM5f0ckZFMVR2t/tijTUAqDZoA==} - engines: {node: '>=14'} + /@opentelemetry/exporter-logs-otlp-proto@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-nl/7S91MXn5R1aIzoWtMKGvqxgJgepB/sH9qW0rZvZtabnsjbf8OQ1uSx3yogtvLr0GzwD596nQKz2fV7q2RBw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: - '@opentelemetry/api': ^1.0.0 + '@opentelemetry/api': ^1.3.0 dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.52.1 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.203.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/exporter-metrics-otlp-http@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-oAHPOy1sZi58bwqXaucd19F/v7+qE2EuVslQOEeLQT94CDuZJJ4tbWzx8DpYBTrOSzKqqrMtx9+PMxkrcbxOyQ==} - engines: {node: '>=14'} + /@opentelemetry/exporter-metrics-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-FCCj9nVZpumPQSEI57jRAA89hQQgONuoC35Lt+rayWY/mzCAc6BQT7RFyFaZKJ2B7IQ8kYjOCPsF/HGFWjdQkQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 dependencies: + '@grpc/grpc-js': 1.12.6 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/exporter-metrics-otlp-proto@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-m9aEOzKkjznNxm+0NbyEV834Wza9asRaFA4VyWY3b1XltqbdStRmOYSZHq0VzcecOe24uD41zFqHweL2fA3y6g==} - engines: {node: '>=14'} + /@opentelemetry/exporter-metrics-otlp-http@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-HFSW10y8lY6BTZecGNpV3GpoSy7eaO0Z6GATwZasnT4bEsILp8UJXNG5OmEsz4SdwCSYvyCbTJdNbZP3/8LGCQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/exporter-trace-otlp-grpc@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-pVkSH20crBwMTqB3nIN4jpQKUEoB0Z94drIHpYyEqs7UBr+I0cpYyOR3bqjA/UasQUMROb3GX8ZX4/9cVRqGBQ==} - engines: {node: '>=14'} + /@opentelemetry/exporter-metrics-otlp-proto@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-OZnhyd9npU7QbyuHXFEPVm3LnjZYifuKpT3kTnF84mXeEQ84pJJZgyLBpU4FSkSwUkt/zbMyNAI7y5+jYTWGIg==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: - '@opentelemetry/api': ^1.0.0 + '@opentelemetry/api': ^1.3.0 dependencies: - '@grpc/grpc-js': 1.12.6 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/exporter-trace-otlp-http@0.203.0(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-ZDiaswNYo0yq/cy1bBLJFe691izEJ6IgNmkjm4C6kE9ub/OMQqDXORx2D2j8fzTBTxONyzusbaZlqtfmyqURPw==} + /@opentelemetry/exporter-prometheus@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-2jLuNuw5m4sUj/SncDf/mFPabUxMZmmYetx5RKIMIQyPnl6G6ooFzfeE8aXNRf8YD1ZXNlCnRPcISxjveGJHNg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@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-metrics': 2.0.1(@opentelemetry/api@1.9.0) + dev: false + + /@opentelemetry/exporter-trace-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-322coOTf81bm6cAA8+ML6A+m4r2xTCdmAZzGNTboPXRzhwPt4JEmovsFAs+grpdarObd68msOJ9FfH3jxM6wqA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 dependencies: + '@grpc/grpc-js': 1.12.6 '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/otlp-transformer': 0.203.0(@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) dev: false - /@opentelemetry/exporter-trace-otlp-http@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-05HcNizx0BxcFKKnS5rwOV+2GevLTVIRA0tRgWYyw4yCgR53Ic/xk83toYKts7kbzcI+dswInUg/4s8oyA+tqg==} - engines: {node: '>=14'} + /@opentelemetry/exporter-trace-otlp-http@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-ZDiaswNYo0yq/cy1bBLJFe691izEJ6IgNmkjm4C6kE9ub/OMQqDXORx2D2j8fzTBTxONyzusbaZlqtfmyqURPw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: - '@opentelemetry/api': ^1.0.0 + '@opentelemetry/api': ^1.3.0 dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@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) dev: false /@opentelemetry/exporter-trace-otlp-http@0.57.0(@opentelemetry/api@1.9.0): @@ -8770,31 +8796,41 @@ packages: '@opentelemetry/sdk-trace-base': 1.30.0(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/exporter-trace-otlp-proto@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-pt6uX0noTQReHXNeEslQv7x311/F1gJzMnp1HD2qgypLRPbXDeMzzeTngRTUaUbP6hqWNtPxuLr4DEoZG+TcEQ==} - engines: {node: '>=14'} + /@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-1xwNTJ86L0aJmWRwENCJlH4LULMG2sOXWIVw+Szta4fkqKVY50Eo4HoVKKq6U9QEytrWCr8+zjw0q/ZOeXpcAQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: - '@opentelemetry/api': ^1.0.0 + '@opentelemetry/api': ^1.3.0 dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@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) dev: false - /@opentelemetry/exporter-zipkin@1.25.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-RmOwSvkimg7ETwJbUOPTMhJm9A9bG1U8s7Zo3ajDh4zM7eYcycQ0dM7FbLD6NXWbI2yj7UY4q8BKinKYBQksyw==} - engines: {node: '>=14'} + /@opentelemetry/exporter-zipkin@2.0.1(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-a9eeyHIipfdxzCfc2XPrE+/TI3wmrZUDFtG2RRXHSbZZULAny7SyybSvaDvS77a7iib5MPiAvluwVvbGTsHxsw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.0.0 dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 + '@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 + dev: false + + /@opentelemetry/host-metrics@0.36.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-14lNY57qa21V3ZOl6xrqLMHR0HGlnPIApR6hr3oCw/Dqs5IzxhTwt2X8Stn82vWJJis7j/ezn11oODsizHj2dQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.9.0 + systeminformation: 5.23.8 dev: false /@opentelemetry/instrumentation-amqplib@0.46.1(@opentelemetry/api@1.9.0): @@ -8811,6 +8847,21 @@ packages: - supports-color dev: false + /@opentelemetry/instrumentation-aws-sdk@0.57.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-RfbyjaeZzX3mPhuaRHlSAQyfX3skfeWOl30jrqSXtE9k0DPdnIqpHhdYS0C/DEDuZbwTmruVJ4cUwMBw5Z6FAg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0)(supports-color@10.0.0) + '@opentelemetry/propagation-utils': 0.31.3(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.36.0 + transitivePeerDependencies: + - supports-color + dev: false + /@opentelemetry/instrumentation-connect@0.43.1(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-ht7YGWQuV5BopMcw5Q2hXn3I8eG8TH0J/kc/GMcW4CuNTgiP6wCu44BOnucJWL3CmFWaRHI//vWyAhaC8BwePw==} engines: {node: '>=14'} @@ -8838,29 +8889,29 @@ packages: - supports-color dev: false - /@opentelemetry/instrumentation-express@0.36.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-ltIE4kIMa+83QjW/p7oe7XCESF29w3FQ9/T1VgShdX7fzm56K2a0xfEX1vF8lnHRGERYxIWX9D086C6gJOjVGA==} + /@opentelemetry/instrumentation-express@0.47.1(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-QNXPTWteDclR2B4pDFpz0TNghgB33UMjUt14B+BZPmtH1MwUFAfLHBaP5If0Z5NZC+jaH8oF2glgYjrmhZWmSw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.49.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 + '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.36.0 transitivePeerDependencies: - supports-color dev: false - /@opentelemetry/instrumentation-express@0.47.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-QNXPTWteDclR2B4pDFpz0TNghgB33UMjUt14B+BZPmtH1MwUFAfLHBaP5If0Z5NZC+jaH8oF2glgYjrmhZWmSw==} - engines: {node: '>=14'} + /@opentelemetry/instrumentation-express@0.52.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-W7pizN0Wh1/cbNhhTf7C62NpyYw7VfCFTYg0DYieSTrtPBT1vmoSZei19wfKLnrMsz3sHayCg0HxCVL2c+cz5w==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0)(supports-color@10.0.0) '@opentelemetry/semantic-conventions': 1.36.0 transitivePeerDependencies: - supports-color @@ -8947,21 +8998,6 @@ packages: - supports-color dev: false - /@opentelemetry/instrumentation-http@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-dG/aevWhaP+7OLv4BQQSEKMJv8GyeOp3Wxl31NHqE8xo9/fYMfEljiZphUHIfyg4gnZ9swMyWjfOQs5GUQe54Q==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - semver: 7.6.3 - transitivePeerDependencies: - - supports-color - dev: false - /@opentelemetry/instrumentation-http@0.57.2(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-1Uz5iJ9ZAlFOiPuwYg29Bf7bJJc/GeoeJIFKJYQf67nTVKFe8RHbEtxgkOmK4UGZNHKXcpW4P8cWBYzBn1USpg==} engines: {node: '>=14'} @@ -9184,23 +9220,6 @@ packages: - supports-color dev: false - /@opentelemetry/instrumentation@0.49.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-0DLtWtaIppuNNRRllSD4bjU8ZIiLp1cDXvJEbp752/Zf+y3gaLNaoGRGIlX4UHhcsrmtL+P2qxi3Hodi8VuKiQ==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.49.1 - '@types/shimmer': 1.0.2 - import-in-the-middle: 1.7.1 - require-in-the-middle: 7.1.1(supports-color@10.0.0) - semver: 7.6.3 - shimmer: 1.2.1 - transitivePeerDependencies: - - supports-color - dev: false - /@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==} engines: {node: '>=14'} @@ -9246,17 +9265,6 @@ packages: '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/otlp-exporter-base@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-z175NXOtX5ihdlshtYBe5RpGeBoTXVCKPPLiQlD6FHvpM4Ch+p2B0yWKYSrBfLH24H9zjJiBdTrtD+hLlfnXEQ==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.0.0 - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) - dev: false - /@opentelemetry/otlp-exporter-base@0.57.0(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-QQl4Ngm3D6H8SDO0EM642ncTxjRsf/HDq7+IWIA0eaEK/NTsJeQ3iYJiZj3F4jkALnvyeM1kkwd+DHtqxTBx9Q==} engines: {node: '>=14'} @@ -9268,17 +9276,17 @@ packages: '@opentelemetry/otlp-transformer': 0.57.0(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/otlp-grpc-exporter-base@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-zo/YrSDmKMjG+vPeA9aBBrsQM9Q/f2zo6N04WMB3yNldJRsgpRBeLLwvAt/Ba7dpehDLOEFBd1i2JCoaFtpCoQ==} - engines: {node: '>=14'} + /@opentelemetry/otlp-grpc-exporter-base@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-te0Ze1ueJF+N/UOFl5jElJW4U0pZXQ8QklgSfJ2linHN0JJsuaHG8IabEUi2iqxY8ZBDlSiz1Trfv5JcjWWWwQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: - '@opentelemetry/api': ^1.0.0 + '@opentelemetry/api': ^1.3.0 dependencies: '@grpc/grpc-js': 1.12.6 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) dev: false /@opentelemetry/otlp-transformer@0.203.0(@opentelemetry/api@1.9.0): @@ -9297,22 +9305,6 @@ packages: protobufjs: 7.3.2 dev: false - /@opentelemetry/otlp-transformer@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-I88uCZSZZtVa0XniRqQWKbjAUm73I8tpEy/uJYPPYw5d7BRdVk0RfTBQw8kSUl01oVWEuqxLDa802222MYyWHg==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.3.0 <1.10.0' - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.52.1 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) - protobufjs: 7.3.2 - dev: false - /@opentelemetry/otlp-transformer@0.57.0(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-yHX7sdwkdAmSa6Jbi3caSLDWy0PCHS1pKQeKz8AIWSyQqL7IojHKgdk9A+7eRd98Z1n9YTdwWSWLnObvIqhEhQ==} engines: {node: '>=14'} @@ -9329,24 +9321,33 @@ packages: protobufjs: 7.3.2 dev: false - /@opentelemetry/propagator-b3@1.25.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-p6HFscpjrv7//kE+7L+3Vn00VEDUJB0n6ZrjkTYHrJ58QZ8B3ajSJhRbCcY6guQ3PDjTbxWklyvIN2ojVbIb1A==} - engines: {node: '>=14'} + /@opentelemetry/propagation-utils@0.31.3(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-ZI6LKjyo+QYYZY5SO8vfoCQ9A69r1/g+pyjvtu5RSK38npINN1evEmwqbqhbg2CdcIK3a4PN6pDAJz/yC5/gAA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + dependencies: + '@opentelemetry/api': 1.9.0 + dev: false + + /@opentelemetry/propagator-b3@2.0.1(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-Hc09CaQ8Tf5AGLmf449H726uRoBNGPBL4bjr7AnnUpzWMvhdn61F78z9qb6IqB737TffBsokGAK1XykFEZ1igw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/propagator-jaeger@1.25.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-nBprRf0+jlgxks78G/xq72PipVK+4or9Ypntw0gVZYNTCSK8rg5SeaGV19tV920CMqBD/9UIOiFr23Li/Q8tiA==} - engines: {node: '>=14'} + /@opentelemetry/propagator-jaeger@2.0.1(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-7PMdPBmGVH2eQNb/AtSJizQNgeNTfh6jQFqys6lfhd6P4r+m/nTh3gKPPpaCXVdRQ+z93vfKk+4UGty390283w==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) dev: false /@opentelemetry/redis-common@0.36.2: @@ -9354,15 +9355,16 @@ packages: engines: {node: '>=14'} dev: false - /@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-pkZT+iFYIZsVn6+GzM0kSX+u3MSLCY9md+lIJOoKl/P+gJFfxJte/60Usdp8Ce4rOs8GduUpSPNe1ddGyDT1sQ==} - engines: {node: '>=14'} + /@opentelemetry/resource-detector-aws@2.3.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-PkD/lyXG3B3REq1Y6imBLckljkJYXavtqGYSryAeJYvGOf5Ds3doR+BCGjmKeF6ObAtI5MtpBeUStTDtGtBsWA==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/api': ^1.0.0 dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.36.0 dev: false /@opentelemetry/resources@1.30.0(@opentelemetry/api@1.9.0): @@ -9410,18 +9412,6 @@ packages: '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/sdk-logs@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-MBYh+WcPPsN8YpRHRmK1Hsca9pVlyyKd4BxOC4SsgHACnl/bPp4Cri9hWhVm5+2tiQ9Zf4qSc1Jshw9tOLGWQA==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.4.0 <1.10.0' - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.52.1 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - dev: false - /@opentelemetry/sdk-logs@0.57.0(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-6Kbxdu/QE9LWH7+WSLmYo3DjAq+c55TiCLXiXu6b/2m2muy5SyOG2m0MrGqetyRpfYSSbIqHmJoqNVTN3+2a9g==} engines: {node: '>=14'} @@ -9434,18 +9424,6 @@ packages: '@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/sdk-metrics@1.25.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-9Mb7q5ioFL4E4dDrc4wC/A3NTHDat44v4I3p2pLPSxRvqUbDIQyMVr9uK+EU69+HWhlET1VaSrRzwdckWqY15Q==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.3.0 <1.10.0' - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - lodash.merge: 4.6.2 - dev: false - /@opentelemetry/sdk-metrics@1.30.0(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-5kcj6APyRMvv6dEIP5plz2qfJAD4OMipBRT11u/pa1a68rHKI2Ln+iXVkAGKgx8o7CXbD7FdPypTUY88ZQgP4Q==} engines: {node: '>=14'} @@ -9468,42 +9446,39 @@ packages: '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) dev: false - /@opentelemetry/sdk-node@0.52.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-uEG+gtEr6eKd8CVWeKMhH2olcCHM9dEK68pe0qE0be32BcCRsvYURhHaD1Srngh1SQcnQzZ4TP324euxqtBOJA==} - engines: {node: '>=14'} + /@opentelemetry/sdk-node@0.203.0(@opentelemetry/api@1.9.0): + resolution: {integrity: sha512-zRMvrZGhGVMvAbbjiNQW3eKzW/073dlrSiAKPVWmkoQzah9wfynpVPeL55f9fVIm0GaBxTLcPeukWGy0/Wj7KQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.52.1 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-grpc': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-http': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-proto': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-zipkin': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-node': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 + '@opentelemetry/api-logs': 0.203.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-grpc': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-grpc': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-prometheus': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-grpc': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-zipkin': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0)(supports-color@10.0.0) + '@opentelemetry/propagator-b3': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-jaeger': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.36.0 transitivePeerDependencies: - supports-color dev: false - /@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - dev: false - /@opentelemetry/sdk-trace-base@1.30.0(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-RKQDaDIkV7PwizmHw+rE/FgfB2a6MBx+AEVVlAHXRG1YYxLiBpPX2KhmoB99R5vA4b72iJrjle68NDWnbrE9Dg==} engines: {node: '>=14'} @@ -9540,21 +9515,6 @@ packages: '@opentelemetry/semantic-conventions': 1.36.0 dev: false - /@opentelemetry/sdk-trace-node@1.25.1(@opentelemetry/api@1.9.0): - resolution: {integrity: sha512-nMcjFIKxnFqoez4gUmihdBrbpsEnAX/Xj16sGvZm+guceYE0NE00vLhpDVK6f3q8Q4VFI5xG8JjlXKMB/SkTTQ==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-b3': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-jaeger': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) - semver: 7.6.3 - dev: false - /@opentelemetry/sdk-trace-node@2.0.1(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-UhdbPF19pMpBtCWYP5lHbTogLWx9N0EBxtdagvkn5YtsAnCBZzL7SjktG+ZmupRgifsHMjwUaCCaVmqGfSADmA==} engines: {node: ^18.19.0 || >=20.6.0} @@ -18151,10 +18111,6 @@ packages: '@types/node': 20.14.14 dev: true - /@types/shimmer@1.0.2: - resolution: {integrity: sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg==} - dev: false - /@types/shimmer@1.2.0: resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} dev: false @@ -18591,7 +18547,7 @@ packages: resolution: {integrity: sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ==} dev: true - /@vercel/otel@1.13.0(@opentelemetry/api-logs@0.203.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.203.0)(@opentelemetry/resources@1.25.1)(@opentelemetry/sdk-logs@0.203.0)(@opentelemetry/sdk-metrics@1.25.1)(@opentelemetry/sdk-trace-base@1.25.1): + /@vercel/otel@1.13.0(@opentelemetry/api-logs@0.203.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.203.0)(@opentelemetry/resources@1.30.1)(@opentelemetry/sdk-logs@0.203.0)(@opentelemetry/sdk-metrics@1.30.0)(@opentelemetry/sdk-trace-base@1.30.1): resolution: {integrity: sha512-esRkt470Y2jRK1B1g7S1vkt4Csu44gp83Zpu8rIyPoqy2BKgk4z7ik1uSMswzi45UogLHFl6yR5TauDurBQi4Q==} engines: {node: '>=18'} peerDependencies: @@ -18606,10 +18562,10 @@ packages: '@opentelemetry/api': 1.9.0 '@opentelemetry/api-logs': 0.203.0 '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0)(supports-color@10.0.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 1.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) dev: false /@vercel/postgres@0.10.0: @@ -24583,15 +24539,6 @@ packages: module-details-from-path: 1.0.3 dev: false - /import-in-the-middle@1.7.1: - resolution: {integrity: sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==} - dependencies: - acorn: 8.14.1 - acorn-import-assertions: 1.9.0(acorn@8.14.1) - cjs-module-lexer: 1.2.3 - module-details-from-path: 1.0.3 - dev: false - /import-meta-resolve@4.1.0: resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} dev: false @@ -31891,6 +31838,13 @@ packages: tslib: 2.8.1 dev: true + /systeminformation@5.23.8: + resolution: {integrity: sha512-Osd24mNKe6jr/YoXLLK3k8TMdzaxDffhpCxgkfgBHcapykIkd50HXThM3TCEuHO2pPuCsSx2ms/SunqhU5MmsQ==} + engines: {node: '>=8.0.0'} + os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] + hasBin: true + dev: false + /table@6.9.0: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} From 64cd327558790b725feedb0a152475751b5f5e82 Mon Sep 17 00:00:00 2001 From: nicktrn <55853254+nicktrn@users.noreply.github.com> Date: Fri, 29 Aug 2025 18:12:11 +0100 Subject: [PATCH 2/4] add env var to disable additional detectors --- apps/webapp/app/env.server.ts | 1 + apps/webapp/app/v3/tracer.server.ts | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/apps/webapp/app/env.server.ts b/apps/webapp/app/env.server.ts index b3d69e1760..f20c02f6a8 100644 --- a/apps/webapp/app/env.server.ts +++ b/apps/webapp/app/env.server.ts @@ -354,6 +354,7 @@ const EnvironmentSchema = z.object({ INTERNAL_OTEL_METRIC_EXPORTER_INTERVAL_MS: z.coerce.number().int().default(30_000), INTERNAL_OTEL_HOST_METRICS_ENABLED: BoolEnv.default(true), INTERNAL_OTEL_NODEJS_METRICS_ENABLED: BoolEnv.default(true), + INTERNAL_OTEL_ADDITIONAL_DETECTORS_ENABLED: BoolEnv.default(true), ORG_SLACK_INTEGRATION_CLIENT_ID: z.string().optional(), ORG_SLACK_INTEGRATION_CLIENT_SECRET: z.string().optional(), diff --git a/apps/webapp/app/v3/tracer.server.ts b/apps/webapp/app/v3/tracer.server.ts index fb332ceb80..1218e16276 100644 --- a/apps/webapp/app/v3/tracer.server.ts +++ b/apps/webapp/app/v3/tracer.server.ts @@ -36,7 +36,7 @@ import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions"; import { PrismaInstrumentation } from "@prisma/instrumentation"; import { HostMetrics } from "@opentelemetry/host-metrics"; -import { AwsInstrumentation } from "@opentelemetry/instrumentation-aws-sdk"; +import { AwsInstrumentation as AwsSdkInstrumentation } from "@opentelemetry/instrumentation-aws-sdk"; import { awsEcsDetector, awsEc2Detector } from "@opentelemetry/resource-detector-aws"; import { detectResources, @@ -45,6 +45,7 @@ import { osDetector, hostDetector, processDetector, + type ResourceDetector, } from "@opentelemetry/resources"; import { env } from "~/env.server"; import type { AuthenticatedEnvironment } from "~/services/apiAuth.server"; @@ -171,16 +172,13 @@ export async function emitWarnLog(message: string, params: Record Date: Fri, 29 Aug 2025 23:52:26 +0100 Subject: [PATCH 3/4] expose more prisma metrics --- apps/webapp/app/v3/tracer.server.ts | 196 ++++++++++++++++++++++++++-- 1 file changed, 184 insertions(+), 12 deletions(-) diff --git a/apps/webapp/app/v3/tracer.server.ts b/apps/webapp/app/v3/tracer.server.ts index 1218e16276..d084f78a7f 100644 --- a/apps/webapp/app/v3/tracer.server.ts +++ b/apps/webapp/app/v3/tracer.server.ts @@ -56,6 +56,7 @@ import { logger } from "~/services/logger.server"; import { flattenAttributes } from "@trigger.dev/core/v3"; import { prisma } from "~/db.server"; import { metricsRegister } from "~/metrics.server"; +import type { Prisma } from "@trigger.dev/database"; export const SEMINTATTRS_FORCE_RECORDING = "forceRecording"; @@ -336,6 +337,33 @@ function setupMetrics() { } function configurePrismaMetrics({ meter }: { meter: Meter }) { + // Counters + const queriesTotal = meter.createObservableCounter("db.client.queries.total", { + description: "Total number of Prisma Client queries executed", + unit: "queries", + }); + const datasourceQueriesTotal = meter.createObservableCounter("db.datasource.queries.total", { + description: "Total number of datasource queries executed", + unit: "queries", + }); + const connectionsOpenedTotal = meter.createObservableCounter("db.pool.connections.opened.total", { + description: "Total number of pool connections opened", + unit: "connections", + }); + const connectionsClosedTotal = meter.createObservableCounter("db.pool.connections.closed.total", { + description: "Total number of pool connections closed", + unit: "connections", + }); + + // Gauges + const queriesActive = meter.createObservableGauge("db.client.queries.active", { + description: "Number of currently active Prisma Client queries", + unit: "queries", + }); + const queriesWait = meter.createObservableGauge("db.client.queries.wait", { + description: "Number of queries currently waiting for a connection", + unit: "queries", + }); const totalGauge = meter.createObservableGauge("db.pool.connections.total", { description: "Open Prisma-pool connections", unit: "connections", @@ -349,26 +377,170 @@ function configurePrismaMetrics({ meter }: { meter: Meter }) { unit: "connections", }); + // Histogram statistics as gauges + const queriesWaitTimeCount = meter.createObservableGauge("db.client.queries.wait_time.count", { + description: "Number of wait time observations", + unit: "observations", + }); + const queriesWaitTimeSum = meter.createObservableGauge("db.client.queries.wait_time.sum", { + description: "Total wait time across all observations", + unit: "ms", + }); + const queriesWaitTimeMean = meter.createObservableGauge("db.client.queries.wait_time.mean", { + description: "Average wait time for a connection", + unit: "ms", + }); + + const queriesDurationCount = meter.createObservableGauge("db.client.queries.duration.count", { + description: "Number of query duration observations", + unit: "observations", + }); + const queriesDurationSum = meter.createObservableGauge("db.client.queries.duration.sum", { + description: "Total query duration across all observations", + unit: "ms", + }); + const queriesDurationMean = meter.createObservableGauge("db.client.queries.duration.mean", { + description: "Average duration of Prisma Client queries", + unit: "ms", + }); + + const datasourceQueriesDurationCount = meter.createObservableGauge( + "db.datasource.queries.duration.count", + { + description: "Number of datasource query duration observations", + unit: "observations", + } + ); + const datasourceQueriesDurationSum = meter.createObservableGauge( + "db.datasource.queries.duration.sum", + { + description: "Total datasource query duration across all observations", + unit: "ms", + } + ); + const datasourceQueriesDurationMean = meter.createObservableGauge( + "db.datasource.queries.duration.mean", + { + description: "Average duration of datasource queries", + unit: "ms", + } + ); + // Single helper so we hit Prisma only once per scrape --------------------- - async function readPoolCounters() { - const { gauges } = await prisma.$metrics.json(); + async function readPrismaMetrics() { + const metrics = await prisma.$metrics.json(); + + // Extract counter values + const counters: Record = {}; + for (const counter of metrics.counters) { + counters[counter.key] = counter.value; + } - const busy = gauges.find((g) => g.key === "prisma_pool_connections_busy")?.value ?? 0; - const free = gauges.find((g) => g.key === "prisma_pool_connections_idle")?.value ?? 0; - const total = - gauges.find((g) => g.key === "prisma_pool_connections_open")?.value ?? busy + free; // fallback compute + // Extract gauge values + const gauges: Record = {}; + for (const gauge of metrics.gauges) { + gauges[gauge.key] = gauge.value; + } + + // Extract histogram values + const histograms: Record = {}; + for (const histogram of metrics.histograms) { + histograms[histogram.key] = histogram.value; + } - return { total, busy, free }; + return { + counters: { + queriesTotal: counters["prisma_client_queries_total"] ?? 0, + datasourceQueriesTotal: counters["prisma_datasource_queries_total"] ?? 0, + connectionsOpenedTotal: counters["prisma_pool_connections_opened_total"] ?? 0, + connectionsClosedTotal: counters["prisma_pool_connections_closed_total"] ?? 0, + }, + gauges: { + queriesActive: gauges["prisma_client_queries_active"] ?? 0, + queriesWait: gauges["prisma_client_queries_wait"] ?? 0, + connectionsOpen: gauges["prisma_pool_connections_open"] ?? 0, + connectionsBusy: gauges["prisma_pool_connections_busy"] ?? 0, + connectionsIdle: gauges["prisma_pool_connections_idle"] ?? 0, + }, + histograms: { + queriesWait: histograms["prisma_client_queries_wait_histogram_ms"], + queriesDuration: histograms["prisma_client_queries_duration_histogram_ms"], + datasourceQueriesDuration: histograms["prisma_datasource_queries_duration_histogram_ms"], + }, + }; } meter.addBatchObservableCallback( async (res) => { - const { total, busy, free } = await readPoolCounters(); - res.observe(totalGauge, total); - res.observe(busyGauge, busy); - res.observe(freeGauge, free); + const { counters, gauges, histograms } = await readPrismaMetrics(); + + // Observe counters + res.observe(queriesTotal, counters.queriesTotal); + res.observe(datasourceQueriesTotal, counters.datasourceQueriesTotal); + res.observe(connectionsOpenedTotal, counters.connectionsOpenedTotal); + res.observe(connectionsClosedTotal, counters.connectionsClosedTotal); + + // Observe gauges + res.observe(queriesActive, gauges.queriesActive); + res.observe(queriesWait, gauges.queriesWait); + res.observe(totalGauge, gauges.connectionsOpen); + res.observe(busyGauge, gauges.connectionsBusy); + res.observe(freeGauge, gauges.connectionsIdle); + + // Observe histogram statistics as gauges + if (histograms.queriesWait) { + res.observe(queriesWaitTimeCount, histograms.queriesWait.count); + res.observe(queriesWaitTimeSum, histograms.queriesWait.sum); + res.observe( + queriesWaitTimeMean, + histograms.queriesWait.count > 0 + ? histograms.queriesWait.sum / histograms.queriesWait.count + : 0 + ); + } + + if (histograms.queriesDuration) { + res.observe(queriesDurationCount, histograms.queriesDuration.count); + res.observe(queriesDurationSum, histograms.queriesDuration.sum); + res.observe( + queriesDurationMean, + histograms.queriesDuration.count > 0 + ? histograms.queriesDuration.sum / histograms.queriesDuration.count + : 0 + ); + } + + if (histograms.datasourceQueriesDuration) { + res.observe(datasourceQueriesDurationCount, histograms.datasourceQueriesDuration.count); + res.observe(datasourceQueriesDurationSum, histograms.datasourceQueriesDuration.sum); + res.observe( + datasourceQueriesDurationMean, + histograms.datasourceQueriesDuration.count > 0 + ? histograms.datasourceQueriesDuration.sum / histograms.datasourceQueriesDuration.count + : 0 + ); + } }, - [totalGauge, busyGauge, freeGauge] + [ + queriesTotal, + datasourceQueriesTotal, + connectionsOpenedTotal, + connectionsClosedTotal, + queriesActive, + queriesWait, + totalGauge, + busyGauge, + freeGauge, + queriesWaitTimeCount, + queriesWaitTimeSum, + queriesWaitTimeMean, + queriesDurationCount, + queriesDurationSum, + queriesDurationMean, + datasourceQueriesDurationCount, + datasourceQueriesDurationSum, + datasourceQueriesDurationMean, + ] ); } From 3be86eb1a021a95094b5b3c08944df740f2eb1e4 Mon Sep 17 00:00:00 2001 From: nicktrn <55853254+nicktrn@users.noreply.github.com> Date: Mon, 1 Sep 2025 12:30:01 +0100 Subject: [PATCH 4/4] chore(webapp): drop node 16 support --- apps/webapp/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/webapp/package.json b/apps/webapp/package.json index 8c48dac819..a09bcc5a66 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -281,6 +281,6 @@ "vite-tsconfig-paths": "^4.0.5" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.19.0 || >=20.6.0" } }