diff --git a/.changeset/posthog-node-metrics-autocapture.md b/.changeset/posthog-node-metrics-autocapture.md new file mode 100644 index 0000000000..37284b4fc4 --- /dev/null +++ b/.changeset/posthog-node-metrics-autocapture.md @@ -0,0 +1,5 @@ +--- +'posthog-node': minor +--- + +Add `metrics.autocapture`: HTTP, database and runtime metrics from the official OpenTelemetry instrumentations, with no instrumentation code. Start the app with `node --import posthog-node/metrics/register` to measure every library it loads. diff --git a/packages/node/package.json b/packages/node/package.json index 1a391fd3e9..4d9bf242e8 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -17,6 +17,7 @@ "lint:fix": "oxlint --report-unused-disable-directives-severity error src --fix", "test:unit": "vitest run", "test:edge-compat": "vitest run --config vitest.edge.config.ts", + "test:built": "node --test scripts/check-metrics-register.mjs", "prebuild": "node ../../tooling/write-version.mjs", "build": "rslib build", "dev": "rslib build -w", @@ -47,22 +48,52 @@ }, "devDependencies": { "@edge-runtime/vm": "^5.0.0", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/auto-instrumentations-node": "^0.80.0", + "@opentelemetry/exporter-metrics-otlp-proto": "^0.222.0", + "@opentelemetry/resources": "^2.11.0", + "@opentelemetry/sdk-metrics": "^2.11.0", + "@opentelemetry/sdk-trace-base": "^2.10.0", "@posthog-tooling/tsconfig-base": "workspace:*", "@posthog/types": "workspace:^", "@rslib/core": "catalog:", "@types/express": "^5.0.6", "@types/node": "^20.0.0", - "rxjs": "^7.8.0", "@vitest/coverage-v8": "catalog:", - "vitest": "catalog:", - "typescript": "catalog:native" + "rxjs": "^7.8.0", + "typescript": "catalog:native", + "vitest": "catalog:" }, "peerDependencies": { - "rxjs": "^7.0.0" + "rxjs": "^7.0.0", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/sdk-metrics": "^2.0.0", + "@opentelemetry/sdk-trace-base": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/exporter-metrics-otlp-proto": ">=0.200.0 <1", + "@opentelemetry/auto-instrumentations-node": ">=0.80.0 <1" }, "peerDependenciesMeta": { "rxjs": { "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/sdk-metrics": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { + "optional": true + }, + "@opentelemetry/resources": { + "optional": true + }, + "@opentelemetry/exporter-metrics-otlp-proto": { + "optional": true + }, + "@opentelemetry/auto-instrumentations-node": { + "optional": true } }, "keywords": [ @@ -113,6 +144,12 @@ "import": "./dist/experimental.mjs", "require": "./dist/experimental.js", "default": "./dist/experimental.js" + }, + "./metrics/register": { + "types": "./dist/entrypoints/metrics-register.node.d.ts", + "import": "./dist/entrypoints/metrics-register.node.mjs", + "require": "./dist/entrypoints/metrics-register.node.js", + "default": "./dist/entrypoints/metrics-register.node.js" } } } diff --git a/packages/node/references/posthog-node-references-latest.json b/packages/node/references/posthog-node-references-latest.json index 295507a5d1..8b23527925 100644 --- a/packages/node/references/posthog-node-references-latest.json +++ b/packages/node/references/posthog-node-references-latest.json @@ -1200,6 +1200,28 @@ }, "path": "src/entrypoints/index.node.ts" }, + { + "category": "Privacy", + "description": "Opt the client back in (same as `enable()`). Autocaptured metrics recorded while opted out are dropped, not sent.", + "details": null, + "id": "optIn", + "showDocs": true, + "title": "optIn", + "examples": [ + { + "id": "optin", + "name": "Generated example for optIn", + "code": "// Generated example for optIn\nposthog.optIn();" + } + ], + "releaseTag": "public", + "params": [], + "returnType": { + "id": "Promise", + "name": "Promise" + }, + "path": "src/entrypoints/index.node.ts" + }, { "category": "Feature flags", "description": "Override feature flags locally. Useful for testing and local development. Overridden flags take precedence over both local evaluation and remote evaluation.", @@ -1629,27 +1651,6 @@ }, "path": "src/entrypoints/index.node.ts" }, - { - "category": "", - "details": null, - "id": "optIn", - "showDocs": true, - "title": "optIn", - "examples": [ - { - "id": "optin", - "name": "Generated example for optIn", - "code": "// Generated example for optIn\nposthog.optIn();" - } - ], - "releaseTag": "public", - "params": [], - "returnType": { - "id": "Promise", - "name": "Promise" - }, - "path": "src/entrypoints/index.node.ts" - }, { "category": "", "details": null, @@ -2805,6 +2806,34 @@ ], "path": "../core/src/error-tracking/types.ts" }, + { + "id": "MetricsAutocaptureConfig", + "name": "MetricsAutocaptureConfig", + "properties": [ + { + "description": "`http.server.request.duration` and `http.client.request.duration` for `http`, `https` and `fetch`.", + "type": "boolean", + "name": "http" + }, + { + "description": "`db.client.operation.duration` and connection metrics for pg, mysql, mysql2, mongodb, redis, ioredis and more.", + "type": "boolean", + "name": "db" + }, + { + "description": "Event loop, heap and garbage collection metrics.", + "type": "boolean", + "name": "runtime" + } + ], + "path": "src/types.ts" + }, + { + "id": "MetricsAutocaptureHandle", + "name": "MetricsAutocaptureHandle", + "properties": [], + "path": "src/client.ts" + }, { "id": "MiddlewareError", "name": "MiddlewareError", @@ -2906,6 +2935,53 @@ ], "path": "../core/src/types.ts" }, + { + "id": "NodeMetricsConfig", + "name": "NodeMetricsConfig", + "properties": [ + { + "description": "The service name for metric series.\nMaps to the OTel resource attribute 'service.name'.", + "type": "string", + "name": "serviceName" + }, + { + "description": "The deployment environment for metric series (e.g. 'production', 'staging').\nMaps to the OTel resource attribute 'deployment.environment'.", + "type": "string", + "name": "environment" + }, + { + "description": "The service version for metric series (e.g. '1.2.3').\nMaps to the OTel resource attribute 'service.version'.", + "type": "string", + "name": "serviceVersion" + }, + { + "description": "Additional resource attributes applied to every metrics batch.\nThese describe the service/deployment, not individual series.\nNamed fields (serviceName, environment, serviceVersion) are set first;\nresourceAttributes can override them.", + "type": "MetricAttributes", + "name": "resourceAttributes" + }, + { + "description": "How often the aggregated window is flushed, in milliseconds. Samples\nare folded into per-series aggregates in memory between flushes — one\ndata point per series per window, no matter how many calls.", + "type": "number", + "name": "flushIntervalMs" + }, + { + "description": "Cardinality guardrail: maximum distinct series (name + type + unit +\nattribute combination) held per flush window. Samples for series\nbeyond the cap are dropped with a single warning per window.", + "type": "number", + "name": "maxSeriesPerFlush" + }, + { + "description": "Pre-aggregation filter for metric samples, as a single function or a\nleft-to-right chain. Each function inspects, mutates, or drops a\nsample (return `null` to drop) before it is aggregated.", + "type": "BeforeSendMetricFn | BeforeSendMetricFn[]", + "name": "beforeSend" + }, + { + "description": "Capture HTTP, database and runtime metrics with no instrumentation code, using\nthe official OpenTelemetry instrumentations. Needs the OpenTelemetry peer\npackages (`npm install", + "type": "boolean | MetricsAutocaptureConfig", + "name": "autocapture" + } + ], + "path": "src/types.ts" + }, { "id": "ObjectLike", "name": "ObjectLike", @@ -3707,7 +3783,7 @@ }, { "description": "Configuration for the `posthog.metrics` API (count, gauge, histogram).\nSet `serviceName` so series can be filtered per service in the Metrics UI.", - "type": "MetricsConfig", + "type": "NodeMetricsConfig", "name": "metrics" }, { diff --git a/packages/node/scripts/check-metrics-register.mjs b/packages/node/scripts/check-metrics-register.mjs new file mode 100644 index 0000000000..376746dd81 --- /dev/null +++ b/packages/node/scripts/check-metrics-register.mjs @@ -0,0 +1,95 @@ +// Runs the built `posthog-node/metrics/register` entrypoint the documented way +// (`node --import`) against a fake PostHog host. Covers what in-process tests +// cannot: the package export, the ESM loader hook and the flush on SIGTERM. +import assert from 'node:assert/strict' +import { spawn } from 'node:child_process' +import { mkdtempSync, rmSync, writeFileSync } from 'node:fs' +import { createServer } from 'node:http' +import { tmpdir } from 'node:os' +import path from 'node:path' +import { test } from 'node:test' +import { fileURLToPath } from 'node:url' + +const packageDir = fileURLToPath(new URL('..', import.meta.url)) + +const APP = ` +import { createServer } from 'node:http' + +const server = createServer((_request, response) => response.end('ok')) +server.listen(0, '127.0.0.1', async () => { + const { port } = server.address() + await fetch('http://127.0.0.1:' + port + '/') + console.log('ready') +}) +` + +async function startFakePostHog(t) { + const requests = [] + const server = createServer((request, response) => { + const chunks = [] + request.on('data', (chunk) => chunks.push(chunk)) + request.on('end', () => { + requests.push({ + method: request.method, + url: request.url, + authorization: request.headers.authorization, + body: Buffer.concat(chunks), + }) + response.end() + }) + }) + await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)) + t.after(() => server.close()) + return { requests, host: `http://127.0.0.1:${server.address().port}` } +} + +test('flushes autocaptured metrics to the host when the process gets SIGTERM', async (t) => { + const fakePostHog = await startFakePostHog(t) + const dir = mkdtempSync(path.join(tmpdir(), 'posthog-metrics-register-')) + t.after(() => rmSync(dir, { recursive: true, force: true })) + const app = path.join(dir, 'app.mjs') + writeFileSync(app, APP) + + // Resolved from the package directory, so the package's own `exports` and its + // OpenTelemetry dev dependencies are used. + const child = spawn(process.execPath, ['--import', 'posthog-node/metrics/register', app], { + cwd: packageDir, + env: { + ...process.env, + POSTHOG_PROJECT_TOKEN: 'phc_test', + // The trailing slash must not change the export path. + POSTHOG_HOST: `${fakePostHog.host}/`, + OTEL_SERVICE_NAME: 'metrics-register-test', + }, + stdio: ['ignore', 'pipe', 'pipe'], + }) + let stderr = '' + child.stderr.on('data', (chunk) => (stderr += chunk)) + const exited = new Promise((resolve) => child.on('exit', (code, signal) => resolve({ code, signal }))) + t.after(() => child.kill('SIGKILL')) + + await new Promise((resolve, reject) => { + child.stdout.on('data', (chunk) => String(chunk).includes('ready') && resolve()) + child.on('exit', () => reject(new Error(`app exited before it was ready: ${stderr}`))) + }) + // The export interval is 10s, so only the shutdown flush can send before this. + child.kill('SIGTERM') + + assert.deepEqual(await exited, { code: null, signal: 'SIGTERM' }, stderr) + const exports = fakePostHog.requests.filter((request) => request.url === '/i/v1/metrics') + assert.ok(exports.length > 0, `requests: ${JSON.stringify(fakePostHog.requests.map((r) => r.url))}`) + for (const metricsExport of exports) { + assert.equal(metricsExport.method, 'POST') + assert.equal(metricsExport.authorization, 'Bearer phc_test') + } + const body = Buffer.concat(exports.map((metricsExport) => metricsExport.body)).toString('latin1') + // Protobuf keeps strings as raw bytes. + for (const expected of [ + 'metrics-register-test', + 'posthog-node', + 'http.server.request.duration', + 'http.client.request.duration', + ]) { + assert.ok(body.includes(expected), `export is missing ${expected}`) + } +}) diff --git a/packages/node/src/__tests__/metrics-autocapture.spec.ts b/packages/node/src/__tests__/metrics-autocapture.spec.ts new file mode 100644 index 0000000000..0f017296b2 --- /dev/null +++ b/packages/node/src/__tests__/metrics-autocapture.spec.ts @@ -0,0 +1,469 @@ +import { createServer, type IncomingMessage, type Server } from 'node:http' +import type { AddressInfo } from 'node:net' +import { createRequire } from 'node:module' +import { metrics as otelMetrics, SpanKind, SpanStatusCode } from '@opentelemetry/api' +import { + AggregationTemporality, + InMemoryMetricExporter, + MeterProvider, + PeriodicExportingMetricReader, + type ResourceMetrics, +} from '@opentelemetry/sdk-metrics' +import type { ReadableSpan } from '@opentelemetry/sdk-trace-base' + +import { PostHog } from '@/entrypoints/index.node' +import { + createDbSpanMetricsProcessor, + DB_METRIC_VIEWS, + startMetricsAutocapture, + type MetricsAutocapture, + type MetricsAutocaptureOptions, +} from '@/extensions/metrics-autocapture.node' + +vi.mock('../version', () => ({ version: '1.2.3' })) + +const requireForTest = createRequire(import.meta.url) + +type Received = { path: string; headers: IncomingMessage['headers']; body: Buffer } + +const listen = async ( + handler?: (req: IncomingMessage, body: Buffer) => void +): Promise<{ server: Server; url: string }> => { + const server = createServer((req, res) => { + const chunks: Buffer[] = [] + req.on('data', (chunk) => chunks.push(chunk)) + req.on('end', () => { + handler?.(req, Buffer.concat(chunks)) + res.writeHead(200, { 'content-type': 'application/json' }) + res.end('{}') + }) + }) + await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)) + return { server, url: `http://127.0.0.1:${(server.address() as AddressInfo).port}` } +} + +const close = (server: Server): Promise => + new Promise((resolve) => { + server.closeAllConnections() + server.close(() => resolve()) + }) + +const httpGet = (url: string): Promise => + new Promise((resolve, reject) => { + // Required after autocapture starts, so the patched core module is used. + const http = requireForTest('node:http') as typeof import('node:http') + http + .get(url, (res) => { + res.resume() + res.on('end', () => resolve()) + }) + .on('error', reject) + }) + +const logger = (): MetricsAutocaptureOptions['logger'] & { warn: ReturnType } => { + const l: any = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), critical: vi.fn() } + l.createLogger = () => l + return l +} + +const metricNames = (batches: ResourceMetrics[]): string[] => + batches.flatMap((batch) => batch.scopeMetrics.flatMap((scope) => scope.metrics.map((m) => m.descriptor.name))) + +const dataPoints = (batches: ResourceMetrics[], name: string): { attributes: Record }[] => + batches.flatMap((batch) => + batch.scopeMetrics.flatMap((scope) => + scope.metrics.filter((m) => m.descriptor.name === name).flatMap((m) => m.dataPoints as any[]) + ) + ) + +describe('metrics autocapture', () => { + beforeEach(() => { + vi.useRealTimers() + }) + + describe('startMetricsAutocapture', () => { + let posthogHost: { server: Server; url: string } + let appServer: { server: Server; url: string } + let received: Received[] + let autocapture: MetricsAutocapture | undefined + let exporter: InMemoryMetricExporter + + const start = (overrides: Partial = {}, useInMemoryReader = true): void => { + exporter = new InMemoryMetricExporter(AggregationTemporality.DELTA) + autocapture = startMetricsAutocapture( + { + host: posthogHost.url, + apiKey: 'phc_test_token', + config: { http: true, db: true, runtime: true }, + serviceName: 'checkout-api', + resourceAttributes: { 'deployment.environment': 'test' }, + distroVersion: '1.2.3', + logger: logger(), + isEnabled: () => true, + ...overrides, + }, + useInMemoryReader + ? { metricReader: new PeriodicExportingMetricReader({ exporter, exportIntervalMillis: 60_000 }) } + : {} + ) + } + + beforeEach(async () => { + received = [] + posthogHost = await listen((req, body) => received.push({ path: req.url!, headers: req.headers, body })) + appServer = await listen() + }) + + afterEach(async () => { + await autocapture?.shutdown() + autocapture = undefined + await close(posthogHost.server) + await close(appServer.server) + }) + + // First, so it sees freshly built instrumentations, as an app does. + it('records fetch requests', async () => { + start() + await fetch(`${appServer.url}/health`) + + await autocapture!.forceFlush() + const ports = dataPoints(exporter.getMetrics(), 'http.client.request.duration').map( + (point) => point.attributes['server.port'] + ) + expect(ports).toContain(Number(new URL(appServer.url).port)) + }) + + it('records HTTP server and client request durations', async () => { + start() + // A server created after autocapture starts, from the patched module. + const http = requireForTest('node:http') as typeof import('node:http') + const server = http.createServer((_req, res) => res.end('ok')) + await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)) + await httpGet(`http://127.0.0.1:${(server.address() as AddressInfo).port}/orders`) + await new Promise((resolve) => server.close(() => resolve())) + + await autocapture!.forceFlush() + const names = metricNames(exporter.getMetrics()) + expect(names).toContain('http.server.request.duration') + expect(names).toContain('http.client.request.duration') + }) + + it('does not record requests to the PostHog host, over http or fetch', async () => { + start() + await httpGet(`${posthogHost.url}/i/v1/metrics`) + await fetch(`${posthogHost.url}/batch/`, { method: 'POST', body: '{}' }) + await httpGet(`${appServer.url}/health`) + await fetch(`${appServer.url}/health`) + + await autocapture!.forceFlush() + const ports = dataPoints(exporter.getMetrics(), 'http.client.request.duration').map( + (point) => point.attributes['server.port'] + ) + const hostPort = Number(new URL(posthogHost.url).port) + const appPort = Number(new URL(appServer.url).port) + expect(ports).toContain(appPort) + expect(ports).not.toContain(hostPort) + }) + + it('exports the runtime gauges in the last window on shutdown', async () => { + start({ config: { http: false, db: false, runtime: true } }, false) + + await autocapture!.shutdown() + const body = received + .filter((r) => r.path === '/i/v1/metrics') + .map((r) => r.body.toString('latin1')) + .join('') + expect(body).toContain('v8js.memory.heap.used') + expect(body).toContain('nodejs.eventloop.utilization') + }) + + it('measures database calls that have no parent span', async () => { + start({ config: { http: false, db: true, runtime: false } }) + + const instrumentations = (globalThis as any)[Symbol.for('posthog-node.metrics-autocapture.instrumentations')] + const ioredis = instrumentations.get('@opentelemetry/instrumentation-ioredis') + expect(ioredis.getConfig()).toMatchObject({ enabled: true, requireParentSpan: false }) + }) + + it('records runtime metrics', async () => { + start({ config: { http: false, db: false, runtime: true } }) + await new Promise((resolve) => setTimeout(resolve, 50)) + + await autocapture!.forceFlush() + const names = metricNames(exporter.getMetrics()) + expect(names.some((name) => name.startsWith('nodejs.eventloop.'))).toBe(true) + expect(names.some((name) => name.startsWith('v8js.'))).toBe(true) + expect(names).not.toContain('http.client.request.duration') + }) + + it('exports OTLP to /i/v1/metrics with the project token and the service resource', async () => { + start({}, false) + await httpGet(`${appServer.url}/health`) + + await autocapture!.forceFlush() + const exports = received.filter((r) => r.path === '/i/v1/metrics') + expect(exports.length).toBeGreaterThan(0) + expect(exports[0].headers['authorization']).toBe('Bearer phc_test_token') + expect(exports[0].headers['content-type']).toBe('application/x-protobuf') + const body = exports.map((r) => r.body.toString('latin1')).join('') + expect(body).toContain('http.client.request.duration') + expect(body).toContain('checkout-api') + expect(body).toContain('telemetry.distro.name') + expect(body).toContain('posthog-node') + expect(body).toContain('deployment.environment') + }) + + it('sends nothing while the client is opted out', async () => { + start({ isEnabled: () => false }, false) + await httpGet(`${appServer.url}/health`) + + await autocapture!.forceFlush() + expect(received.filter((r) => r.path === '/i/v1/metrics')).toHaveLength(0) + }) + + it('warns once and returns undefined when the OpenTelemetry packages are missing', () => { + const log = logger() + const missing = (): never => { + const error: NodeJS.ErrnoException = new Error("Cannot find module '@opentelemetry/sdk-metrics'") + error.code = 'MODULE_NOT_FOUND' + throw error + } + const options: MetricsAutocaptureOptions = { + host: posthogHost.url, + apiKey: 'phc_test_token', + config: { http: true, db: true, runtime: true }, + serviceName: 'checkout-api', + resourceAttributes: {}, + distroVersion: '1.2.3', + logger: log, + isEnabled: () => true, + } + + expect(() => startMetricsAutocapture(options, { load: missing })).not.toThrow() + expect(startMetricsAutocapture(options, { load: missing })).toBeUndefined() + expect(log.warn).toHaveBeenCalledTimes(1) + expect(log.warn.mock.calls[0].join(' ')).toContain('npm install @opentelemetry/') + }) + + it('does not start when the app already set up OpenTelemetry', async () => { + const appProvider = new MeterProvider() + otelMetrics.setGlobalMeterProvider(appProvider) + try { + const log = logger() + start({ logger: log }) + expect(autocapture).toBeUndefined() + expect(log.warn.mock.calls[0].join(' ')).toContain('OpenTelemetry is already set up') + } finally { + otelMetrics.disable() + await appProvider.shutdown() + } + }) + + it('runs once per process, and can start again after shutdown', async () => { + start() + const log = logger() + const second = startMetricsAutocapture({ + host: posthogHost.url, + apiKey: 'phc_test_token', + config: { http: true, db: true, runtime: true }, + serviceName: 'other', + resourceAttributes: {}, + distroVersion: '1.2.3', + logger: log, + isEnabled: () => true, + }) + expect(second).toBeUndefined() + expect(log.warn).toHaveBeenCalledTimes(1) + + await autocapture!.shutdown() + start() + expect(autocapture).toBeDefined() + }) + }) + + describe('createDbSpanMetricsProcessor', () => { + const collect = async (spans: Partial[]): Promise => { + const exporter = new InMemoryMetricExporter(AggregationTemporality.DELTA) + const reader = new PeriodicExportingMetricReader({ exporter, exportIntervalMillis: 60_000 }) + const provider = new MeterProvider({ readers: [reader] }) + const processor = createDbSpanMetricsProcessor(provider.getMeter('test')) + for (const span of spans) { + processor.onEnd({ + kind: SpanKind.CLIENT, + duration: [0, 250_000_000], + status: { code: SpanStatusCode.UNSET }, + instrumentationScope: { name: '@opentelemetry/instrumentation-mysql2' }, + attributes: {}, + ...span, + } as ReadableSpan) + } + await reader.forceFlush() + const metrics = exporter.getMetrics() + await provider.shutdown() + return metrics + } + + it('turns a database client span into a duration histogram without the statement', async () => { + const metrics = await collect([ + { + attributes: { + 'db.system': 'mysql', + 'db.statement': "SELECT * FROM orders WHERE email = 'a@b.c'", + 'db.name': 'shop', + 'net.peer.name': 'db.internal', + }, + }, + ]) + + const points = dataPoints(metrics, 'db.client.operation.duration') as any[] + expect(points).toHaveLength(1) + expect(points[0].attributes).toEqual({ + 'db.system.name': 'mysql', + 'db.operation.name': 'SELECT', + 'db.namespace': 'shop', + 'server.address': 'db.internal', + }) + expect(points[0].value.sum).toBeCloseTo(0.25) + const descriptor = metrics[0].scopeMetrics[0].metrics[0].descriptor + expect(descriptor.unit).toBe('s') + }) + + it('uses the explicit operation and collection, and marks failures', async () => { + const metrics = await collect([ + { + instrumentationScope: { name: '@opentelemetry/instrumentation-mongodb' }, + status: { code: SpanStatusCode.ERROR }, + attributes: { + 'db.system': 'mongodb', + 'db.operation': 'find', + 'db.mongodb.collection': 'orders', + 'db.statement': '{"email":"?"}', + }, + }, + ]) + + const [point] = dataPoints(metrics, 'db.client.operation.duration') + expect(point.attributes).toEqual({ + 'db.system.name': 'mongodb', + 'db.operation.name': 'find', + 'db.collection.name': 'orders', + 'error.type': '_OTHER', + }) + }) + + it('skips spans that are not driver-level database client calls', async () => { + const metrics = await collect([ + // pg records db.client.operation.duration itself. + { + instrumentationScope: { name: '@opentelemetry/instrumentation-pg' }, + attributes: { 'db.system': 'postgresql' }, + }, + // knex wraps a driver span, so counting it would count the query twice. + { instrumentationScope: { name: '@opentelemetry/instrumentation-knex' }, attributes: { 'db.system': 'mysql' } }, + { kind: SpanKind.SERVER, attributes: { 'db.system': 'mysql' } }, + { attributes: { 'http.request.method': 'GET' } }, + ]) + + expect(dataPoints(metrics, 'db.client.operation.duration')).toHaveLength(0) + }) + }) + + describe('DB_METRIC_VIEWS', () => { + it('keeps only the leading word of a native db.operation.name', async () => { + const exporter = new InMemoryMetricExporter(AggregationTemporality.DELTA) + const reader = new PeriodicExportingMetricReader({ exporter, exportIntervalMillis: 60_000 }) + const provider = new MeterProvider({ readers: [reader], views: DB_METRIC_VIEWS }) + // As pg records it: the text before the first space of the statement. + const histogram = provider + .getMeter('@opentelemetry/instrumentation-pg') + .createHistogram('db.client.operation.duration', { + unit: 's', + advice: { explicitBucketBoundaries: [0.001, 0.01, 0.1, 1] }, + }) + histogram.record(0.2, { 'db.system.name': 'postgresql', 'db.operation.name': "SELECT\n'private@example.com'" }) + histogram.record(0.2, { 'db.system.name': 'postgresql', 'db.operation.name': "('private@example.com')" }) + histogram.record(0.2, { 'db.system.name': 'mongodb', 'db.operation.name': 'findAndModify' }) + histogram.record(0.2, { 'db.system.name': 'postgresql' }) + + await reader.forceFlush() + const points = dataPoints(exporter.getMetrics(), 'db.client.operation.duration') as any[] + await provider.shutdown() + expect(points.map((point) => point.attributes)).toEqual([ + { 'db.system.name': 'postgresql', 'db.operation.name': 'SELECT' }, + { 'db.system.name': 'postgresql' }, + { 'db.system.name': 'mongodb', 'db.operation.name': 'findAndModify' }, + ]) + expect(points[0].value.buckets.boundaries).toEqual([0.001, 0.01, 0.1, 1]) + }) + }) + + describe('PostHog client option', () => { + let posthogHost: { server: Server; url: string } + + beforeEach(async () => { + posthogHost = await listen() + }) + + afterEach(async () => { + await close(posthogHost.server) + }) + + const tryStart = (): MetricsAutocapture | undefined => + startMetricsAutocapture({ + host: posthogHost.url, + apiKey: 'phc_test_token', + config: { http: true, db: true, runtime: true }, + serviceName: 'probe', + resourceAttributes: {}, + distroVersion: '1.2.3', + logger: logger(), + isEnabled: () => true, + }) + + it('starts autocapture with metrics.autocapture and stops it on shutdown', async () => { + const posthog = new PostHog('phc_test_token', { host: posthogHost.url, metrics: { autocapture: true } }) + expect(tryStart()).toBeUndefined() + + await posthog.shutdown() + const probe = tryStart() + expect(probe).toBeDefined() + await probe!.shutdown() + }) + + it('drops metrics recorded while opted out when the client opts in again', async () => { + const received: string[] = [] + const host = await listen((req, body) => req.url === '/i/v1/metrics' && received.push(body.toString('latin1'))) + const app = await listen() + const posthog = new PostHog('phc_test_token', { + host: host.url, + defaultOptIn: false, + metrics: { autocapture: { http: true, db: false, runtime: false }, flushIntervalMs: 60_000 }, + }) + try { + await httpGet(`${app.url}/while-opted-out`) + await posthog.optIn() + await posthog.shutdown() + expect(received.join('')).not.toContain('http.client.request.duration') + } finally { + await posthog.shutdown() + await close(host.server) + await close(app.server) + } + }) + + it('does not start autocapture by default or when the client is disabled', async () => { + const plain = new PostHog('phc_test_token', { host: posthogHost.url }) + const disabled = new PostHog('phc_test_token', { + host: posthogHost.url, + disabled: true, + metrics: { autocapture: true }, + }) + + const probe = tryStart() + expect(probe).toBeDefined() + await probe!.shutdown() + await plain.shutdown() + await disabled.shutdown() + }) + }) +}) diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts index de800f8729..72e9a544a5 100644 --- a/packages/node/src/client.ts +++ b/packages/node/src/client.ts @@ -43,6 +43,7 @@ import { GroupIdentifyMessage, IdentifyMessage, IPostHog, + MetricsAutocaptureConfig, OverrideFeatureFlagsOptions, PostHogOptions, SendFeatureFlagsOptions, @@ -70,6 +71,12 @@ import { V1CaptureSender } from './capture-v1/sender' import { eventByteSize, partitionAiBatch } from './ai-capture/batching' import { AI_CAPTURE_ENDPOINT_PATH, AI_CAPTURE_ROUTE, AI_MAX_EVENT_BYTES } from './ai-capture/routing' +/** The running metrics autocapture, as `startMetricsAutocapture` returns it. */ +export interface MetricsAutocaptureHandle { + forceFlush(): Promise + shutdown(): Promise +} + // Standard local evaluation rate limit is 600 per minute (10 per second), // so the fastest a poller should ever be set is 100ms. const MINIMUM_POLLING_INTERVAL = 100 @@ -151,6 +158,7 @@ export abstract class PostHogBackendClient extends PostHogCoreStateless implemen public readonly options: PostHogOptions protected readonly context?: IPostHogContext private _metrics?: PostHogMetrics + private _metricsAutocapture?: MetricsAutocaptureHandle private _traces?: PostHogTraces private _spanContext?: SpanContextManager @@ -297,6 +305,25 @@ export abstract class PostHogBackendClient extends PostHogCoreStateless implemen this.errorTracking = new ErrorTracking(this, normalizedOptions, this._logger) this._distinctIdHasSentFlagCalls = new Map() this.maxCacheSize = normalizedOptions.maxCacheSize || MAX_CACHE_SIZE + + const autocapture = normalizedOptions.metrics?.autocapture + if (!this.disabled && autocapture) { + const areas = autocapture === true ? {} : autocapture + this._metricsAutocapture = this.startMetricsAutocapture({ + http: areas.http ?? true, + db: areas.db ?? true, + runtime: areas.runtime ?? true, + }) + } + } + + /** + * Starts metrics autocapture. Overridden by the Node entrypoint; other + * runtimes have no OpenTelemetry instrumentations to start. + */ + protected startMetricsAutocapture(_areas: Required): MetricsAutocaptureHandle | undefined { + this._logger.warn('metrics.autocapture needs the Node.js runtime, so it is ignored here.') + return undefined } protected override enqueue( @@ -887,6 +914,24 @@ export abstract class PostHogBackendClient extends PostHogCoreStateless implemen * @returns Promise that resolves when the client is enabled */ enable(): Promise { + return this.optIn() + } + + /** + * Opt the client back in (same as `enable()`). Autocaptured metrics recorded + * while opted out are dropped, not sent. + * + * {@label Privacy} + * + * @returns Promise that resolves when the client is opted in + */ + override async optIn(): Promise { + if (this._metricsAutocapture && this.optedOut) { + // Autocaptured metrics recorded while opted out are still in the current + // window. Collecting it now, while the exporter still sees the client as + // opted out, drops them instead of sending them after opt-in. + await this._metricsAutocapture.forceFlush().catch(() => {}) + } return super.optIn() } @@ -2909,6 +2954,14 @@ export abstract class PostHogBackendClient extends PostHogCoreStateless implemen // merged back onto a re-armed timer after teardown. this._metrics.reset() } + if (this._metricsAutocapture) { + // Exports the last window, then removes the instrumentations. + await raceWithTimeout( + this._metricsAutocapture.shutdown().catch(() => {}), + Math.max(0, shutdownDeadlineMs - Date.now()) + ) + this._metricsAutocapture = undefined + } if (this._traces) { // Same treatment as metrics: send what's queued, raced against the shared // shutdown budget, then reset so a losing flush can't re-arm a timer. diff --git a/packages/node/src/entrypoints/index.node.ts b/packages/node/src/entrypoints/index.node.ts index c456c50645..17d9803d27 100644 --- a/packages/node/src/entrypoints/index.node.ts +++ b/packages/node/src/entrypoints/index.node.ts @@ -5,13 +5,16 @@ import { addSourceContext } from '../extensions/error-tracking/modifiers/context import { createRelativePathModifier } from '../extensions/error-tracking/modifiers/relative-path.node' import type { PostHogFetchBodyBytes } from '@posthog/core' -import { PostHogBackendClient } from '../client' +import { PostHogBackendClient, type MetricsAutocaptureHandle } from '../client' import { ErrorTracking as CoreErrorTracking } from '@posthog/core' import type { SpanContextManager } from '@posthog/core' import { PostHogContext } from '../extensions/context/context' import { AsyncLocalStorageSpanContextManager } from '../extensions/context/span-context.node' import { gzipCompress } from '../gzip.node' import { hostOsResourceAttributes } from '../host-os.node' +import { startMetricsAutocapture } from '../extensions/metrics-autocapture.node' +import type { MetricsAutocaptureConfig } from '../types' +import { version } from '../version' export class PostHog extends PostHogBackendClient { getLibraryId(): string { @@ -34,6 +37,28 @@ export class PostHog extends PostHogBackendClient { return hostOsResourceAttributes() } + protected override startMetricsAutocapture( + areas: Required + ): MetricsAutocaptureHandle | undefined { + const metrics = this.options.metrics + return startMetricsAutocapture({ + host: this.host, + apiKey: this.apiKey, + config: areas, + serviceName: metrics?.serviceName, + resourceAttributes: { + ...hostOsResourceAttributes(), + ...(metrics?.serviceVersion ? { 'service.version': metrics.serviceVersion } : {}), + ...(metrics?.environment ? { 'deployment.environment': metrics.environment } : {}), + ...metrics?.resourceAttributes, + }, + distroVersion: version, + logger: this._logger, + isEnabled: () => !this.isDisabled && !this.optedOut, + exportIntervalMs: metrics?.flushIntervalMs, + }) + } + protected override createErrorPropertiesBuilder(): CoreErrorTracking.ErrorPropertiesBuilder { return new CoreErrorTracking.ErrorPropertiesBuilder( [ diff --git a/packages/node/src/entrypoints/metrics-register.node.ts b/packages/node/src/entrypoints/metrics-register.node.ts new file mode 100644 index 0000000000..a3b3caf707 --- /dev/null +++ b/packages/node/src/entrypoints/metrics-register.node.ts @@ -0,0 +1,62 @@ +import { createRequire, register } from 'node:module' +import { pathToFileURL } from 'node:url' +import { PostHog } from './index.node' + +/** + * `node --import posthog-node/metrics/register app.js` + * + * Starts metrics autocapture before the app loads any module, so every library + * the app imports is instrumented. Configured from the environment: + * `POSTHOG_PROJECT_TOKEN` (or `POSTHOG_API_KEY`), `POSTHOG_HOST` and + * `OTEL_SERVICE_NAME`. + */ + +// Short enough to fit inside a container's termination grace period. +const SHUTDOWN_TIMEOUT_MS = 5000 +const EXIT_SIGNALS = ['SIGTERM', 'SIGINT'] as const + +// ESM imports bypass the CommonJS require hook, so ESM apps need the loader hook +// the OpenTelemetry instrumentations ship. Without it, only `require` is patched. +function registerEsmLoaderHook(): void { + try { + const autoInstrumentations = createRequire(import.meta.url).resolve('@opentelemetry/auto-instrumentations-node') + const hook = createRequire(autoInstrumentations).resolve('@opentelemetry/instrumentation/hook.mjs') + register(pathToFileURL(hook)) + } catch { + // Missing packages are reported once by the client below. + } +} + +const token = process.env.POSTHOG_PROJECT_TOKEN || process.env.POSTHOG_API_KEY + +if (token) { + registerEsmLoaderHook() + const posthog = new PostHog(token, { + host: process.env.POSTHOG_HOST, + metrics: { autocapture: true, serviceName: process.env.OTEL_SERVICE_NAME }, + }) + let shuttingDown: Promise | undefined + const shutdown = (): Promise => (shuttingDown ??= posthog.shutdown(SHUTDOWN_TIMEOUT_MS).catch(() => {})) + + // Sends the last window when the event loop drains. + process.once('beforeExit', () => { + void shutdown() + }) + // `beforeExit` does not run on a signal, so the last window is sent here too. + // `once` removes this listener before it runs: when no other listener is left, + // the app has no handler of its own, and the signal is raised again after the + // flush so the process still exits the default way. When the app has a + // handler, it owns the exit. + for (const signal of EXIT_SIGNALS) { + process.once(signal, () => { + const appHandlesSignal = process.listenerCount(signal) > 0 + void shutdown().then(() => { + if (!appHandlesSignal) { + process.kill(process.pid, signal) + } + }) + }) + } +} else { + console.warn('[PostHog] posthog-node/metrics/register needs POSTHOG_PROJECT_TOKEN, so metrics autocapture is off.') +} diff --git a/packages/node/src/extensions/metrics-autocapture.node.ts b/packages/node/src/extensions/metrics-autocapture.node.ts new file mode 100644 index 0000000000..262e487b58 --- /dev/null +++ b/packages/node/src/extensions/metrics-autocapture.node.ts @@ -0,0 +1,417 @@ +import { createRequire } from 'node:module' +import type { Attributes, Meter, SpanKind as OtelSpanKind } from '@opentelemetry/api' +import type { MetricReader, PushMetricExporter, ViewOptions } from '@opentelemetry/sdk-metrics' +import type { ReadableSpan, Sampler, SpanProcessor } from '@opentelemetry/sdk-trace-base' +import { allSettled, type Logger } from '@posthog/core' + +/** + * Metrics autocapture: HTTP, database and runtime metrics from the official + * OpenTelemetry instrumentations, exported to PostHog with no instrumentation + * code in the app. + * + * Node-only, like the other `.node` modules. The OpenTelemetry packages are + * optional peer dependencies, loaded here on first use, so an app that never + * turns autocapture on loads none of them. + * + * The meter and tracer providers are private: nothing is registered on the + * OpenTelemetry globals, so the app's own OpenTelemetry setup (if it adds one + * later) is not changed. Spans are only used to derive database metrics and are + * never exported. + */ + +export interface MetricsAutocaptureAreas { + http: boolean + db: boolean + runtime: boolean +} + +export interface MetricsAutocaptureOptions { + host: string + apiKey: string + config: MetricsAutocaptureAreas + serviceName?: string + resourceAttributes: Record + distroVersion: string + logger: Logger + /** Read before each export, so an opted-out client sends nothing. */ + isEnabled: () => boolean + exportIntervalMs?: number +} + +export interface MetricsAutocapture { + forceFlush(): Promise + shutdown(): Promise +} + +type Load = ((id: string) => any) & { resolve?: (id: string) => string } + +export const METRICS_AUTOCAPTURE_PACKAGES = [ + '@opentelemetry/api', + '@opentelemetry/sdk-metrics', + '@opentelemetry/sdk-trace-base', + '@opentelemetry/resources', + '@opentelemetry/exporter-metrics-otlp-proto', + '@opentelemetry/auto-instrumentations-node', +] + +const INSTALL_COMMAND = `npm install ${METRICS_AUTOCAPTURE_PACKAGES.join(' ')}` + +const HTTP_INSTRUMENTATIONS = ['@opentelemetry/instrumentation-http', '@opentelemetry/instrumentation-undici'] + +// Driver-level instrumentations only. ORM and query-builder layers (knex, +// mongoose) wrap a driver span, so instrumenting both would count one query twice. +const DB_INSTRUMENTATIONS = [ + '@opentelemetry/instrumentation-pg', + '@opentelemetry/instrumentation-mysql', + '@opentelemetry/instrumentation-mysql2', + '@opentelemetry/instrumentation-mongodb', + '@opentelemetry/instrumentation-redis', + '@opentelemetry/instrumentation-ioredis', + '@opentelemetry/instrumentation-tedious', + '@opentelemetry/instrumentation-cassandra-driver', + '@opentelemetry/instrumentation-memcached', + '@opentelemetry/instrumentation-oracledb', +] + +const RUNTIME_INSTRUMENTATIONS = ['@opentelemetry/instrumentation-runtime-node'] + +// These record `db.client.operation.duration` themselves. +const NATIVE_DB_METRIC_SCOPES = new Set([ + '@opentelemetry/instrumentation-pg', + '@opentelemetry/instrumentation-oracledb', +]) +const DERIVED_DB_METRIC_SCOPES = new Set(DB_INSTRUMENTATIONS.filter((name) => !NATIVE_DB_METRIC_SCOPES.has(name))) + +const DB_OPERATION_DURATION = 'db.client.operation.duration' +// OpenTelemetry semantic convention advice for `db.client.operation.duration`. +const DB_DURATION_BUCKETS = [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10] + +const SPAN_KIND_CLIENT = 2 as OtelSpanKind +const SPAN_STATUS_ERROR = 2 + +// On globalThis rather than in module scope, so the CommonJS and ESM builds +// loaded side by side still share one instrumentation set per process. +const ACTIVE = Symbol.for('posthog-node.metrics-autocapture') +const INSTRUMENTATIONS = Symbol.for('posthog-node.metrics-autocapture.instrumentations') + +let warnedAboutMissingPackages = false + +const firstString = (attributes: Attributes, keys: string[]): string | undefined => { + for (const key of keys) { + const value = attributes[key] + if (typeof value === 'string' && value) { + return value + } + } + return undefined +} + +// The leading keyword (`SELECT`, `GET`) is bounded; the rest of a statement is not. +const operationFromStatement = (statement: string | undefined): string | undefined => { + const keyword = statement?.match(/^\s*([A-Za-z]{2,20})\b/)?.[1] + return keyword?.toUpperCase() +} + +// An operation name is one word (`SELECT`, `find`, `HGETALL`). Anything after it +// may be part of the statement. +const DB_OPERATION_NAME = /^\s*([A-Za-z_][A-Za-z0-9_]{0,63})/ + +/** + * Keeps only the leading word of `db.operation.name` on every + * `db.client.operation.duration` series. Native instrumentations derive it from + * the statement too: pg takes the text before the first space, so + * `SELECT\n'a@b.c'` would otherwise reach PostHog with the literal in it. + */ +export const DB_METRIC_VIEWS: ViewOptions[] = [ + { + instrumentName: DB_OPERATION_DURATION, + attributesProcessors: [ + { + process: (incoming) => { + const value = incoming['db.operation.name'] + if (value === undefined) { + return incoming + } + const { 'db.operation.name': _dropped, ...attributes } = incoming + const operation = typeof value === 'string' ? value.match(DB_OPERATION_NAME)?.[1] : undefined + return operation ? { ...attributes, 'db.operation.name': operation } : attributes + }, + }, + ], + }, +] + +/** + * Turns driver-level database client spans into a `db.client.operation.duration` + * histogram. Only bounded attributes are kept: never the statement, which holds + * values, and never anything per-user. + */ +export function createDbSpanMetricsProcessor(meter: Meter): SpanProcessor { + const histogram = meter.createHistogram(DB_OPERATION_DURATION, { + unit: 's', + description: 'Duration of database client operations.', + advice: { explicitBucketBoundaries: DB_DURATION_BUCKETS }, + }) + + return { + onStart: () => {}, + onEnd: (span: ReadableSpan) => { + if (span.kind !== SPAN_KIND_CLIENT || !DERIVED_DB_METRIC_SCOPES.has(span.instrumentationScope?.name)) { + return + } + const attributes = span.attributes + const system = firstString(attributes, ['db.system.name', 'db.system']) + if (!system) { + return + } + const metricAttributes: Attributes = { 'db.system.name': system } + const operation = + firstString(attributes, ['db.operation.name', 'db.operation']) ?? + operationFromStatement(firstString(attributes, ['db.query.text', 'db.statement'])) + const collection = firstString(attributes, [ + 'db.collection.name', + 'db.mongodb.collection', + 'db.sql.table', + 'db.cassandra.table', + ]) + const namespace = firstString(attributes, ['db.namespace', 'db.name']) + const address = firstString(attributes, ['server.address', 'net.peer.name']) + const port = attributes['server.port'] ?? attributes['net.peer.port'] + if (operation) { + metricAttributes['db.operation.name'] = operation + } + if (collection) { + metricAttributes['db.collection.name'] = collection + } + if (namespace) { + metricAttributes['db.namespace'] = namespace + } + if (address) { + metricAttributes['server.address'] = address + } + if (typeof port === 'number') { + metricAttributes['server.port'] = port + } + if (span.status?.code === SPAN_STATUS_ERROR) { + metricAttributes['error.type'] = firstString(attributes, ['error.type']) ?? '_OTHER' + } + const [seconds, nanos] = span.duration + histogram.record(seconds + nanos / 1e9, metricAttributes) + }, + forceFlush: () => Promise.resolve(), + shutdown: () => Promise.resolve(), + } +} + +// Records only client spans, the kind a database call makes; server spans stay +// no-ops. Not every driver sets `db.system` when the span starts, so the kind is +// all a sampler can check. +const clientSpansOnlySampler = (decisions: { NOT_RECORD: number; RECORD: number }): Sampler => ({ + shouldSample: (_context, _traceId, _name, kind) => ({ + decision: kind === SPAN_KIND_CLIENT ? decisions.RECORD : decisions.NOT_RECORD, + }), + toString: () => 'PostHogClientSpansOnlySampler', +}) + +const isNoopProvider = (provider: any): boolean => { + const delegate = typeof provider?.getDelegate === 'function' ? provider.getDelegate() : provider + return /^Noop/.test(delegate?.constructor?.name ?? '') +} + +// The exporter still sends while the client is opted out unless it is gated here. +const gateExporter = (exporter: PushMetricExporter, isEnabled: () => boolean): PushMetricExporter => ({ + export: (metrics, resultCallback) => { + if (!isEnabled()) { + resultCallback({ code: 0 }) + return + } + exporter.export(metrics, resultCallback) + }, + forceFlush: () => exporter.forceFlush(), + shutdown: () => exporter.shutdown(), + selectAggregationTemporality: exporter.selectAggregationTemporality?.bind(exporter), + selectAggregation: exporter.selectAggregation?.bind(exporter), +}) + +const defaultPort = (protocol: string | undefined): number => (protocol === 'https:' ? 443 : 80) + +const instrumentationClass = (module: Record): (new (config?: object) => any) | undefined => + Object.values(module).find( + (value): value is new (config?: object) => any => typeof value === 'function' && /Instrumentation$/.test(value.name) + ) + +/** + * Starts metrics autocapture. Returns `undefined`, after one warning, when the + * OpenTelemetry packages are missing, when OpenTelemetry is already set up in + * the process, or when autocapture is already running. Never throws. + */ +export function startMetricsAutocapture( + options: MetricsAutocaptureOptions, + overrides: { metricReader?: MetricReader; load?: Load } = {} +): MetricsAutocapture | undefined { + const { logger, config } = options + const globals = globalThis as { [ACTIVE]?: MetricsAutocapture; [INSTRUMENTATIONS]?: Map } + if (globals[ACTIVE]) { + logger.warn('Metrics autocapture is already running in this process, so this client does not start it again.') + return undefined + } + + const load: Load = overrides.load ?? createRequire(import.meta.url) + let otel: { + api: typeof import('@opentelemetry/api') + sdkMetrics: typeof import('@opentelemetry/sdk-metrics') + sdkTrace: typeof import('@opentelemetry/sdk-trace-base') + resources: typeof import('@opentelemetry/resources') + exporter: typeof import('@opentelemetry/exporter-metrics-otlp-proto') + loadInstrumentation: (name: string) => Record + } + try { + const autoInstrumentationsPath = load.resolve?.('@opentelemetry/auto-instrumentations-node') + // The individual instrumentations are dependencies of the meta-package, so + // they resolve from its location even under strict package managers. + const loadInstrumentation: Load = autoInstrumentationsPath ? createRequire(autoInstrumentationsPath) : load + otel = { + api: load('@opentelemetry/api'), + sdkMetrics: load('@opentelemetry/sdk-metrics'), + sdkTrace: load('@opentelemetry/sdk-trace-base'), + resources: load('@opentelemetry/resources'), + exporter: load('@opentelemetry/exporter-metrics-otlp-proto'), + loadInstrumentation, + } + } catch (error) { + if (!warnedAboutMissingPackages) { + warnedAboutMissingPackages = true + logger.warn( + `Metrics autocapture needs the OpenTelemetry packages. Install them with: ${INSTALL_COMMAND}`, + error instanceof Error ? error.message : error + ) + } + return undefined + } + + try { + const { api, sdkMetrics, sdkTrace, resources, exporter } = otel + if (!isNoopProvider(api.metrics.getMeterProvider()) || !isNoopProvider(api.trace.getTracerProvider())) { + logger.warn( + 'OpenTelemetry is already set up in this process, so metrics autocapture does not start. ' + + 'Point your OTLP metrics exporter at PostHog instead: https://posthog.com/docs/metrics' + ) + return undefined + } + + const hostUrl = new URL(options.host) + const hostPort = Number(hostUrl.port) || defaultPort(hostUrl.protocol) + const isPostHogRequest = (hostname: string | undefined, port: number): boolean => + hostname === hostUrl.hostname && port === hostPort + + const resource = resources.resourceFromAttributes({ + 'service.name': options.serviceName || process.env.OTEL_SERVICE_NAME || 'unknown_service', + ...options.resourceAttributes, + 'telemetry.distro.name': 'posthog-node', + 'telemetry.distro.version': options.distroVersion, + }) + + const reader = + overrides.metricReader ?? + new sdkMetrics.PeriodicExportingMetricReader({ + exporter: gateExporter( + new exporter.OTLPMetricExporter({ + url: `${options.host}/i/v1/metrics`, + headers: { Authorization: `Bearer ${options.apiKey}` }, + temporalityPreference: sdkMetrics.AggregationTemporality.DELTA, + }), + options.isEnabled + ), + exportIntervalMillis: options.exportIntervalMs ?? 10000, + }) + const meterProvider = new sdkMetrics.MeterProvider({ resource, readers: [reader], views: DB_METRIC_VIEWS }) + const tracerProvider = new sdkTrace.BasicTracerProvider({ + resource, + sampler: clientSpansOnlySampler(sdkTrace.SamplingDecision), + spanProcessors: config.db + ? [createDbSpanMetricsProcessor(meterProvider.getMeter('posthog-node.metrics-autocapture'))] + : [], + }) + + // Some drivers (ioredis, redis) skip calls with no parent span by default, and + // without a context manager no call has one. + const dbConfig = { requireParentSpan: false } + const instrumentationConfig: Record = { + ...Object.fromEntries(DB_INSTRUMENTATIONS.map((name) => [name, dbConfig])), + '@opentelemetry/instrumentation-http': { + ignoreOutgoingRequestHook: (request: { + hostname?: string + host?: string + port?: number | string + protocol?: string + }) => + isPostHogRequest( + request.hostname ?? request.host?.replace(/:\d+$/, ''), + Number(request.port) || defaultPort(request.protocol ?? undefined) + ), + }, + '@opentelemetry/instrumentation-undici': { + ignoreRequestHook: (request: { origin: string }) => { + const url = new URL(request.origin) + return isPostHogRequest(url.hostname, Number(url.port) || defaultPort(url.protocol)) + }, + }, + } + const names = [ + ...(config.http ? HTTP_INSTRUMENTATIONS : []), + ...(config.db ? DB_INSTRUMENTATIONS : []), + ...(config.runtime ? RUNTIME_INSTRUMENTATIONS : []), + ] + // One instance per instrumentation per process, enabled again on each start. + // The require hook remembers a module it has already handed out, so a new + // instance would never see `http` again after the first one was disabled. + const cache = (globals[INSTRUMENTATIONS] ??= new Map()) + const instrumentations = names.flatMap((name) => { + try { + let instrumentation = cache.get(name) + if (!instrumentation) { + const Instrumentation = instrumentationClass(otel.loadInstrumentation(name)) + if (!Instrumentation) { + return [] + } + // Disabled until it has our providers. + instrumentation = new Instrumentation({ enabled: false }) + cache.set(name, instrumentation) + } + // Also clears `enabled: false`, which some instrumentations (undici) check on every request. + instrumentation.setConfig(instrumentationConfig[name] ?? {}) + return [instrumentation] + } catch (error) { + logger.debug(`Metrics autocapture skipped ${name}`, error) + return [] + } + }) + for (const instrumentation of instrumentations) { + instrumentation.setTracerProvider(tracerProvider) + instrumentation.setMeterProvider(meterProvider) + instrumentation.enable() + } + + const handle: MetricsAutocapture = { + forceFlush: () => meterProvider.forceFlush(), + shutdown: async () => { + if (globals[ACTIVE] !== handle) { + return + } + delete globals[ACTIVE] + // Export first: disabling removes the runtime gauges' callbacks, so they + // would be missing from the last window. + await allSettled([meterProvider.forceFlush()]) + for (const instrumentation of instrumentations) { + instrumentation.disable() + } + await allSettled([meterProvider.shutdown(), tracerProvider.shutdown()]) + }, + } + globals[ACTIVE] = handle + return handle + } catch (error) { + logger.error('Metrics autocapture failed to start', error) + return undefined + } +} diff --git a/packages/node/src/types.ts b/packages/node/src/types.ts index 9713b81536..f8d41cafe0 100644 --- a/packages/node/src/types.ts +++ b/packages/node/src/types.ts @@ -18,6 +18,37 @@ import { ContextData, ContextOptions } from './extensions/context/types' import type { FeatureFlagEvaluations } from './feature-flag-evaluations' import type { FlagDefinitionCacheInput, FlagDefinitionCacheProvider } from './extensions/feature-flags/cache' +/** + * Which areas metrics autocapture measures. Every area defaults to on. + */ +export type MetricsAutocaptureConfig = { + /** `http.server.request.duration` and `http.client.request.duration` for `http`, `https` and `fetch`. */ + http?: boolean + /** `db.client.operation.duration` and connection metrics for pg, mysql, mysql2, mongodb, redis, ioredis and more. */ + db?: boolean + /** Event loop, heap and garbage collection metrics. */ + runtime?: boolean +} + +/** + * Options for the posthog.metrics API, plus Node-only autocapture. + */ +export type NodeMetricsConfig = MetricsConfig & { + /** + * Capture HTTP, database and runtime metrics with no instrumentation code, using + * the official OpenTelemetry instrumentations. Needs the OpenTelemetry peer + * packages (`npm install @opentelemetry/api @opentelemetry/sdk-metrics + * @opentelemetry/sdk-trace-base @opentelemetry/resources + * @opentelemetry/exporter-metrics-otlp-proto @opentelemetry/auto-instrumentations-node`). + * + * Libraries loaded before the client is built are not instrumented. To measure + * everything, start the app with `node --import posthog-node/metrics/register`. + * + * @default false + */ + autocapture?: boolean | MetricsAutocaptureConfig +} + export type IdentifyMessage = { distinctId: string properties?: Record @@ -190,7 +221,7 @@ export type PostHogOptions = Omit=12.10.0'} + + '@grpc/proto-loader@0.8.1': + resolution: {integrity: sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==} + engines: {node: '>=6'} + hasBin: true + '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} @@ -5154,6 +5181,9 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@jsep-plugin/assignment@1.3.0': resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==} engines: {node: '>= 10.16.0'} @@ -5641,16 +5671,39 @@ packages: resolution: {integrity: sha512-wBlPk1nFB37Hsm+3Qy73yQSobVn28F4isnWIBvKpd5IUH/eat8bwcL02H9yzmHyyPmukeccSl2mbN5sDQZYnPg==} engines: {node: '>=8.0.0'} + '@opentelemetry/api-logs@0.222.0': + resolution: {integrity: sha512-9mb1If+IF6u0ZVXkHQ6ogEae5HwA6ajIVUgpSDQyRASxft6BSXHvBvPooRle3yFN/fKnCdSOnuu0OC3PLcF6+g==} + engines: {node: '>=8.0.0'} + '@opentelemetry/api@1.9.0': resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} + '@opentelemetry/auto-instrumentations-node@0.80.0': + resolution: {integrity: sha512-McPSxdNZqudZnC8WsYti63QyDoj+QOB4EKVp3Ndrq+gq5UOoi2GcDvXjphIxgXUFoJ3jzWoiczhReKW23OKsOw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.4.1 + '@opentelemetry/core': ^2.0.0 + + '@opentelemetry/configuration@0.222.0': + resolution: {integrity: sha512-zNWGmEvyX7CUbS6F6PKi7hf3CF/SffzeBYyWVQAfadZ8hODrvLmqV3IUGVt1SiqyYanRPHc8VuhoO0Qh9OEuug==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + '@opentelemetry/context-async-hooks@2.10.0': resolution: {integrity: sha512-bvyMcgLEkozzSzpEEEo1OMoeQ97bxj6Qs2uN3mPrSdDvObMI1myffD/BPqcLlzZO9//d1SqQA/WPw7Cz2AiqhA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/context-async-hooks@2.11.0': + resolution: {integrity: sha512-Tr79DyWI8itsBdg+jH+opjfrwLzX+erk1/ExkIwhWoAVjVrJIn2y5+cGjTC0Vy8fyNIA/y8wuJPZwr1T3xCZeQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/core@2.0.0': resolution: {integrity: sha512-SLX36allrcnVaPYG3R78F/UZZsBsvbc7lMCLx37LyH5MJ1KAAZ2E3mW9OAD3zGz0G8q/BtoS5VUrjzDydhD6LQ==} engines: {node: ^18.19.0 || >=20.6.0} @@ -5669,24 +5722,84 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/core@2.11.0': + resolution: {integrity: sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/core@2.12.0': + resolution: {integrity: sha512-1HsSAuvT4/my0QrXWsyXFdWjKaPeCHsismKZgEEIb8NK13LP6DrMRlsUbvD/0F9mDWK3xDom9AMv3IscxgOnOQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/core@2.2.0': resolution: {integrity: sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/exporter-logs-otlp-grpc@0.222.0': + resolution: {integrity: sha512-HH4Oi/E8HXBKtcjgcVPJGsrg+lSstdw1m93brRdpVj5CjMpyTkv/O0ZYMXP6QXVEaLjjFivtzUu4Y8+i1UJpjw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/exporter-logs-otlp-http@0.205.0': resolution: {integrity: sha512-5JteMyVWiro4ghF0tHQjfE6OJcF7UBUcoEqX3UIQ5jutKP1H+fxFdyhqjjpmeHMFxzOHaYuLlNR1Bn7FOjGyJg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/exporter-logs-otlp-http@0.222.0': + resolution: {integrity: sha512-GqwLZohJTf/sttYlOpT1oFTJ9ScYaKnk0sOx4Qe/+KmXYVOa+v94cfnkUkFKDuvTODWhCL50Hz3gvsZD6ngQpg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-logs-otlp-proto@0.222.0': + resolution: {integrity: sha512-LlCDJuaznfFPzjHoKXjN/r9T5pgCZpmVheZ/EmwMUhMvpxI7RXDmsdLXoYpl5suYQNkwyXAUZhVEXKe3lev8Hg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-metrics-otlp-grpc@0.222.0': + resolution: {integrity: sha512-nPU2gpQWJfQttf+A71aLkKEOQoO6n6QGs5QTtPagi/rb3Lc1I55bqRXoLQEZsWqWimc8eas2Vo168NkTaByxQw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/exporter-metrics-otlp-http@0.205.0': resolution: {integrity: sha512-fFxNQ/HbbpLmh1pgU6HUVbFD1kNIjrkoluoKJkh88+gnmpFD92kMQ8WFNjPnSbjg2mNVnEkeKXgCYEowNW+p1w==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/exporter-metrics-otlp-http@0.222.0': + resolution: {integrity: sha512-6Ko+0bgNP6V4G/RsmNBSk5lO1B/lo9z6tvLpFY3ykPPevXNzFmOW3C9hEmTt0zKCvHovyrol3TYlg4HVb5gwjg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-metrics-otlp-proto@0.222.0': + resolution: {integrity: sha512-s1ZPwS8Ig7cpRmL3kCobPaFbemM81dJ03LNPrsuN32h3mCDvNF2NQ1pRHruOju0P0o1TZ24LkZA685rtQal1KA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-prometheus@0.222.0': + resolution: {integrity: sha512-I7nalnnBZrhlTgjlqsVeEjJGcQCFK5kKAYVk7XTz/cbubvj5fvjLOal/Many0taHF2GIkOWmegsbQ8vbQJjhFg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-trace-otlp-grpc@0.222.0': + resolution: {integrity: sha512-uisilePEdOMa3hIfXW82XXU6FofF8gw3iv+PoboIMWEUBC7XbJB3XnIHSdrSDsqCw3njR/If08qD0yzOY1U9Sg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/exporter-trace-otlp-http@0.200.0': resolution: {integrity: sha512-Goi//m/7ZHeUedxTGVmEzH19NgqJY+Bzr6zXo1Rni1+hwqaksEyJ44gdlEMREu6dzX1DlAaH/qSykSVzdrdafA==} engines: {node: ^18.19.0 || >=20.6.0} @@ -5699,6 +5812,276 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/exporter-trace-otlp-http@0.222.0': + resolution: {integrity: sha512-RCnPWcHppwiquQ+cV3nWvNwdf0MG1w26e5jewW2T83nTZOlXgcg88sY9ulCVgagGHcq1mj0L0GP6YHgzk2v8oA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-trace-otlp-proto@0.222.0': + resolution: {integrity: sha512-imLrLzNhnABJt3tUyT63h6MqfZrG3Gdv3TE7+OUQTvwD088RfCUx3rF01lcgfu2KXBFk13vwi0yKZLvFEalkIA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-zipkin@2.11.0': + resolution: {integrity: sha512-mFibA45yXLEETIj+VcTVycFFe4R91iD41d+r3CU0f3DDWJCrICiHxUIjmYBTCZIuywXEeNo++2lncQeWnH7lWQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/instrumentation-amqplib@0.69.0': + resolution: {integrity: sha512-hoSfNGxqospEFw0S2RH7cY8MF5U1BRKsAfX7PhiiZgGDWxPcmfAKYdXilmn0DqPBGRFYzq+HbtSp+R+2sy4mXA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-aws-lambda@0.74.0': + resolution: {integrity: sha512-N7L+NIyndEUWC0EjtN7OmNBF0J5beXQ81+46qt1NCA2YDC95os9TIh2iWfKL+U3wINkJeStMWBEQgFZhEvj1qw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-aws-sdk@0.77.0': + resolution: {integrity: sha512-igri8DF7ZWlYtQjT1u2A3v6Grb59VSsYiheGrLpnI7rlEAxmFeWHPwiwzzko39lM0LO7Ntf3VJPRBA1ZNGwF1w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-bunyan@0.67.0': + resolution: {integrity: sha512-a/ucku1yx4qW2zpYpepTM/rZlv92DG/C+k/Kxn/nqhh5HOoe3pHFbXUXunvy2EtHW/7l81PI++AUm+rIxXqlTg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-cassandra-driver@0.67.0': + resolution: {integrity: sha512-PIHbjmBWfYeYqAH8XDCyoJoXaR6TkEakNw3BX8uDt8b9zjYk3uetjCoP8nubRDb8m30vkDbs09Qg09pFOXKj2w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-connect@0.65.0': + resolution: {integrity: sha512-i7xkOkzzeaYbaK2Gjpxa6g9FJd1nqoH0+KFyRXV0iweH/F2+xZPintRFD5gcSN5/H4mpfslsLbDqRT897CvzEQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-cucumber@0.38.0': + resolution: {integrity: sha512-sorgrR3FOBy+YEwVutxcm84JTI0luCNIGp0kiL+jSoUrH9W/pYVSpP4isLB3VtQMgNnD4cd0e9qNvvr7RwKLpA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/instrumentation-dataloader@0.39.0': + resolution: {integrity: sha512-01+jNP1hESK8GYTCuRMoiQAEf9ZI5b3XwfSk7bWDiXLB2/zml5Md/U/xaWyFHQ2kYyU553Qvr8dcyup5Beu7qA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-dns@0.65.0': + resolution: {integrity: sha512-7QXICs4eV/GeihRqPnsR7TnK6ugAK8/B7tWr8UFxRzGTfNG97LEfByevhNfMEE8pFFLHUhiCE5metED2lO8nhw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-express@0.70.0': + resolution: {integrity: sha512-OHdj/2apRZNhMKkd6w4OV4SnX/aS2LWMLyHwGGNYhWratgh88o+cVJS9FvqC+HCYWSDWTEWEfl/8d7BdEI7c+g==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-fs@0.41.0': + resolution: {integrity: sha512-rk1RcxvOeb5j7Gi6P/PB6M9MRRYQzp4t9ZYN/i6jVM+m0j2zCUYGH4Xo6omNh0FhTDhhytDPG6o95p82eXFL2w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-generic-pool@0.65.0': + resolution: {integrity: sha512-iKkn/8m0oerf00qCxz9/xeua+EieX6tlSmLhGiVLgLsOspmV1sb33ee8RPiWnJiandGVJgKA0GTGUZXwVKgPnQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-graphql@0.70.0': + resolution: {integrity: sha512-zyBTEG0Dxm6rYf0IaoIqt1ZRAuiq4AUPDhAi0vl/hBbYweU56CleS5zH8n+GQ3+EsTBW6KYKULHvXk21+UJo9w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-grpc@0.222.0': + resolution: {integrity: sha512-5gUFhJF5X8ss60apt2p7czvIeIzTHZQSq1QowiKVS4gBfP5nHZNhBYoOtq1j14A8IXs/qL8Hn/sfni4kaPVLRA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-hapi@0.68.0': + resolution: {integrity: sha512-wJShEI4aKajQT5Sg/sJ6jV3xF6SqJKfXHTLDdrmWMv0h1sDXp4mpSTD1XUJfO5H0lZFUtEJapxtWl126zAmf9w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-host-metrics@0.5.0': + resolution: {integrity: sha512-rAw5lmY2u3bwUFohRtR4ZYNDnhMTiSeQqq8BB4Bo+aJQ+7vIOOwW/3d4awLPMDQ69VeA5jsh+ICL5oJinrWIwA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-http@0.222.0': + resolution: {integrity: sha512-HhMHW32LyGzIJEmUElxaML4oUe6JiCq0Hvjt/Awxb60SlMsSFetFLFjed45g/0wrPr1n7z+xW+x1B/584WBAkg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-ioredis@0.70.0': + resolution: {integrity: sha512-AUyn8K5vlSGkIF2AXPlUsa5d5ZXRidHMXlAHNAykvgW3u8juDZqGTgsOKJMYnLfllawygawLrqK6Fr2lnPcBUQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-kafkajs@0.31.0': + resolution: {integrity: sha512-9/EBOb1aW5ai4+U7mu2ER5fhJ7OYZNK/ghRSETfCf92xCeoQkZcS8LEF8e05w6OlrgZCwq7x+vLuUxXtkRPv3w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-knex@0.66.0': + resolution: {integrity: sha512-tPI1T0ur+P2qvsOWcadv9ViWtJ8g0XsKOAMPiR5rasZBZAC6nEI4u4BAnAhaZtdZkuMJrGa4uZur5xTn1bv7MQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-koa@0.70.0': + resolution: {integrity: sha512-+CFyL7V0auN0FzKvGUwOIOGT/8VTC3BM8cd8X0UoHRmPKEdYfwNWuHIkA6zknZPDMXN9WLfZCxdZ0Ln/YqLx4w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + + '@opentelemetry/instrumentation-lru-memoizer@0.66.0': + resolution: {integrity: sha512-kYJQFqkR2eEwGzqTRw2Nc/NiQyrQRU3rLHmsEvdnlf40YRfCBadbDu3I8C5GWoVn1XyEKFTvmn85UoslRpbUjA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-memcached@0.65.0': + resolution: {integrity: sha512-QLGrx33THENogCdkBi1DJxPwvWe4QInoKUbx7u15zb37bxrKww68ZrqbMF4luq9YZbGQUFqEsnSprHV8kU93QA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mongodb@0.75.0': + resolution: {integrity: sha512-Bf9Az6zdOsnRFUew1CToTKpfhcFkAJ4SgmnGpxID/vuzVHI31oZhAwuKBTHny/Eq7ydXfncDbET8jV6d3L8REw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mongoose@0.68.0': + resolution: {integrity: sha512-GrDPpy9XHwWJUpKb4NjH8bdRU9EvtS37D102LhMOnjNOp6ouvtVBmFcPLMsJKsZcFOG4YykSERnau4l5a+sy2w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mysql2@0.68.0': + resolution: {integrity: sha512-xNvUL0nwk/t0gGPb1GSQJWKiR3gj4Cd3vk4palrttLy/FYbnRBOOBRCobik3grAMzjsynEgyYdzEziXx/CvpyQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mysql@0.68.0': + resolution: {integrity: sha512-N6TCMiWmisdG9DzSuMHxZ+N5qD3meoCy70mVE6fneZj6M24EXj86e56BzLFQ8Pkd6BgaPBJcdMTT/GBfPuW15w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-nestjs-core@0.68.0': + resolution: {integrity: sha512-BCsqKPLWVDgrTDyVScRwENWg8uNH7LA0QBy+ojuPQx9C9F85yOhNkale5MdmQG0su7L6BLLTNPByZOZeKp3c5A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-net@0.66.0': + resolution: {integrity: sha512-OxnzC0696+Ne7zHisHo95RZkYT4e2C4OoB+q0dqQyZ0/9klLQ9CyC/Yu+OzYrQzPjdzRQVVPNDhoW+5+cXk3XQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-openai@0.20.0': + resolution: {integrity: sha512-vl8ReH9dq9goRWbajF0xQt/mnCZDl2KCcmOvgC1sSKCRA8DnqSMq7Z9ZVKPA9PnaV4tGInb39qtGdGIORUkEqQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-oracledb@0.47.0': + resolution: {integrity: sha512-3DDgcsl2CFX4829TxZiNYD29pFN9xyT71HUBN475CuFQ94eq+1jyMZPshO+K7qJltrJY2Df3MWV2ANrlw8H8fQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-pg@0.74.0': + resolution: {integrity: sha512-8i59Z7M0FjEwp2hF1eRqEr+NZtiwjvPYGl2xsGWEfL/hF6ffmPERWbySyK1EXa7gGyHCArwNkHLShsMfFywqpQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-pino@0.68.0': + resolution: {integrity: sha512-U0ggAM9eqDe7jsUnZeFMv6QIZwahNfyPZQAlUV9ZQ3aAYpaq+Ag9Okec75Fgzwh72+e4gewfT99HObkDg6Y/bA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-redis@0.70.0': + resolution: {integrity: sha512-jXHduXt6GQWluGtqBPibAvpw27seRjA6SMyLp0Oc41AzSQz1JFZq1CNw6gvdOrRasH4AJPpRykPxw02IjHYr0A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-restify@0.67.0': + resolution: {integrity: sha512-T4sjjxX0CaeYNEMUNEDbCL9nGPIRkEmAzj7b1HwI0YJgZV459aStVsgJRTKmuaeIoJSihTqH2yUmcB+gdR5Qxg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-router@0.66.0': + resolution: {integrity: sha512-18GWiTNuIMDFxepxYV0PVikAAMmcqLZsMziJXi2PyuP3r9msPjMJnU7RZ+DLS1N8amwWit3EZYmFI4dNE4d9uQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-runtime-node@0.35.0': + resolution: {integrity: sha512-/cOW4Qlv4nnr4QXDCkv0TEtOBa9R9lXHu//JuD5+nRPYR74g9iLmf5tadcYvn32oz2R8vQnV8FTnMLzjfAGMCQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-socket.io@0.69.0': + resolution: {integrity: sha512-VlS6GFeWd32d09WziTZR9cfLPNJ1nV747suBCgUivRVzIwrg1UG+DBCmMX/kvrMmGJcFRAbf6I6s6nLsR6+Jag==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-tedious@0.41.0': + resolution: {integrity: sha512-dtrHwEs40nzD/fR9jkSNbSiHqCIHf2sXcMM8nY29Ekc25pw0EADRBqN4Ya2prrCSNGVtIx6N9o3fTS7fsACysA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-undici@0.32.0': + resolution: {integrity: sha512-Ms8oPkrCHa6hJOYodcFC8QOt1AFlns3KD1CqXBEihXyTFeLXDO84tIXYyKlXNHr8jMrl1Gm2velDvsSDXAuh9w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.7.0 + + '@opentelemetry/instrumentation-winston@0.66.0': + resolution: {integrity: sha512-wwBZnlq9/2qiBpIoLB5yC88Ws0zoOLFde6DuIbEYL+SmC+bgYBITYV59AIlaDGpvos/n7AM+k8EFw+y/ZQVudw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation@0.222.0': + resolution: {integrity: sha512-fhbRDuAgzPKpq1k5+hX3uS+3QAYNca0on0Ngot/R8dDsQtuFaADeZnG2uSgxABuvcI7S2phAaRhbct9jieeKZw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/otlp-exporter-base@0.200.0': resolution: {integrity: sha512-IxJgA3FD7q4V6gGq4bnmQM5nTIyMDkoGFGrBrrDjB6onEiq1pafma55V+bHvGYLWvcqbBbRfezr1GED88lacEQ==} engines: {node: ^18.19.0 || >=20.6.0} @@ -5711,6 +6094,18 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/otlp-exporter-base@0.222.0': + resolution: {integrity: sha512-YbywG3veEm2Fb6TbdxRkuquWob6eVWXuA8/Ba1tXz9jHfUqpdE3keilOHEtPboC4CvS1bjeeVfNkWGOOrLj+lw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-grpc-exporter-base@0.222.0': + resolution: {integrity: sha512-Kw5WqDBYYpCgY+edHWZS/Jp3bdguqNkCyEWOsqFhf8RmtcEuWYzPFA9i+L6UsNoJXTs8ngeQB6dwELH1czNYjA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/otlp-transformer@0.200.0': resolution: {integrity: sha512-+9YDZbYybOnv7sWzebWOeK6gKyt2XE7iarSyBFkwwnP559pEevKOUD8NyDHhRjCSp13ybh9iVXlMfcj/DwF/yw==} engines: {node: ^18.19.0 || >=20.6.0} @@ -5723,12 +6118,70 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/otlp-transformer@0.222.0': + resolution: {integrity: sha512-/F3BZ89+CJQnZkMh2tCrtcdB+XT2Dxhj4FFE+WPQ//413hmFL0/RfEX6vgOIWGhiSzrkHWTK3+6SiT7K5/g/jQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/propagator-aws-xray@2.2.0': + resolution: {integrity: sha512-Yjvt2EjL+tfpkVOdKbhTPgpM4SIAez9nG6Q/QjQ3yfcJcjIWp59ph70SLfvmkSL6++3DCnuBG3iWcB18PwWavQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/propagator-b3@2.11.0': + resolution: {integrity: sha512-ldyRZXx6qsqu9Spqd7rVxo6SNAUJqP8Ir3vwIi4N8xyZLXNl/2XeQmIHvFneiVOqNwWkU+JGFg2O9/T1fefU0w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/propagator-jaeger@2.11.0': + resolution: {integrity: sha512-RUOqgoIqXOPQTOhpBrs07Y8sBlxVoLY5Fka6ueZ0prW+k6fWQsba/nHDY4gm+gmfuwtRqbX5Y9YKhDvktjbIqQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/redis-common@0.38.3': + resolution: {integrity: sha512-VCghU1JYs/4gP6Gqf/xro9MEsZ7LrMv2uONVsaESKL38ZOB9BqnI98FfS23wjMnHlpuE+TTaWSoAVNpTwYXzjw==} + engines: {node: ^18.19.0 || >=20.6.0} + + '@opentelemetry/resource-detector-alibaba-cloud@0.37.0': + resolution: {integrity: sha512-tEbi6ZPrPZG79oZdQlzw5xR7sirtYy+LBbt/S/JxDUZnmSWEYmo7l2jp985XU4UhsfMDpcfdOY+Gnt2bPMtvyQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/resource-detector-aws@2.23.0': + resolution: {integrity: sha512-+wpGu2UafLOGsyQX9LpVtFmSXRit+XlCw/je6c5hHBb0lNk4bHOlbjDG3XaD6yh9hv8eLAlz0HeR0lABUmFr0Q==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/resource-detector-azure@0.30.0': + resolution: {integrity: sha512-fwGDPVGJ6PyRMc5CPdHBfASX5prg3mLhZA0rs+n8ZJK4DjpJw9CvB1FujWl8l0QAsTmvrYBm9Deal3fvfqZBkQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/resource-detector-container@0.8.14': + resolution: {integrity: sha512-m7eU89Jb9XnC2ieCQBic8L4ovki+Zw+eSXgdwF5ItN0rWUaCfJQz7Ds/luYqLbxha56wY4IP/jsxnz/WM+a53Q==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + '@opentelemetry/resource-detector-gcp@0.40.3': resolution: {integrity: sha512-C796YjBA5P1JQldovApYfFA/8bQwFfpxjUbOtGhn1YZkVTLoNQN+kvBwgALfTPWzug6fWsd0xhn9dzeiUcndag==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.0.0 + '@opentelemetry/resource-detector-gcp@0.57.0': + resolution: {integrity: sha512-wp+hk7jD7mxA6swAqa5wQ3jws2egh1DCPZ9FfEgntmFw/mc8MaGZjwuttOoMeRjIlcBCCaNUHuN8B+MZaujAXQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + '@opentelemetry/resources@2.0.0': resolution: {integrity: sha512-rnZr6dML2z4IARI4zPGQV4arDikF/9OXZQzrC01dLmn0CZxU5U5OLd/m1T7YkGRj5UitjeoCtg/zorlgMQcdTg==} engines: {node: ^18.19.0 || >=20.6.0} @@ -5747,6 +6200,18 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/resources@2.11.0': + resolution: {integrity: sha512-Ie7+8q8MDF4FAEQCKVMTx3ReUvxiIAgIiiW3c9JdmP8+HMcDy20puT+AHjexnExgnbvBxjQ9fjkFDWrikJ2jQA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/resources@2.12.0': + resolution: {integrity: sha512-+rSRoOdln6NhXTVcBdHSlZxJDNzwxadeweK2ltZO3tVtfp6aklABc06xclDk6ovRR+EiGgIcSbh/6NgjFhnb3A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/resources@2.2.0': resolution: {integrity: sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==} engines: {node: ^18.19.0 || >=20.6.0} @@ -5765,6 +6230,12 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.4.0 <1.10.0' + '@opentelemetry/sdk-logs@0.222.0': + resolution: {integrity: sha512-+19YHODIjaUCArxleaJtuufFZVpz/xvvK+VllQqE+W8hHolxdoRwHfK/s667zezwh1hkx6FFF+oYzetYgqK+Bg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.4.0 <1.10.0' + '@opentelemetry/sdk-metrics@2.0.0': resolution: {integrity: sha512-Bvy8QDjO05umd0+j+gDeWcTaVa1/R2lDj/eOvjzpm8VQj1K1vVZJuyjThpV5/lSHyYW2JaHF2IQ7Z8twJFAhjA==} engines: {node: ^18.19.0 || >=20.6.0} @@ -5783,6 +6254,24 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.9.0 <1.10.0' + '@opentelemetry/sdk-metrics@2.11.0': + resolution: {integrity: sha512-7GXXcObyHyDUUSG+L+kJoquty01bzm7ivE7+SSgXXJcHuPzGviptxwARmI2c+bnnxjexGQbJnyNlN8HxBP/Y7A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.9.0 <1.10.0' + + '@opentelemetry/sdk-metrics@2.12.0': + resolution: {integrity: sha512-mVMaEHwCUJuY3S4Esn+nT0yQA3qCEGh+SOPJsXygU0Gl453WcsDNjtEa8EfdewMwoLyr1tlofB4fXytVpiXuow==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.9.0 <1.10.0' + + '@opentelemetry/sdk-node@0.222.0': + resolution: {integrity: sha512-t8tlFN/ezYV7iI4k6u3t2jFbIReX99Z0iVMVSYLJscE4McxIW9YGHhdOldeY1elHeoq8mjEO4B9s4Fk7+zJbsg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/sdk-trace-base@2.0.0': resolution: {integrity: sha512-qQnYdX+ZCkonM7tA5iU4fSRsVxbFGml8jbxOgipRGMFHKaXKHQ30js03rTobYjKjIfnOsZSbHKWF0/0v0OQGfw==} engines: {node: ^18.19.0 || >=20.6.0} @@ -5801,6 +6290,12 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/sdk-trace-base@2.11.0': + resolution: {integrity: sha512-H19x/TX/LZdqiYOjM7fqtSxwlplC5pgelavqbQdHbhdq0q/AI/TGkM2dfGuuynTXmJPeF2HoZVoPDu+TGoW78A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/sdk-trace-base@2.2.0': resolution: {integrity: sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==} engines: {node: ^18.19.0 || >=20.6.0} @@ -5813,16 +6308,38 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/sdk-trace-node@2.11.0': + resolution: {integrity: sha512-CuvCMJmZxswhNLlM2LfuLOW3h3fZujA4hsG4B+Sz4dX2zvaXO8Ng74cnDHWD64gLszTlhiG3c0iNUjj4g+0/sA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/sdk-trace@2.10.0': resolution: {integrity: sha512-MfQGq3GRmTh5fM/y+OjaO0vj6+luCB1XO2gfXCalKCfgKw0eHL++sm75DNweC6ohlp+aFvACqeE0fYayqdRaoQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/sdk-trace@2.11.0': + resolution: {integrity: sha512-fFnTqGm8/G73GQVnxYi7LXa1ZVYEUvgL6XI1LpvV0bPC7WQ/ZGgKxCSl8FnlZBKto9JHHEFTO6s6CUpvvtwFrA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/semantic-conventions@1.38.0': resolution: {integrity: sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==} engines: {node: '>=14'} + '@opentelemetry/semantic-conventions@1.43.0': + resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} + engines: {node: '>=14'} + + '@opentelemetry/sql-common@0.42.0': + resolution: {integrity: sha512-nwUwUU+8O8a4bnLqk6CodWeegGMEANgC94KTAhXcpGWLrW/2/hek/0ajNbjXnSOoNuCX+nteUPs46HFHhou9Xw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@oxc-parser/binding-android-arm-eabi@0.140.0': resolution: {integrity: sha512-ZfjDZ422mo7eo3b3VltqNsV9kmv1qt/sPEAMSl64iOSwhVfd0eIZ9LB79Mbs1xYXJnk7WSROwzBCKDIiVxPTvQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -8135,6 +8652,9 @@ packages: '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/aws-lambda@8.10.164': + resolution: {integrity: sha512-XOnrazWcOd6yWPnR7DxqCBPPYciDjHq+NN8LPwwqBCJNXLyPJgKo47fZpJ113+oyAn9Zti0Cf6H4k6yPcE3WFg==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -8245,6 +8765,9 @@ packages: '@types/lodash@4.17.21': resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} + '@types/memcached@2.2.10': + resolution: {integrity: sha512-AM9smvZN55Gzs2wRrqeMHVP7KE8KWgCJO/XL5yCly2xF6EKa4YlbpK+cLSAH4NG/Ah64HrlegmGqW8kYws7Vxg==} + '@types/minimatch@3.0.3': resolution: {integrity: sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==} @@ -8299,6 +8822,12 @@ packages: '@types/offscreencanvas@2019.7.3': resolution: {integrity: sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==} + '@types/pg-pool@2.0.7': + resolution: {integrity: sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==} + + '@types/pg@8.15.6': + resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} + '@types/pixelmatch@5.2.6': resolution: {integrity: sha512-wC83uexE5KGuUODn6zkm9gMzTwdY5L0chiK+VrKcDfEjzxh1uadlWTvOmAbCpnM9zx/Ww3f8uKlYQVnO/TrqVg==} @@ -9921,6 +10450,9 @@ packages: cjs-module-lexer@1.4.3: resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + cjs-module-lexer@2.3.0: + resolution: {integrity: sha512-lmNyBzi6iYiqyrExTctfmjd8tInx+dHu9PBomTfH5RXS53c27JMFJgzNv5TyAnm3PgGf+MLy0+Ws41/HlVxdKQ==} + class-utils@0.3.6: resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} engines: {node: '>=0.10.0'} @@ -11036,6 +11568,9 @@ packages: es-module-lexer@2.3.2: resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} + es-module-lexer@3.0.3: + resolution: {integrity: sha512-yWGe1O/j+almnV4hOYrmZo8u58JdnmXEMneRQAYkWtqSiT86yoMIEKF4rpqEDj52tbYl3xceBD3DQIBwcsC9Pw==} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -11649,6 +12184,9 @@ packages: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} + forwarded-parse@2.1.2: + resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -12322,6 +12860,10 @@ packages: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} + import-in-the-middle@3.5.2: + resolution: {integrity: sha512-WseIA/4o56+GYO3RmlOPvejYi771OFeJEeK/ejROsr9bdjW+E5NXTOD1Di8TL40Qgg3JJX9aa97Hf8iiSVIKZw==} + engines: {node: '>=18'} + import-lazy@3.1.0: resolution: {integrity: sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==} engines: {node: '>=6'} @@ -13532,6 +14074,9 @@ packages: lodash-es@4.18.1: resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -14204,6 +14749,9 @@ packages: mocked-exports@0.1.1: resolution: {integrity: sha512-aF7yRQr/Q0O2/4pIXm6PZ5G+jAd7QS4Yu8m+WEeEHGnbo+7mE36CbLSDQiXYV8bVL3NfmdeqPJct0tUlnjVSnA==} + module-details-from-path@1.0.4: + resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + moment-duration-format-commonjs@1.0.1: resolution: {integrity: sha512-KhKZRH21/+ihNRWrmdNFOyBptFi7nAWZFeFsRRpXkzgk/Yublb4fxyP0jU6EY1VDxUL/VUPdCmm/wAnpbfXdfw==} @@ -15070,6 +15618,17 @@ packages: perfect-debounce@2.1.0: resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-protocol@1.16.1: + resolution: {integrity: sha512-p9VOFMiHB/ZbJATetbg+99PxssTVSQRnyuPSQ67mN1+1KBOjZaZ83ZQzltnxPhJwSsC3nwVjJ10DVJlerbFzLg==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -15570,6 +16129,22 @@ packages: resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} engines: {node: ^10 || ^12 || >=14} + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.1: + resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + posthog-react-native-session-replay@1.6.0: resolution: {integrity: sha512-OCaei77mtgg7JT+TgHSCgpWeKq2XXENUOPNxGbjhXZa/aJpptOW5VsBqjtH4BPzM2c1veS1DK4/Fb/uV4Rb3cg==} peerDependencies: @@ -16099,6 +16674,10 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + require-in-the-middle@8.0.1: + resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==} + engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'} + require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} @@ -17098,6 +17677,12 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + systeminformation@5.33.15: + resolution: {integrity: sha512-s5RloL0F7xhN0ZjfHtLGnbf7EW74EI0N8NFL+1xR7Oxz9QA33obNZsl7lyfnJOhN04E/kGFPoJPlvY7TZ5fzmw==} + engines: {node: '>=10.0.0'} + os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] + hasBin: true + tagged-tag@1.0.0: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} engines: {node: '>=20'} @@ -18922,10 +19507,11 @@ snapshots: optionalDependencies: graphql: 15.8.0 - '@a2a-js/sdk@0.3.14(express@5.2.1)': + '@a2a-js/sdk@0.3.14(@grpc/grpc-js@1.14.5)(express@5.2.1)': dependencies: uuid: 11.1.0 optionalDependencies: + '@grpc/grpc-js': 1.14.5 express: 5.2.1 '@adobe/css-tools@4.4.0': {} @@ -23036,9 +23622,9 @@ snapshots: - supports-color - utf-8-validate - '@google/adk@2.0.0(@modelcontextprotocol/sdk@1.30.0(@cfworker/json-schema@4.1.1)(zod@4.1.13))(express@5.2.1)': + '@google/adk@2.0.0(@grpc/grpc-js@1.14.5)(@modelcontextprotocol/sdk@1.30.0(@cfworker/json-schema@4.1.1)(zod@4.1.13))(express@5.2.1)': dependencies: - '@a2a-js/sdk': 0.3.14(express@5.2.1) + '@a2a-js/sdk': 0.3.14(@grpc/grpc-js@1.14.5)(express@5.2.1) '@google-cloud/vertexai': 1.12.0(@modelcontextprotocol/sdk@1.30.0(@cfworker/json-schema@4.1.1)(zod@4.1.13)) '@google/genai': 2.18.0(@modelcontextprotocol/sdk@1.30.0(@cfworker/json-schema@4.1.1)(zod@4.1.13)) '@mikro-orm/core': 6.6.16 @@ -23103,6 +23689,18 @@ snapshots: dependencies: graphql: 15.8.0 + '@grpc/grpc-js@1.14.5': + dependencies: + '@grpc/proto-loader': 0.8.1 + '@js-sdsl/ordered-map': 4.4.2 + + '@grpc/proto-loader@0.8.1': + dependencies: + lodash.camelcase: 4.3.0 + long: 5.3.2 + protobufjs: 7.6.5 + yargs: 17.7.3 + '@hapi/hoek@9.3.0': {} '@hapi/topo@5.1.0': @@ -23554,6 +24152,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@js-sdsl/ordered-map@4.4.2': {} + '@jsep-plugin/assignment@1.3.0(jsep@1.4.0)': dependencies: jsep: 1.4.0 @@ -23574,12 +24174,12 @@ snapshots: '@kwsites/promise-deferred@1.1.1': {} - '@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0)': + '@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0)': dependencies: '@cfworker/json-schema': 4.1.1 '@standard-schema/spec': 1.1.0 js-tiktoken: 1.0.21 - langsmith: 0.10.5(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) + langsmith: 0.10.5(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) mustache: 4.2.0 p-queue: 6.6.2 zod: 4.6.5 @@ -23590,13 +24190,13 @@ snapshots: - openai - ws - '@langchain/langgraph-checkpoint@1.1.5(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))': + '@langchain/langgraph-checkpoint@1.1.5(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))': dependencies: - '@langchain/core': 1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) + '@langchain/core': 1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) - '@langchain/langgraph-sdk@1.12.0(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + '@langchain/langgraph-sdk@1.12.0(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@langchain/core': 1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) + '@langchain/core': 1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) '@langchain/protocol': 0.0.19 '@types/json-schema': 7.0.15 p-queue: 9.3.3 @@ -23605,11 +24205,11 @@ snapshots: react: 19.2.7 react-dom: 19.2.7(react@19.2.7) - '@langchain/langgraph@1.4.18(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(zod@4.6.5)': + '@langchain/langgraph@1.4.18(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(zod@4.6.5)': dependencies: - '@langchain/core': 1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) - '@langchain/langgraph-checkpoint': 1.1.5(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0)) - '@langchain/langgraph-sdk': 1.12.0(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@langchain/core': 1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) + '@langchain/langgraph-checkpoint': 1.1.5(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0)) + '@langchain/langgraph-sdk': 1.12.0(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@langchain/protocol': 0.0.19 '@standard-schema/spec': 1.1.0 zod: 4.6.5 @@ -23977,7 +24577,7 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/microservices': 11.1.29(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.29)(ioredis@5.11.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/microservices': 11.1.29(@grpc/grpc-js@1.14.5)(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.29)(ioredis@5.11.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/platform-express': 11.1.29(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.29) '@nestjs/jwt@11.0.2(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))': @@ -23986,7 +24586,7 @@ snapshots: '@types/jsonwebtoken': 9.0.10 jsonwebtoken: 9.0.3 - '@nestjs/microservices@11.1.29(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.29)(ioredis@5.11.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/microservices@11.1.29(@grpc/grpc-js@1.14.5)(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.29)(ioredis@5.11.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: '@nestjs/common': 11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.29(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.29)(@nestjs/platform-express@11.1.29)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -23995,6 +24595,7 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: + '@grpc/grpc-js': 1.14.5 ioredis: 5.11.1 '@nestjs/passport@11.0.5(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)': @@ -24589,12 +25190,82 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs@0.222.0': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api@1.9.0': {} + '@opentelemetry/auto-instrumentations-node@0.80.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@2.12.0(@opentelemetry/api@1.9.0))': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.12.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-amqplib': 0.69.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-aws-lambda': 0.74.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-aws-sdk': 0.77.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-bunyan': 0.67.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-cassandra-driver': 0.67.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-connect': 0.65.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-cucumber': 0.38.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-dataloader': 0.39.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-dns': 0.65.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-express': 0.70.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-fs': 0.41.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-generic-pool': 0.65.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-graphql': 0.70.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-grpc': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-hapi': 0.68.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-host-metrics': 0.5.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-http': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-ioredis': 0.70.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-kafkajs': 0.31.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-knex': 0.66.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-koa': 0.70.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-lru-memoizer': 0.66.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-memcached': 0.65.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongodb': 0.75.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongoose': 0.68.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql': 0.68.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql2': 0.68.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-nestjs-core': 0.68.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-net': 0.66.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-openai': 0.20.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-oracledb': 0.47.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-pg': 0.74.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-pino': 0.68.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-redis': 0.70.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-restify': 0.67.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-router': 0.66.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-runtime-node': 0.35.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-socket.io': 0.69.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-tedious': 0.41.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-undici': 0.32.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-winston': 0.66.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-alibaba-cloud': 0.37.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-aws': 2.23.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-azure': 0.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-container': 0.8.14(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-gcp': 0.57.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-node': 0.222.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/configuration@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + yaml: 2.9.0 + '@opentelemetry/context-async-hooks@2.10.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 + '@opentelemetry/context-async-hooks@2.11.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core@2.0.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24610,11 +25281,29 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/core@2.11.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.38.0 + + '@opentelemetry/core@2.12.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/exporter-logs-otlp-grpc@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-http@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24624,6 +25313,27 @@ snapshots: '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-logs': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-http@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.222.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-logs-otlp-proto@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.222.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-metrics-otlp-grpc@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/exporter-metrics-otlp-http': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24633,6 +25343,38 @@ snapshots: '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.11.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-metrics-otlp-proto@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/exporter-metrics-otlp-http': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-prometheus@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + + '@opentelemetry/exporter-trace-otlp-grpc@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http@0.200.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24651,6 +25393,387 @@ snapshots: '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace': 2.11.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace': 2.11.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-zipkin@2.11.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + + '@opentelemetry/instrumentation-amqplib@0.69.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-aws-lambda@0.74.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-aws-xray': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + '@types/aws-lambda': 8.10.164 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-aws-sdk@0.77.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-bunyan@0.67.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.222.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.43.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-cassandra-driver@0.67.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-connect@0.65.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + '@types/connect': 3.4.38 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-cucumber@0.38.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-dataloader@0.39.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-dns@0.65.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-express@0.70.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-fs@0.41.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-generic-pool@0.65.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-graphql@0.70.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-grpc@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-hapi@0.68.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-host-metrics@0.5.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + systeminformation: 5.33.15 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-http@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + forwarded-parse: 2.1.2 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-ioredis@0.70.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/redis-common': 0.38.3 + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-kafkajs@0.31.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-knex@0.66.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-koa@0.70.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-lru-memoizer@0.66.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-memcached@0.65.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + '@types/memcached': 2.2.10 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mongodb@0.75.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mongoose@0.68.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mysql2@0.68.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/sql-common': 0.42.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mysql@0.68.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-nestjs-core@0.68.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-net@0.66.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-openai@0.20.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.222.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-oracledb@0.47.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-pg@0.74.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/sql-common': 0.42.0(@opentelemetry/api@1.9.0) + '@types/pg': 8.15.6 + '@types/pg-pool': 2.0.7 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-pino@0.68.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.222.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.43.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-redis@0.70.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/redis-common': 0.38.3 + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-restify@0.67.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-router@0.66.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-runtime-node@0.35.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.222.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-socket.io@0.69.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-tedious@0.41.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-undici@0.32.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-winston@0.66.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.222.0 + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.222.0 + import-in-the-middle: 3.5.2 + require-in-the-middle: 8.0.1 + transitivePeerDependencies: + - supports-color + '@opentelemetry/otlp-exporter-base@0.200.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24663,6 +25786,20 @@ snapshots: '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/otlp-grpc-exporter-base@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.14.5 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer@0.200.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24685,16 +25822,77 @@ snapshots: '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) protobufjs: 7.6.5 + '@opentelemetry/otlp-transformer@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.222.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace': 2.11.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/propagator-aws-xray@2.2.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + + '@opentelemetry/propagator-b3@2.11.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/propagator-jaeger@2.11.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/redis-common@0.38.3': {} + + '@opentelemetry/resource-detector-alibaba-cloud@0.37.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.10.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/resource-detector-aws@2.23.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + + '@opentelemetry/resource-detector-azure@0.30.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + + '@opentelemetry/resource-detector-container@0.8.14(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-gcp@0.40.3(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.10.0(@opentelemetry/api@1.9.0) gcp-metadata: 6.1.1 transitivePeerDependencies: - encoding - supports-color + '@opentelemetry/resource-detector-gcp@0.57.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.10.0(@opentelemetry/api@1.9.0) + gcp-metadata: 8.1.2 + transitivePeerDependencies: + - supports-color + '@opentelemetry/resources@2.0.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24713,6 +25911,18 @@ snapshots: '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/resources@2.11.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + + '@opentelemetry/resources@2.12.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.12.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24733,6 +25943,14 @@ snapshots: '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.222.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/sdk-metrics@2.0.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24751,6 +25969,51 @@ snapshots: '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics@2.11.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/sdk-metrics@2.12.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.12.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.12.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/sdk-node@0.222.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.222.0 + '@opentelemetry/configuration': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/context-async-hooks': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-grpc': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-http': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-proto': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-grpc': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-proto': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-prometheus': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-grpc': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-proto': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-zipkin': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-b3': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-jaeger': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.222.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/sdk-trace-base@2.0.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24773,6 +26036,14 @@ snapshots: '@opentelemetry/sdk-trace': 2.10.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/sdk-trace-base@2.11.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24787,6 +26058,13 @@ snapshots: '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.10.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node@2.11.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/context-async-hooks': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace@2.10.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -24794,8 +26072,22 @@ snapshots: '@opentelemetry/resources': 2.10.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/sdk-trace@2.11.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.11.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions@1.38.0': {} + '@opentelemetry/semantic-conventions@1.43.0': {} + + '@opentelemetry/sql-common@0.42.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.0) + '@oxc-parser/binding-android-arm-eabi@0.140.0': optional: true @@ -25947,7 +27239,7 @@ snapshots: '@modelcontextprotocol/server': 2.0.0 '@nestjs/common': 11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.29(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.29)(@nestjs/platform-express@11.1.29)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/microservices': 11.1.29(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.29)(ioredis@5.11.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/microservices': 11.1.29(@grpc/grpc-js@1.14.5)(@nestjs/common@11.1.29(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.29)(ioredis@5.11.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) express: 5.2.1 multer: 2.2.0 path-to-regexp: 8.4.2 @@ -27223,6 +28515,8 @@ snapshots: '@types/aria-query@5.0.4': {} + '@types/aws-lambda@8.10.164': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.29.9 @@ -27255,7 +28549,7 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 22.20.1 + '@types/node': 22.20.4 '@types/cookie@0.4.1': {} @@ -27313,7 +28607,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 3.0.3 - '@types/node': 22.20.1 + '@types/node': 22.20.4 '@types/graceful-fs@4.1.9': dependencies: @@ -27361,6 +28655,10 @@ snapshots: '@types/lodash@4.17.21': {} + '@types/memcached@2.2.10': + dependencies: + '@types/node': 22.20.4 + '@types/minimatch@3.0.3': {} '@types/minimist@1.2.5': {} @@ -27371,7 +28669,7 @@ snapshots: '@types/node-forge@1.3.14': dependencies: - '@types/node': 22.20.1 + '@types/node': 22.20.4 '@types/node@12.20.55': {} @@ -27416,6 +28714,16 @@ snapshots: '@types/offscreencanvas@2019.7.3': {} + '@types/pg-pool@2.0.7': + dependencies: + '@types/pg': 8.15.6 + + '@types/pg@8.15.6': + dependencies: + '@types/node': 22.20.4 + pg-protocol: 1.16.1 + pg-types: 2.2.0 + '@types/pixelmatch@5.2.6': dependencies: '@types/node': 22.20.1 @@ -27509,7 +28817,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.20.1 + '@types/node': 22.20.4 optional: true '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260216.1': @@ -27927,14 +29235,14 @@ snapshots: '@babel/core': 7.29.7 '@babel/helper-module-imports': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@vue/compiler-sfc': 3.5.22 transitivePeerDependencies: - supports-color '@vue/compiler-core@3.5.22': dependencies: - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@vue/shared': 3.5.22 entities: 4.5.0 estree-walker: 2.0.2 @@ -29365,7 +30673,7 @@ snapshots: chrome-launcher@0.15.2: dependencies: - '@types/node': 22.20.1 + '@types/node': 22.20.4 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -29390,7 +30698,7 @@ snapshots: chromium-edge-launcher@0.2.0: dependencies: - '@types/node': 22.20.1 + '@types/node': 22.20.4 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -29414,6 +30722,8 @@ snapshots: cjs-module-lexer@1.4.3: optional: true + cjs-module-lexer@2.3.0: {} + class-utils@0.3.6: dependencies: arr-union: 3.1.0 @@ -30510,6 +31820,8 @@ snapshots: es-module-lexer@2.3.2: {} + es-module-lexer@3.0.3: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -31517,6 +32829,8 @@ snapshots: dependencies: fetch-blob: 3.2.0 + forwarded-parse@2.1.2: {} + forwarded@0.2.0: {} fraction.js@4.3.7: {} @@ -32290,6 +33604,12 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 + import-in-the-middle@3.5.2: + dependencies: + cjs-module-lexer: 2.3.0 + es-module-lexer: 3.0.3 + module-details-from-path: 1.0.4 + import-lazy@3.1.0: {} import-lazy@4.0.0: {} @@ -32983,7 +34303,7 @@ snapshots: dependencies: '@jest/types': 27.5.1 '@types/graceful-fs': 4.1.9 - '@types/node': 22.20.1 + '@types/node': 22.20.4 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -33144,7 +34464,7 @@ snapshots: jest-serializer@27.5.1: dependencies: - '@types/node': 22.20.1 + '@types/node': 22.20.4 graceful-fs: 4.2.11 jest-snapshot@29.7.0: @@ -33176,7 +34496,7 @@ snapshots: jest-util@27.5.1: dependencies: '@jest/types': 27.5.1 - '@types/node': 22.20.1 + '@types/node': 22.20.4 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -33616,12 +34936,12 @@ snapshots: kuler@2.0.0: {} - langchain@1.5.14(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(ws@8.22.0): + langchain@1.5.14(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(ws@8.22.0): dependencies: - '@langchain/core': 1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) - '@langchain/langgraph': 1.4.18(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(zod@4.6.5) - '@langchain/langgraph-checkpoint': 1.1.5(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0)) - langsmith: 0.10.5(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) + '@langchain/core': 1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) + '@langchain/langgraph': 1.4.18(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(zod@4.6.5) + '@langchain/langgraph-checkpoint': 1.1.5(@langchain/core@1.2.13(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0)) + langsmith: 0.10.5(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0) zod: 4.6.5 transitivePeerDependencies: - '@opentelemetry/api' @@ -33632,11 +34952,12 @@ snapshots: - react-dom - ws - langsmith@0.10.5(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0): + langsmith@0.10.5(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.222.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13))(ws@8.22.0): dependencies: p-queue: 6.6.2 optionalDependencies: '@opentelemetry/api': 1.9.0 + '@opentelemetry/exporter-trace-otlp-proto': 0.222.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) openai: 6.49.0(@aws-sdk/credential-provider-node@3.972.30)(@smithy/signature-v4@5.7.4)(ws@8.21.3)(zod@4.1.13) ws: 8.22.0 @@ -33831,6 +35152,8 @@ snapshots: lodash-es@4.18.1: {} + lodash.camelcase@4.3.0: {} + lodash.debounce@4.0.8: {} lodash.get@4.4.2: {} @@ -34534,7 +35857,7 @@ snapshots: dependencies: '@babel/core': 7.29.7 '@babel/generator': 7.29.8 - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 babel-preset-fbjs: 3.4.0(@babel/core@7.29.7) metro: 0.70.4 @@ -34555,7 +35878,7 @@ snapshots: dependencies: '@babel/core': 7.29.7 '@babel/generator': 7.29.8 - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 flow-enums-runtime: 0.0.6 metro: 0.80.12 @@ -34596,7 +35919,7 @@ snapshots: '@babel/code-frame': 7.29.7 '@babel/core': 7.29.7 '@babel/generator': 7.29.8 - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/template': 7.29.7 '@babel/traverse': 7.28.5 '@babel/types': 7.29.8 @@ -34949,6 +36272,8 @@ snapshots: mocked-exports@0.1.1: {} + module-details-from-path@1.0.4: {} + moment-duration-format-commonjs@1.0.1: {} moment@2.30.1: {} @@ -36172,6 +37497,18 @@ snapshots: perfect-debounce@2.1.0: {} + pg-int8@1.0.1: {} + + pg-protocol@1.16.1: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.1 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + picocolors@1.1.1: {} picomatch@2.3.2: {} @@ -36649,6 +37986,16 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postgres-array@2.0.0: {} + + postgres-bytea@1.0.1: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + posthog-react-native-session-replay@1.6.0(react-native@0.69.12(@babel/core@7.28.5)(@babel/preset-env@7.28.5(@babel/core@7.28.5))(react@18.2.0))(react@18.2.0): dependencies: react: 18.2.0 @@ -37353,6 +38700,13 @@ snapshots: require-from-string@2.0.2: {} + require-in-the-middle@8.0.1: + dependencies: + debug: 4.4.3 + module-details-from-path: 1.0.4 + transitivePeerDependencies: + - supports-color + require-main-filename@2.0.0: {} requireg@0.2.2: @@ -38537,6 +39891,8 @@ snapshots: symbol-tree@3.2.4: {} + systeminformation@5.33.15: {} + tagged-tag@1.0.0: {} tapable@2.3.3: {}