From c0d0966cbb37bbe24071baa940ff34780c4a7624 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Thu, 12 Dec 2024 11:47:47 -0800 Subject: [PATCH 1/2] feat(otlp-transformer)!: add new entrypoints for non-core features In preparation of stabilizing `@opentelemetry/otlp-transformer`, this commit introduces some new entrypoints for the package: * `@opentelemetry/otlp-transformer/protobuf`: utilities for working with the OTLP binary protobuf format * `@opentelemetry/otlp-transformer/json`: utilities for working with the OTLP JSON format * `@opentelemetry/otlp-transformer/experimental`: features to remain in experimental status post-stabilization The intent of separating out the first two entrypoints is to both aid bundlers with tree-shaking, but also to prevent the irrelevant code from running at all, since the generated prtobuf code is known to cause problems in certain environments (e.g. see #4987, #5096). The last of those entrypoints is currently empty, but expected to be utilized in future commits as features are triaged as part of the stabilization effort. Fixes #5216 --- experimental/CHANGELOG.md | 4 + .../src/OTLPLogExporter.ts | 2 +- .../src/platform/browser/OTLPLogExporter.ts | 2 +- .../src/platform/node/OTLPLogExporter.ts | 2 +- .../src/platform/browser/OTLPLogExporter.ts | 2 +- .../src/platform/node/OTLPLogExporter.ts | 2 +- .../src/OTLPTraceExporter.ts | 2 +- .../src/platform/browser/OTLPTraceExporter.ts | 2 +- .../src/platform/node/OTLPTraceExporter.ts | 2 +- .../src/platform/browser/OTLPTraceExporter.ts | 2 +- .../src/platform/node/OTLPTraceExporter.ts | 2 +- .../src/OTLPMetricExporter.ts | 2 +- .../platform/browser/OTLPMetricExporter.ts | 2 +- .../src/platform/node/OTLPMetricExporter.ts | 2 +- .../src/OTLPMetricExporter.ts | 2 +- .../packages/otlp-transformer/README.md | 83 ++++++++++++++++++- .../packages/otlp-transformer/package.json | 46 +++++++++- .../src/experimental/index.ts | 17 ++++ .../packages/otlp-transformer/src/index.ts | 12 --- .../otlp-transformer/src/json/index.ts | 21 +++++ .../otlp-transformer/src/protobuf/index.ts | 21 +++++ .../otlp-transformer/test/logs.test.ts | 4 +- .../otlp-transformer/test/metrics.test.ts | 9 +- .../otlp-transformer/test/trace.test.ts | 4 +- 24 files changed, 205 insertions(+), 44 deletions(-) create mode 100644 experimental/packages/otlp-transformer/src/experimental/index.ts create mode 100644 experimental/packages/otlp-transformer/src/json/index.ts create mode 100644 experimental/packages/otlp-transformer/src/protobuf/index.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 83471e2416e..8f0cc8dfb13 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -19,6 +19,10 @@ All notable changes to experimental packages in this project will be documented ### :boom: Breaking Change +* feat(otlp-transformer)!: add new entrypoints for non-core features [#5259](https://github.com/open-telemetry/opentelemetry-js/pull/5259/) + * (user-facing): OTLP (binary protobuf) utilities now located at `@opentelemetry/otlp-transformer/proto` + * (user-facing): OTLP (json) utilities now located at `@opentelemetry/otlp-transformer/json` + * (internal): features to remain experimental post-stabilization now located at `@opentelemetry/otlp-transformer/experimental` (empty for now) * feat(otlp-exporter-base)!: collapse base classes into one [#5031](https://github.com/open-telemetry/opentelemetry-js/pull/5031) @pichlermarc * `OTLPExporterNodeBase` has been removed in favor of a platform-agnostic implementation (`OTLPExporterBase`) * `OTLPExporterBrowserBase` has been removed in favor of a platform-agnostic implementation (`OTLPExporterBase`) diff --git a/experimental/packages/exporter-logs-otlp-grpc/src/OTLPLogExporter.ts b/experimental/packages/exporter-logs-otlp-grpc/src/OTLPLogExporter.ts index e7e883e1ea3..0a929afcecc 100644 --- a/experimental/packages/exporter-logs-otlp-grpc/src/OTLPLogExporter.ts +++ b/experimental/packages/exporter-logs-otlp-grpc/src/OTLPLogExporter.ts @@ -20,7 +20,7 @@ import { createOtlpGrpcExportDelegate, OTLPGRPCExporterConfigNode, } from '@opentelemetry/otlp-grpc-exporter-base'; -import { ProtobufLogsSerializer } from '@opentelemetry/otlp-transformer'; +import { ProtobufLogsSerializer } from '@opentelemetry/otlp-transformer/protobuf'; import { OTLPExporterBase } from '@opentelemetry/otlp-exporter-base'; /** diff --git a/experimental/packages/exporter-logs-otlp-http/src/platform/browser/OTLPLogExporter.ts b/experimental/packages/exporter-logs-otlp-http/src/platform/browser/OTLPLogExporter.ts index 01a0d1f26a7..a2d77b607e0 100644 --- a/experimental/packages/exporter-logs-otlp-http/src/platform/browser/OTLPLogExporter.ts +++ b/experimental/packages/exporter-logs-otlp-http/src/platform/browser/OTLPLogExporter.ts @@ -20,7 +20,7 @@ import type { } from '@opentelemetry/sdk-logs'; import type { OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base'; import { OTLPExporterBase } from '@opentelemetry/otlp-exporter-base'; -import { JsonLogsSerializer } from '@opentelemetry/otlp-transformer'; +import { JsonLogsSerializer } from '@opentelemetry/otlp-transformer/json'; import { createLegacyOtlpBrowserExportDelegate } from '@opentelemetry/otlp-exporter-base/browser-http'; /** diff --git a/experimental/packages/exporter-logs-otlp-http/src/platform/node/OTLPLogExporter.ts b/experimental/packages/exporter-logs-otlp-http/src/platform/node/OTLPLogExporter.ts index 28bb25319d6..de58077b8b8 100644 --- a/experimental/packages/exporter-logs-otlp-http/src/platform/node/OTLPLogExporter.ts +++ b/experimental/packages/exporter-logs-otlp-http/src/platform/node/OTLPLogExporter.ts @@ -20,7 +20,7 @@ import type { } from '@opentelemetry/sdk-logs'; import type { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base'; import { OTLPExporterBase } from '@opentelemetry/otlp-exporter-base'; -import { JsonLogsSerializer } from '@opentelemetry/otlp-transformer'; +import { JsonLogsSerializer } from '@opentelemetry/otlp-transformer/json'; import { VERSION } from '../../version'; import { convertLegacyHttpOptions, diff --git a/experimental/packages/exporter-logs-otlp-proto/src/platform/browser/OTLPLogExporter.ts b/experimental/packages/exporter-logs-otlp-proto/src/platform/browser/OTLPLogExporter.ts index 91293ce4730..ddcd32d6627 100644 --- a/experimental/packages/exporter-logs-otlp-proto/src/platform/browser/OTLPLogExporter.ts +++ b/experimental/packages/exporter-logs-otlp-proto/src/platform/browser/OTLPLogExporter.ts @@ -18,7 +18,7 @@ import { OTLPExporterConfigBase, OTLPExporterBase, } from '@opentelemetry/otlp-exporter-base'; -import { ProtobufLogsSerializer } from '@opentelemetry/otlp-transformer'; +import { ProtobufLogsSerializer } from '@opentelemetry/otlp-transformer/protobuf'; import { ReadableLogRecord, LogRecordExporter } from '@opentelemetry/sdk-logs'; import { createLegacyOtlpBrowserExportDelegate } from '@opentelemetry/otlp-exporter-base/browser-http'; diff --git a/experimental/packages/exporter-logs-otlp-proto/src/platform/node/OTLPLogExporter.ts b/experimental/packages/exporter-logs-otlp-proto/src/platform/node/OTLPLogExporter.ts index 5afa6cb17a5..96a54ca2236 100644 --- a/experimental/packages/exporter-logs-otlp-proto/src/platform/node/OTLPLogExporter.ts +++ b/experimental/packages/exporter-logs-otlp-proto/src/platform/node/OTLPLogExporter.ts @@ -18,7 +18,7 @@ import { OTLPExporterBase, OTLPExporterNodeConfigBase, } from '@opentelemetry/otlp-exporter-base'; -import { ProtobufLogsSerializer } from '@opentelemetry/otlp-transformer'; +import { ProtobufLogsSerializer } from '@opentelemetry/otlp-transformer/protobuf'; import { convertLegacyHttpOptions, createOtlpHttpExportDelegate, diff --git a/experimental/packages/exporter-trace-otlp-grpc/src/OTLPTraceExporter.ts b/experimental/packages/exporter-trace-otlp-grpc/src/OTLPTraceExporter.ts index daca6f8987d..2e1cac1387c 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/src/OTLPTraceExporter.ts +++ b/experimental/packages/exporter-trace-otlp-grpc/src/OTLPTraceExporter.ts @@ -20,7 +20,7 @@ import { createOtlpGrpcExportDelegate, OTLPGRPCExporterConfigNode, } from '@opentelemetry/otlp-grpc-exporter-base'; -import { ProtobufTraceSerializer } from '@opentelemetry/otlp-transformer'; +import { ProtobufTraceSerializer } from '@opentelemetry/otlp-transformer/protobuf'; import { OTLPExporterBase } from '@opentelemetry/otlp-exporter-base'; /** diff --git a/experimental/packages/exporter-trace-otlp-http/src/platform/browser/OTLPTraceExporter.ts b/experimental/packages/exporter-trace-otlp-http/src/platform/browser/OTLPTraceExporter.ts index 47dff844a06..a2561219dd6 100644 --- a/experimental/packages/exporter-trace-otlp-http/src/platform/browser/OTLPTraceExporter.ts +++ b/experimental/packages/exporter-trace-otlp-http/src/platform/browser/OTLPTraceExporter.ts @@ -19,7 +19,7 @@ import { OTLPExporterConfigBase, OTLPExporterBase, } from '@opentelemetry/otlp-exporter-base'; -import { JsonTraceSerializer } from '@opentelemetry/otlp-transformer'; +import { JsonTraceSerializer } from '@opentelemetry/otlp-transformer/json'; import { createLegacyOtlpBrowserExportDelegate } from '@opentelemetry/otlp-exporter-base/browser-http'; /** diff --git a/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts b/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts index 9d8b4900a56..868bc413964 100644 --- a/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts +++ b/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts @@ -20,7 +20,7 @@ import { OTLPExporterBase, } from '@opentelemetry/otlp-exporter-base'; import { VERSION } from '../../version'; -import { JsonTraceSerializer } from '@opentelemetry/otlp-transformer'; +import { JsonTraceSerializer } from '@opentelemetry/otlp-transformer/json'; import { convertLegacyHttpOptions, createOtlpHttpExportDelegate, diff --git a/experimental/packages/exporter-trace-otlp-proto/src/platform/browser/OTLPTraceExporter.ts b/experimental/packages/exporter-trace-otlp-proto/src/platform/browser/OTLPTraceExporter.ts index 7292f6a6390..29ce171b3f9 100644 --- a/experimental/packages/exporter-trace-otlp-proto/src/platform/browser/OTLPTraceExporter.ts +++ b/experimental/packages/exporter-trace-otlp-proto/src/platform/browser/OTLPTraceExporter.ts @@ -19,7 +19,7 @@ import { OTLPExporterConfigBase, OTLPExporterBase, } from '@opentelemetry/otlp-exporter-base'; -import { ProtobufTraceSerializer } from '@opentelemetry/otlp-transformer'; +import { ProtobufTraceSerializer } from '@opentelemetry/otlp-transformer/protobuf'; import { createLegacyOtlpBrowserExportDelegate } from '@opentelemetry/otlp-exporter-base/browser-http'; const DEFAULT_COLLECTOR_RESOURCE_PATH = 'v1/traces'; diff --git a/experimental/packages/exporter-trace-otlp-proto/src/platform/node/OTLPTraceExporter.ts b/experimental/packages/exporter-trace-otlp-proto/src/platform/node/OTLPTraceExporter.ts index f546fcb6437..21ef9869b23 100644 --- a/experimental/packages/exporter-trace-otlp-proto/src/platform/node/OTLPTraceExporter.ts +++ b/experimental/packages/exporter-trace-otlp-proto/src/platform/node/OTLPTraceExporter.ts @@ -19,7 +19,7 @@ import { OTLPExporterNodeConfigBase, OTLPExporterBase, } from '@opentelemetry/otlp-exporter-base'; -import { ProtobufTraceSerializer } from '@opentelemetry/otlp-transformer'; +import { ProtobufTraceSerializer } from '@opentelemetry/otlp-transformer/protobuf'; import { VERSION } from '../../version'; import { createOtlpHttpExportDelegate, diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts index 074c5e5c63d..632afd7303e 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts @@ -23,7 +23,7 @@ import { createOtlpGrpcExportDelegate, OTLPGRPCExporterConfigNode, } from '@opentelemetry/otlp-grpc-exporter-base'; -import { ProtobufMetricsSerializer } from '@opentelemetry/otlp-transformer'; +import { ProtobufMetricsSerializer } from '@opentelemetry/otlp-transformer/protobuf'; /** * OTLP-gRPC metric exporter diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts index 01a39a24795..f1409c8a048 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts @@ -17,7 +17,7 @@ import { OTLPMetricExporterOptions } from '../../OTLPMetricExporterOptions'; import { OTLPMetricExporterBase } from '../../OTLPMetricExporterBase'; import { OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base'; -import { JsonMetricsSerializer } from '@opentelemetry/otlp-transformer'; +import { JsonMetricsSerializer } from '@opentelemetry/otlp-transformer/json'; import { createLegacyOtlpBrowserExportDelegate } from '@opentelemetry/otlp-exporter-base/browser-http'; /** diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts index ae7ea320daf..c8369483ce8 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts @@ -17,7 +17,7 @@ import { OTLPMetricExporterOptions } from '../../OTLPMetricExporterOptions'; import { OTLPMetricExporterBase } from '../../OTLPMetricExporterBase'; import { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base'; -import { JsonMetricsSerializer } from '@opentelemetry/otlp-transformer'; +import { JsonMetricsSerializer } from '@opentelemetry/otlp-transformer/json'; import { VERSION } from '../../version'; import { convertLegacyHttpOptions, diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts index f2509dcedae..a8c43c0c72a 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts @@ -17,7 +17,7 @@ import { OTLPMetricExporterOptions } from '@opentelemetry/exporter-metrics-otlp-http'; import { OTLPMetricExporterBase } from '@opentelemetry/exporter-metrics-otlp-http'; import { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base'; -import { ProtobufMetricsSerializer } from '@opentelemetry/otlp-transformer'; +import { ProtobufMetricsSerializer } from '@opentelemetry/otlp-transformer/protobuf'; import { VERSION } from './version'; import { convertLegacyHttpOptions, diff --git a/experimental/packages/otlp-transformer/README.md b/experimental/packages/otlp-transformer/README.md index b91b6d06d71..476fc20ea91 100644 --- a/experimental/packages/otlp-transformer/README.md +++ b/experimental/packages/otlp-transformer/README.md @@ -21,7 +21,7 @@ npm install @opentelemetry/api ### Serialize Traces/Metrics/Logs -This module exports functions to serialize traces, metrics and logs from the OpenTelemetry SDK into protocol buffers which can be sent over HTTP to the OpenTelemetry collector or a compatible receiver. +This package exports functions to serialize traces, metrics and logs from the OpenTelemetry SDK into OTLP JSON format, which can be sent over HTTP to the OpenTelemetry collector or a compatible receiver. ```typescript import { @@ -30,11 +30,86 @@ import { createExportLogsServiceRequest, } from '@opentelemetry/otlp-transformer'; -const serializedSpans = createExportTraceServiceRequest(readableSpans); -const serializedMetrics = createExportMetricsServiceRequest(readableMetrics); -const serializedLogs = createExportLogsServiceRequest(readableLogRecords); +const serializableSpans = createExportTraceServiceRequest(readableSpans); +const serializableMetrics = createExportMetricsServiceRequest(readableMetrics); +const serializableLogs = createExportLogsServiceRequest(readableLogRecords); ``` +Note that these functions return JSON-serializable objects (i.e. JavaScript objects that can be passed into `JSON.stringify(...)`) adhering to the OTLP JSON format, not the serialized JSON-text payload themselves. + +### Protobuf (Binary) Serializers + +Additionally, this package also exports serializers to serialize traces, metrics and logs into the export requests using the OTLP binary protobuf format, as well as deserializing the corresponding binary response payloads. + +```typescript +import { + ProtobufTraceSerializer, + ProtobufMetricsSerializer, + ProtobufLogsSerializer, +} from '@opentelemetry/otlp-transformer/protobuf'; + +const serializedSpans: Uint8Array = + ProtobufTraceSerializer.serializeRequest(readableSpans); +const serializedMetrics: Uint8Array = + ProtobufMetricsSerializer.serializeRequest(readableMetrics); +const serializedLogs: Uint8Array = + ProtobufLogsSerializer.serializeRequest(readableLogRecords); + +// ... + +const deserializedTraceResponse = ProtobufTraceSerializer.deserializeResponse( + serializedTraceResponse /* Uint8Array */ +); +const deserializedMetricsResponse = + ProtobufMetricsSerializer.deserializeResponse( + serializedTraceResponse /* Uint8Array */ + ); +const deserializedLogsResponse = ProtobufLogsSerializer.deserializeResponse( + serializedTraceResponse /* Uint8Array */ +); +``` + +### JSON Serializers + +For feature parity, this package also exports JSON serializers with the same interfaces: + +```typescript +import { + JsonTraceSerializer, + JsonMetricsSerializer, + JsonLogsSerializer, +} from '@opentelemetry/otlp-transformer/json'; + +const serializedSpans: Uint8Array = + JsonTraceSerializer.serializeRequest(readableSpans); +const serializedMetrics: Uint8Array = + JsonMetricsSerializer.serializeRequest(readableMetrics); +const serializedLogs: Uint8Array = + JsonLogsSerializer.serializeRequest(readableLogRecords); + +// ... + +const deserializedTraceResponse = JsonTraceSerializer.deserializeResponse( + serializedTraceResponse /* Uint8Array */ +); +const deserializedMetricsResponse = JsonMetricsSerializer.deserializeResponse( + serializedTraceResponse /* Uint8Array */ +); +const deserializedLogsResponse = JsonLogsSerializer.deserializeResponse( + serializedTraceResponse /* Uint8Array */ +); +``` + +Unlike the `createExport*Request` functions (and similar to the binary protobuf serializers), these serializer methods return the _serialized_ bytes directly, skipping the need to further serialize them with `JSON.stringify(...)`. + +Among other things, the `Uint8Array` can be used directly as the `body` of a `fetch()` request. Likewise, a `Uint8Array` of the response body can be obtained from `await response.bytes()`. + +### Experimental Features + +As we iterate towards the stabilization of this package, certain features are expected to remain in experimental status. These features are subject to changes and breakages between minor versions of the package, even after the package itself reaches version `1.0`. + +These features are exported from the `@opentelemetry/otlp-transformer/experimental` entrypoint. Currently, this entrypoint is empty, as the entire package is considered experimental at the moment. It is expected to be utilized as part of upcoming stabilization efforts. + ## Useful links - For more information on OpenTelemetry, visit: diff --git a/experimental/packages/otlp-transformer/package.json b/experimental/packages/otlp-transformer/package.json index f01055187f6..b5ae1444117 100644 --- a/experimental/packages/otlp-transformer/package.json +++ b/experimental/packages/otlp-transformer/package.json @@ -6,10 +6,48 @@ }, "version": "0.56.0", "description": "Transform OpenTelemetry SDK data into OTLP", - "module": "build/esm/index.js", - "esnext": "build/esnext/index.js", - "types": "build/src/index.d.ts", - "main": "build/src/index.js", + "exports": { + ".": { + "module": "./build/esm/index.js", + "esnext": "./build/esnext/index.js", + "types": "./build/src/index.d.ts", + "default": "./build/src/index.js" + }, + "./experimental": { + "module": "./build/esm/experimental/index.js", + "esnext": "./build/esnext/experimental/index.js", + "types": "./build/src/experimental/index.d.ts", + "default": "./build/src/experimental/index.js" + }, + "./json": { + "module": "./build/esm/json/index.js", + "esnext": "./build/esnext/json/index.js", + "types": "./build/src/json/index.d.ts", + "default": "./build/src/json/index.js" + }, + "./protobuf": { + "module": "./build/esm/protobuf/index.js", + "esnext": "./build/esnext/protobuf/index.js", + "types": "./build/src/protobuf/index.d.ts", + "default": "./build/src/protobuf/index.js" + } + }, + "typesVersions": { + "*": { + "*": [ + "./build/src/index.d.ts" + ], + "experimental": [ + "./build/src/experimental/index.d.ts" + ], + "json": [ + "./build/src/json/index.d.ts" + ], + "protobuf": [ + "./build/src/protobuf/index.d.ts" + ] + } + }, "repository": "open-telemetry/opentelemetry-js", "scripts": { "prepublishOnly": "npm run compile", diff --git a/experimental/packages/otlp-transformer/src/experimental/index.ts b/experimental/packages/otlp-transformer/src/experimental/index.ts new file mode 100644 index 00000000000..445eb3186af --- /dev/null +++ b/experimental/packages/otlp-transformer/src/experimental/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export default {}; diff --git a/experimental/packages/otlp-transformer/src/index.ts b/experimental/packages/otlp-transformer/src/index.ts index 12c1cadc870..7f94d527ded 100644 --- a/experimental/packages/otlp-transformer/src/index.ts +++ b/experimental/packages/otlp-transformer/src/index.ts @@ -84,16 +84,4 @@ export { createExportTraceServiceRequest } from './trace'; export { createExportMetricsServiceRequest } from './metrics'; export { createExportLogsServiceRequest } from './logs'; -export { - ProtobufLogsSerializer, - ProtobufMetricsSerializer, - ProtobufTraceSerializer, -} from './protobuf/serializers'; - -export { - JsonTraceSerializer, - JsonLogsSerializer, - JsonMetricsSerializer, -} from './json/serializers'; - export { ISerializer } from './common/i-serializer'; diff --git a/experimental/packages/otlp-transformer/src/json/index.ts b/experimental/packages/otlp-transformer/src/json/index.ts new file mode 100644 index 00000000000..a7273be717c --- /dev/null +++ b/experimental/packages/otlp-transformer/src/json/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { + JsonTraceSerializer, + JsonMetricsSerializer, + JsonLogsSerializer, +} from './serializers'; diff --git a/experimental/packages/otlp-transformer/src/protobuf/index.ts b/experimental/packages/otlp-transformer/src/protobuf/index.ts new file mode 100644 index 00000000000..835965e8b29 --- /dev/null +++ b/experimental/packages/otlp-transformer/src/protobuf/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { + ProtobufTraceSerializer, + ProtobufMetricsSerializer, + ProtobufLogsSerializer, +} from './serializers'; diff --git a/experimental/packages/otlp-transformer/test/logs.test.ts b/experimental/packages/otlp-transformer/test/logs.test.ts index b279ae75dae..deadcdf5d94 100644 --- a/experimental/packages/otlp-transformer/test/logs.test.ts +++ b/experimental/packages/otlp-transformer/test/logs.test.ts @@ -21,10 +21,10 @@ import { createExportLogsServiceRequest, ESeverityNumber, IExportLogsServiceRequest, - ProtobufLogsSerializer, - JsonLogsSerializer, OtlpEncodingOptions, } from '../src'; +import { JsonLogsSerializer } from '../src/json'; +import { ProtobufLogsSerializer } from '../src/protobuf'; import { ReadableLogRecord } from '@opentelemetry/sdk-logs'; import { SeverityNumber } from '@opentelemetry/api-logs'; import { toBase64 } from './utils'; diff --git a/experimental/packages/otlp-transformer/test/metrics.test.ts b/experimental/packages/otlp-transformer/test/metrics.test.ts index 06d357102ef..a2d70567d94 100644 --- a/experimental/packages/otlp-transformer/test/metrics.test.ts +++ b/experimental/packages/otlp-transformer/test/metrics.test.ts @@ -26,12 +26,9 @@ import * as assert from 'assert'; import { createExportMetricsServiceRequest } from '../src/metrics'; import { EAggregationTemporality } from '../src/metrics/types'; import { hrTime, hrTimeToNanoseconds } from '@opentelemetry/core'; -import { - encodeAsString, - encodeAsLongBits, - ProtobufMetricsSerializer, - JsonMetricsSerializer, -} from '../src'; +import { encodeAsString, encodeAsLongBits } from '../src'; +import { JsonMetricsSerializer } from '../src/json'; +import { ProtobufMetricsSerializer } from '../src/protobuf'; import * as root from '../src/generated/root'; const START_TIME = hrTime(); diff --git a/experimental/packages/otlp-transformer/test/trace.test.ts b/experimental/packages/otlp-transformer/test/trace.test.ts index b740430dc30..81b0cbb5d72 100644 --- a/experimental/packages/otlp-transformer/test/trace.test.ts +++ b/experimental/packages/otlp-transformer/test/trace.test.ts @@ -24,9 +24,9 @@ import { createExportTraceServiceRequest, ESpanKind, EStatusCode, - ProtobufTraceSerializer, - JsonTraceSerializer, } from '../src'; +import { JsonTraceSerializer } from '../src/json'; +import { ProtobufTraceSerializer } from '../src/protobuf'; import { toBase64 } from './utils'; function createExpectedSpanJson(options: OtlpEncodingOptions) { From 7bfdb6cf833d3ef81217bc2ae8f50c382a8cd8b1 Mon Sep 17 00:00:00 2001 From: Sebastien Guillemot Date: Sat, 14 Dec 2024 00:41:32 +0900 Subject: [PATCH 2/2] refactor(otlp-transformer): json schema based validation --- api/test/common/diag/logLevel.test.ts | 2 +- .../packages/otlp-transformer/package.json | 3 +- .../otlp-transformer/src/common/types.ts | 131 +++--- .../otlp-transformer/src/logs/types.ts | 115 ++--- .../otlp-transformer/src/metrics/types.ts | 426 +++++++----------- .../otlp-transformer/src/resource/types.ts | 18 +- .../otlp-transformer/src/trace/types.ts | 195 +++----- package-lock.json | 39 +- 8 files changed, 392 insertions(+), 537 deletions(-) diff --git a/api/test/common/diag/logLevel.test.ts b/api/test/common/diag/logLevel.test.ts index 065e46d6831..e4b20932a93 100644 --- a/api/test/common/diag/logLevel.test.ts +++ b/api/test/common/diag/logLevel.test.ts @@ -77,7 +77,7 @@ describe('LogLevelFilter DiagLogger', () => { const levelMap: Array<{ message: string; - level: DiagLogLevel; + level: number | DiagLogLevel; ignoreFuncs: Array; }> = [ { message: 'ALL', level: DiagLogLevel.ALL, ignoreFuncs: [] }, diff --git a/experimental/packages/otlp-transformer/package.json b/experimental/packages/otlp-transformer/package.json index b5ae1444117..e4dfe1966ae 100644 --- a/experimental/packages/otlp-transformer/package.json +++ b/experimental/packages/otlp-transformer/package.json @@ -115,10 +115,11 @@ "nyc": "15.1.0", "protobufjs-cli": "1.1.3", "ts-loader": "9.5.1", - "typescript": "4.4.4", + "typescript": "5.7.2", "webpack": "5.96.1" }, "dependencies": { + "@sinclair/typebox": "0.34.11", "@opentelemetry/api-logs": "0.56.0", "@opentelemetry/core": "1.29.0", "@opentelemetry/resources": "1.29.0", diff --git a/experimental/packages/otlp-transformer/src/common/types.ts b/experimental/packages/otlp-transformer/src/common/types.ts index 732944f2e09..025e544e00f 100644 --- a/experimental/packages/otlp-transformer/src/common/types.ts +++ b/experimental/packages/otlp-transformer/src/common/types.ts @@ -14,72 +14,71 @@ * limitations under the License. */ -/** Properties of an InstrumentationScope. */ -export interface IInstrumentationScope { - /** InstrumentationScope name */ - name: string; - - /** InstrumentationScope version */ - version?: string; - - /** InstrumentationScope attributes */ - attributes?: IKeyValue[]; - - /** InstrumentationScope droppedAttributesCount */ - droppedAttributesCount?: number; -} - -/** Properties of a KeyValue. */ -export interface IKeyValue { - /** KeyValue key */ - key: string; - - /** KeyValue value */ - value: IAnyValue; -} - -/** Properties of an AnyValue. */ -export interface IAnyValue { - /** AnyValue stringValue */ - stringValue?: string | null; - - /** AnyValue boolValue */ - boolValue?: boolean | null; - - /** AnyValue intValue */ - intValue?: number | null; - - /** AnyValue doubleValue */ - doubleValue?: number | null; - - /** AnyValue arrayValue */ - arrayValue?: IArrayValue; - - /** AnyValue kvlistValue */ - kvlistValue?: IKeyValueList; - - /** AnyValue bytesValue */ - bytesValue?: Uint8Array; -} - -/** Properties of an ArrayValue. */ -export interface IArrayValue { - /** ArrayValue values */ - values: IAnyValue[]; -} - -/** Properties of a KeyValueList. */ -export interface IKeyValueList { - /** KeyValueList values */ - values: IKeyValue[]; -} - -export interface LongBits { - low: number; - high: number; -} - -export type Fixed64 = LongBits | string | number; +import { Type, type Static } from "@sinclair/typebox"; + +export const OtelCommonTypes = Type.Module({ + ResourceAttributes: Type.Object({ + key: Type.String(), + value: Type.Any(), + }), + IResource: Type.Object({ + attributes: Type.Array(Type.Ref("ResourceAttributes")), + }), + IKeyValue: Type.Object({ + key: Type.String(), + value: Type.Ref("IAnyValue"), + }), + IKeyValueList: Type.Object({ + values: Type.Array(Type.Ref("IKeyValue")), + }), + IArrayValue: Type.Object({ + values: Type.Array(Type.Ref("IAnyValue")), + }), + IAnyValue: Type.Object({ + stringValue: Type.Optional(Type.Union([Type.String(), Type.Null()])), + boolValue: Type.Optional(Type.Union([Type.Boolean(), Type.Null()])), + intValue: Type.Optional(Type.Union([Type.Number(), Type.Null()])), + doubleValue: Type.Optional(Type.Union([Type.Number(), Type.Null()])), + arrayValue: Type.Optional(Type.Ref("IArrayValue")), + kvlistValue: Type.Optional(Type.Ref("IKeyValueList")), + bytesValue: Type.Optional(Type.Uint8Array()), + }), + IInstrumentationScope: Type.Object({ + name: Type.String(), + version: Type.Optional(Type.String()), + attributes: Type.Optional(Type.Array(Type.Ref("IKeyValue"))), + droppedAttributesCount: Type.Optional(Type.Number()), + }), + LongBits: Type.Object({ + low: Type.Number(), + high: Type.Number(), + }), + Fixed64: Type.Union([Type.Ref("LongBits"), Type.String(), Type.Number()]), +}); + +export const TResourceAttributes = OtelCommonTypes.Import("ResourceAttributes"); +export type ResourceAttributes = Static; + +export const TKeyValue = OtelCommonTypes.Import("IKeyValue"); +export type IKeyValue = Static; + +export const TKeyValueList = OtelCommonTypes.Import("IKeyValueList"); +export type IKeyValueList = Static; + +export const TArrayValue = OtelCommonTypes.Import("IArrayValue"); +export type IArrayValue = Static; + +export const TAnyValue = OtelCommonTypes.Import("IAnyValue"); +export type IAnyValue = Static; + +export const TInstrumentationScope = OtelCommonTypes.Import("IInstrumentationScope"); +export type IInstrumentationScope = Static; + +export const TLongBits = OtelCommonTypes.Import("LongBits"); +export type LongBits = Static; + +export const TFixed64 = OtelCommonTypes.Import("Fixed64"); +export type Fixed64 = Static; export interface OtlpEncodingOptions { /** Convert trace and span IDs to hex strings. */ diff --git a/experimental/packages/otlp-transformer/src/logs/types.ts b/experimental/packages/otlp-transformer/src/logs/types.ts index 57c5422cbb4..94530514949 100644 --- a/experimental/packages/otlp-transformer/src/logs/types.ts +++ b/experimental/packages/otlp-transformer/src/logs/types.ts @@ -14,19 +14,9 @@ * limitations under the License. */ -import type { - Fixed64, - IAnyValue, - IInstrumentationScope, - IKeyValue, -} from '../common/types'; -import type { IResource } from '../resource/types'; - -/** Properties of an ExportLogsServiceRequest. */ -export interface IExportLogsServiceRequest { - /** ExportLogsServiceRequest resourceLogs */ - resourceLogs?: IResourceLogs[]; -} +import { Type, type Static } from "@sinclair/typebox"; +import { TKeyValue, TFixed64, TAnyValue, TInstrumentationScope } from "../common/types"; +import { TResource } from '../resource/types'; export interface IExportLogsServiceResponse { /** ExportLogsServiceResponse partialSuccess */ @@ -41,67 +31,10 @@ export interface IExportLogsPartialSuccess { errorMessage?: string; } -/** Properties of a ResourceLogs. */ -export interface IResourceLogs { - /** ResourceLogs resource */ - resource?: IResource; - - /** ResourceLogs scopeLogs */ - scopeLogs: IScopeLogs[]; - - /** ResourceLogs schemaUrl */ - schemaUrl?: string; -} - -/** Properties of an ScopeLogs. */ -export interface IScopeLogs { - /** IScopeLogs scope */ - scope?: IInstrumentationScope; - - /** IScopeLogs logRecords */ - logRecords?: ILogRecord[]; - - /** IScopeLogs schemaUrl */ - schemaUrl?: string | null; -} - -/** Properties of a LogRecord. */ -export interface ILogRecord { - /** LogRecord timeUnixNano */ - timeUnixNano: Fixed64; - - /** LogRecord observedTimeUnixNano */ - observedTimeUnixNano: Fixed64; - - /** LogRecord severityNumber */ - severityNumber?: ESeverityNumber; - - /** LogRecord severityText */ - severityText?: string; - - /** LogRecord body */ - body?: IAnyValue; - - /** LogRecord attributes */ - attributes: IKeyValue[]; - - /** LogRecord droppedAttributesCount */ - droppedAttributesCount: number; - - /** LogRecord flags */ - flags?: number; - - /** LogRecord traceId */ - traceId?: string | Uint8Array; - - /** LogRecord spanId */ - spanId?: string | Uint8Array; -} - /** * Numerical value of the severity, normalized to values described in Log Data Model. */ -export const enum ESeverityNumber { +export enum ESeverityNumber { /** Unspecified. Do NOT use as default */ SEVERITY_NUMBER_UNSPECIFIED = 0, SEVERITY_NUMBER_TRACE = 1, @@ -129,3 +62,43 @@ export const enum ESeverityNumber { SEVERITY_NUMBER_FATAL3 = 23, SEVERITY_NUMBER_FATAL4 = 24, } + +export const OtelLogTypes = Type.Module({ + ILogRecord: Type.Object({ + timeUnixNano: TFixed64, + observedTimeUnixNano: TFixed64, + severityNumber: Type.Optional(Type.Enum(ESeverityNumber)), + severityText: Type.Optional(Type.String()), + body: Type.Optional(TAnyValue), + attributes: Type.Array(TKeyValue), + droppedAttributesCount: Type.Number(), + flags: Type.Optional(Type.Number()), + traceId: Type.Optional(Type.Union([Type.String(), Type.Uint8Array()])), + spanId: Type.Optional(Type.Union([Type.String(), Type.Uint8Array()])), + }), + IScopeLogs: Type.Object({ + scope: Type.Optional(TInstrumentationScope), + logRecords: Type.Optional(Type.Array(Type.Ref("ILogRecord"))), + schemaUrl: Type.Optional(Type.Union([Type.String(), Type.Null()])), + }), + IResourceLogs: Type.Object({ + resource: Type.Optional(TResource), + scopeLogs: Type.Array(Type.Ref("IScopeLogs")), + schemaUrl: Type.Optional(Type.String()), + }), + IExportLogsServiceRequest: Type.Object({ + resourceLogs: Type.Optional(Type.Array(Type.Ref("IResourceLogs"))), + }), +}); + +export const TLogRecord = OtelLogTypes.Import("ILogRecord"); +export type ILogRecord = Static; + +export const TScopeLogs = OtelLogTypes.Import("IScopeLogs"); +export type IScopeLogs = Static; + +export const TResourceLogs = OtelLogTypes.Import("IResourceLogs"); +export type IResourceLogs = Static; + +export const TExportLogsServiceRequest = OtelLogTypes.Import("IExportLogsServiceRequest"); +export type IExportLogsServiceRequest = Static; diff --git a/experimental/packages/otlp-transformer/src/metrics/types.ts b/experimental/packages/otlp-transformer/src/metrics/types.ts index 208c6aa6782..843d434cf40 100644 --- a/experimental/packages/otlp-transformer/src/metrics/types.ts +++ b/experimental/packages/otlp-transformer/src/metrics/types.ts @@ -13,14 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Fixed64, IInstrumentationScope, IKeyValue } from '../common/types'; -import { IResource } from '../resource/types'; - -/** Properties of an ExportMetricsServiceRequest. */ -export interface IExportMetricsServiceRequest { - /** ExportMetricsServiceRequest resourceMetrics */ - resourceMetrics: IResourceMetrics[]; -} +import { TFixed64, TInstrumentationScope, TKeyValue } from '../common/types'; +import { TResource } from '../resource/types'; +import { Type, type Static } from "@sinclair/typebox"; export interface IExportMetricsServiceResponse { /** ExportMetricsServiceResponse partialSuccess */ @@ -35,270 +30,12 @@ export interface IExportMetricsPartialSuccess { errorMessage?: string; } -/** Properties of a ResourceMetrics. */ -export interface IResourceMetrics { - /** ResourceMetrics resource */ - resource?: IResource; - - /** ResourceMetrics scopeMetrics */ - scopeMetrics: IScopeMetrics[]; - - /** ResourceMetrics schemaUrl */ - schemaUrl?: string; -} - -/** Properties of an IScopeMetrics. */ -export interface IScopeMetrics { - /** ScopeMetrics scope */ - scope?: IInstrumentationScope; - - /** ScopeMetrics metrics */ - metrics: IMetric[]; - - /** ScopeMetrics schemaUrl */ - schemaUrl?: string; -} - -/** Properties of a Metric. */ -export interface IMetric { - /** Metric name */ - name: string; - - /** Metric description */ - description?: string; - - /** Metric unit */ - unit?: string; - - /** Metric gauge */ - gauge?: IGauge; - - /** Metric sum */ - sum?: ISum; - - /** Metric histogram */ - histogram?: IHistogram; - - /** Metric exponentialHistogram */ - exponentialHistogram?: IExponentialHistogram; - - /** Metric summary */ - summary?: ISummary; -} - -/** Properties of a Gauge. */ -export interface IGauge { - /** Gauge dataPoints */ - dataPoints: INumberDataPoint[]; -} - -/** Properties of a Sum. */ -export interface ISum { - /** Sum dataPoints */ - dataPoints: INumberDataPoint[]; - - /** Sum aggregationTemporality */ - aggregationTemporality: EAggregationTemporality; - - /** Sum isMonotonic */ - isMonotonic?: boolean | null; -} - -/** Properties of a Histogram. */ -export interface IHistogram { - /** Histogram dataPoints */ - dataPoints: IHistogramDataPoint[]; - - /** Histogram aggregationTemporality */ - aggregationTemporality?: EAggregationTemporality; -} - -/** Properties of an ExponentialHistogram. */ -export interface IExponentialHistogram { - /** ExponentialHistogram dataPoints */ - dataPoints: IExponentialHistogramDataPoint[]; - - /** ExponentialHistogram aggregationTemporality */ - aggregationTemporality?: EAggregationTemporality; -} - -/** Properties of a Summary. */ -export interface ISummary { - /** Summary dataPoints */ - dataPoints: ISummaryDataPoint[]; -} - -/** Properties of a NumberDataPoint. */ -export interface INumberDataPoint { - /** NumberDataPoint attributes */ - attributes: IKeyValue[]; - - /** NumberDataPoint startTimeUnixNano */ - startTimeUnixNano?: Fixed64; - - /** NumberDataPoint timeUnixNano */ - timeUnixNano?: Fixed64; - - /** NumberDataPoint asDouble */ - asDouble?: number | null; - - /** NumberDataPoint asInt */ - asInt?: number; - - /** NumberDataPoint exemplars */ - exemplars?: IExemplar[]; - - /** NumberDataPoint flags */ - flags?: number; -} - -/** Properties of a HistogramDataPoint. */ -export interface IHistogramDataPoint { - /** HistogramDataPoint attributes */ - attributes?: IKeyValue[]; - - /** HistogramDataPoint startTimeUnixNano */ - startTimeUnixNano?: Fixed64; - - /** HistogramDataPoint timeUnixNano */ - timeUnixNano?: Fixed64; - - /** HistogramDataPoint count */ - count?: number; - - /** HistogramDataPoint sum */ - sum?: number; - - /** HistogramDataPoint bucketCounts */ - bucketCounts?: number[]; - - /** HistogramDataPoint explicitBounds */ - explicitBounds?: number[]; - - /** HistogramDataPoint exemplars */ - exemplars?: IExemplar[]; - - /** HistogramDataPoint flags */ - flags?: number; - - /** HistogramDataPoint min */ - min?: number; - - /** HistogramDataPoint max */ - max?: number; -} - -/** Properties of an ExponentialHistogramDataPoint. */ -export interface IExponentialHistogramDataPoint { - /** ExponentialHistogramDataPoint attributes */ - attributes?: IKeyValue[]; - - /** ExponentialHistogramDataPoint startTimeUnixNano */ - startTimeUnixNano?: Fixed64; - - /** ExponentialHistogramDataPoint timeUnixNano */ - timeUnixNano?: Fixed64; - - /** ExponentialHistogramDataPoint count */ - count?: number; - - /** ExponentialHistogramDataPoint sum */ - sum?: number; - - /** ExponentialHistogramDataPoint scale */ - scale?: number; - - /** ExponentialHistogramDataPoint zeroCount */ - zeroCount?: number; - - /** ExponentialHistogramDataPoint positive */ - positive?: IBuckets; - - /** ExponentialHistogramDataPoint negative */ - negative?: IBuckets; - - /** ExponentialHistogramDataPoint flags */ - flags?: number; - - /** ExponentialHistogramDataPoint exemplars */ - exemplars?: IExemplar[]; - - /** ExponentialHistogramDataPoint min */ - min?: number; - - /** ExponentialHistogramDataPoint max */ - max?: number; -} - -/** Properties of a SummaryDataPoint. */ -export interface ISummaryDataPoint { - /** SummaryDataPoint attributes */ - attributes?: IKeyValue[]; - - /** SummaryDataPoint startTimeUnixNano */ - startTimeUnixNano?: number; - - /** SummaryDataPoint timeUnixNano */ - timeUnixNano?: string; - - /** SummaryDataPoint count */ - count?: number; - - /** SummaryDataPoint sum */ - sum?: number; - - /** SummaryDataPoint quantileValues */ - quantileValues?: IValueAtQuantile[]; - - /** SummaryDataPoint flags */ - flags?: number; -} - -/** Properties of a ValueAtQuantile. */ -export interface IValueAtQuantile { - /** ValueAtQuantile quantile */ - quantile?: number; - - /** ValueAtQuantile value */ - value?: number; -} - -/** Properties of a Buckets. */ -export interface IBuckets { - /** Buckets offset */ - offset?: number; - - /** Buckets bucketCounts */ - bucketCounts?: number[]; -} - -/** Properties of an Exemplar. */ -export interface IExemplar { - /** Exemplar filteredAttributes */ - filteredAttributes?: IKeyValue[]; - - /** Exemplar timeUnixNano */ - timeUnixNano?: string; - - /** Exemplar asDouble */ - asDouble?: number; - - /** Exemplar asInt */ - asInt?: number; - - /** Exemplar spanId */ - spanId?: string | Uint8Array; - - /** Exemplar traceId */ - traceId?: string | Uint8Array; -} - /** * AggregationTemporality defines how a metric aggregator reports aggregated * values. It describes how those values relate to the time interval over * which they are aggregated. */ -export const enum EAggregationTemporality { +export enum EAggregationTemporality { /* UNSPECIFIED is the default AggregationTemporality, it MUST not be used. */ AGGREGATION_TEMPORALITY_UNSPECIFIED = 0, @@ -365,3 +102,158 @@ export const enum EAggregationTemporality { value was reset (e.g. Prometheus). */ AGGREGATION_TEMPORALITY_CUMULATIVE = 2, } + +export const OtelMetricTypes = Type.Module({ + IExportMetricsServiceRequest: Type.Object({ + resourceMetrics: Type.Array(Type.Ref("IResourceMetrics")), + }), + IResourceMetrics: Type.Object({ + resource: Type.Optional(TResource), + scopeMetrics: Type.Array(Type.Ref("IScopeMetrics")), + schemaUrl: Type.Optional(Type.String()), + }), + IScopeMetrics: Type.Object({ + scope: Type.Optional(TInstrumentationScope), + metrics: Type.Array(Type.Ref("IMetric")), + schemaUrl: Type.Optional(Type.String()), + }), + IMetric: Type.Object({ + name: Type.String(), + description: Type.Optional(Type.String()), + unit: Type.Optional(Type.String()), + gauge: Type.Optional(Type.Ref("IGauge")), + sum: Type.Optional(Type.Ref("ISum")), + histogram: Type.Optional(Type.Ref("IHistogram")), + exponentialHistogram: Type.Optional(Type.Ref("IExponentialHistogram")), + summary: Type.Optional(Type.Ref("ISummary")), + }), + IGauge: Type.Object({ + dataPoints: Type.Array(Type.Ref("INumberDataPoint")), + }), + ISum: Type.Object({ + dataPoints: Type.Array(Type.Ref("INumberDataPoint")), + aggregationTemporality: Type.Enum(EAggregationTemporality), + isMonotonic: Type.Optional(Type.Union([Type.Boolean(), Type.Null()])), + }), + IHistogram: Type.Object({ + dataPoints: Type.Array(Type.Ref("IHistogramDataPoint")), + aggregationTemporality: Type.Optional(Type.Enum(EAggregationTemporality)), + }), + IExponentialHistogram: Type.Object({ + dataPoints: Type.Array(Type.Ref("IExponentialHistogramDataPoint")), + aggregationTemporality: Type.Optional(Type.Enum(EAggregationTemporality)), + }), + ISummary: Type.Object({ + dataPoints: Type.Array(Type.Ref("ISummaryDataPoint")), + }), + INumberDataPoint: Type.Object({ + attributes: Type.Array(TKeyValue), + startTimeUnixNano: Type.Optional(TFixed64), + timeUnixNano: Type.Optional(TFixed64), + asDouble: Type.Optional(Type.Union([Type.Number(), Type.Null()])), + asInt: Type.Optional(Type.Number()), + exemplars: Type.Optional(Type.Array(Type.Ref("IExemplar"))), + flags: Type.Optional(Type.Number()), + }), + IHistogramDataPoint: Type.Object({ + attributes: Type.Optional(Type.Array(TKeyValue)), + startTimeUnixNano: Type.Optional(TFixed64), + timeUnixNano: Type.Optional(TFixed64), + count: Type.Optional(Type.Number()), + sum: Type.Optional(Type.Number()), + bucketCounts: Type.Optional(Type.Array(Type.Number())), + explicitBounds: Type.Optional(Type.Array(Type.Number())), + exemplars: Type.Optional(Type.Array(Type.Ref("IExemplar"))), + flags: Type.Optional(Type.Number()), + min: Type.Optional(Type.Number()), + max: Type.Optional(Type.Number()), + }), + IExponentialHistogramDataPoint: Type.Object({ + attributes: Type.Optional(Type.Array(TKeyValue)), + startTimeUnixNano: Type.Optional(TFixed64), + timeUnixNano: Type.Optional(TFixed64), + count: Type.Optional(Type.Number()), + sum: Type.Optional(Type.Number()), + scale: Type.Optional(Type.Number()), + zeroCount: Type.Optional(Type.Number()), + positive: Type.Optional(Type.Ref("IBuckets")), + negative: Type.Optional(Type.Ref("IBuckets")), + flags: Type.Optional(Type.Number()), + exemplars: Type.Optional(Type.Array(Type.Ref("IExemplar"))), + min: Type.Optional(Type.Number()), + max: Type.Optional(Type.Number()), + }), + ISummaryDataPoint: Type.Object({ + attributes: Type.Optional(Type.Array(TKeyValue)), + startTimeUnixNano: Type.Optional(Type.Number()), + timeUnixNano: Type.Optional(Type.String()), + count: Type.Optional(Type.Number()), + sum: Type.Optional(Type.Number()), + quantileValues: Type.Optional(Type.Array(Type.Ref("IValueAtQuantile"))), + flags: Type.Optional(Type.Number()), + }), + IValueAtQuantile: Type.Object({ + quantile: Type.Optional(Type.Number()), + value: Type.Optional(Type.Number()), + }), + IBuckets: Type.Object({ + offset: Type.Optional(Type.Number()), + bucketCounts: Type.Optional(Type.Array(Type.Number())), + }), + IExemplar: Type.Object({ + filteredAttributes: Type.Optional(Type.Array(TKeyValue)), + timeUnixNano: Type.Optional(Type.String()), + asDouble: Type.Optional(Type.Number()), + asInt: Type.Optional(Type.Number()), + spanId: Type.Optional(Type.Union([Type.String(), Type.Uint8Array()])), + traceId: Type.Optional(Type.Union([Type.String(), Type.Uint8Array()])), + }), +}); + +export const TExportMetricsServiceRequest = OtelMetricTypes.Import("IExportMetricsServiceRequest"); +export type IExportMetricsServiceRequest = Static; + +export const TResourceMetrics = OtelMetricTypes.Import("IResourceMetrics"); +export type IResourceMetrics = Static; + +export const TScopeMetrics = OtelMetricTypes.Import("IScopeMetrics"); +export type IScopeMetrics = Static; + +export const TMetric = OtelMetricTypes.Import("IMetric"); +export type IMetric = Static; + +export const TGauge = OtelMetricTypes.Import("IGauge"); +export type IGauge = Static; + +export const TSum = OtelMetricTypes.Import("ISum"); +export type ISum = Static; + +export const THistogram = OtelMetricTypes.Import("IHistogram"); +export type IHistogram = Static; + +export const TExponentialHistogram = OtelMetricTypes.Import("IExponentialHistogram"); +export type IExponentialHistogram = Static; + +export const TSummary = OtelMetricTypes.Import("ISummary"); +export type ISummary = Static; + +export const TNumberDataPoint = OtelMetricTypes.Import("INumberDataPoint"); +export type INumberDataPoint = Static; + +export const THistogramDataPoint = OtelMetricTypes.Import("IHistogramDataPoint"); +export type IHistogramDataPoint = Static; + +export const TExponentialHistogramDataPoint = OtelMetricTypes.Import("IExponentialHistogramDataPoint"); +export type IExponentialHistogramDataPoint = Static; + +export const TSummaryDataPoint = OtelMetricTypes.Import("ISummaryDataPoint"); +export type ISummaryDataPoint = Static; + +export const TValueAtQuantile = OtelMetricTypes.Import("IValueAtQuantile"); +export type IValueAtQuantile = Static; + +export const TBuckets = OtelMetricTypes.Import("IBuckets"); +export type IBuckets = Static; + +export const TExemplar = OtelMetricTypes.Import("IExemplar"); +export type IExemplar = Static; diff --git a/experimental/packages/otlp-transformer/src/resource/types.ts b/experimental/packages/otlp-transformer/src/resource/types.ts index 7755b756e91..b85abaf399e 100644 --- a/experimental/packages/otlp-transformer/src/resource/types.ts +++ b/experimental/packages/otlp-transformer/src/resource/types.ts @@ -14,13 +14,15 @@ * limitations under the License. */ -import { IKeyValue } from '../common/types'; +import { TKeyValue } from '../common/types'; +import { Type, type Static } from "@sinclair/typebox"; -/** Properties of a Resource. */ -export interface IResource { - /** Resource attributes */ - attributes: IKeyValue[]; +export const OtelResourceTypes = Type.Module({ + IResource: Type.Object({ + attributes: Type.Array(TKeyValue), + droppedAttributesCount: Type.Number(), + }), +}); - /** Resource droppedAttributesCount */ - droppedAttributesCount: number; -} +export const TResource = OtelResourceTypes.Import("IResource"); +export type IResource = Static; diff --git a/experimental/packages/otlp-transformer/src/trace/types.ts b/experimental/packages/otlp-transformer/src/trace/types.ts index d32c85eb5a5..6279918ccf6 100644 --- a/experimental/packages/otlp-transformer/src/trace/types.ts +++ b/experimental/packages/otlp-transformer/src/trace/types.ts @@ -14,14 +14,10 @@ * limitations under the License. */ -import { Fixed64, IInstrumentationScope, IKeyValue } from '../common/types'; -import { IResource } from '../resource/types'; -/** Properties of an ExportTraceServiceRequest. */ -export interface IExportTraceServiceRequest { - /** ExportTraceServiceRequest resourceSpans */ - resourceSpans?: IResourceSpans[]; -} +import { TFixed64, TInstrumentationScope, TKeyValue } from '../common/types'; +import { Type, type Static } from "@sinclair/typebox"; +import { TResource } from '../resource/types'; export interface IExportTraceServiceResponse { /** ExportTraceServiceResponse partialSuccess */ @@ -36,78 +32,6 @@ export interface IExportTracePartialSuccess { errorMessage?: string; } -/** Properties of a ResourceSpans. */ -export interface IResourceSpans { - /** ResourceSpans resource */ - resource?: IResource; - - /** ResourceSpans scopeSpans */ - scopeSpans: IScopeSpans[]; - - /** ResourceSpans schemaUrl */ - schemaUrl?: string; -} - -/** Properties of an ScopeSpans. */ -export interface IScopeSpans { - /** IScopeSpans scope */ - scope?: IInstrumentationScope; - - /** IScopeSpans spans */ - spans?: ISpan[]; - - /** IScopeSpans schemaUrl */ - schemaUrl?: string | null; -} - -/** Properties of a Span. */ -export interface ISpan { - /** Span traceId */ - traceId: string | Uint8Array; - - /** Span spanId */ - spanId: string | Uint8Array; - - /** Span traceState */ - traceState?: string | null; - - /** Span parentSpanId */ - parentSpanId?: string | Uint8Array; - - /** Span name */ - name: string; - - /** Span kind */ - kind: ESpanKind; - - /** Span startTimeUnixNano */ - startTimeUnixNano: Fixed64; - - /** Span endTimeUnixNano */ - endTimeUnixNano: Fixed64; - - /** Span attributes */ - attributes: IKeyValue[]; - - /** Span droppedAttributesCount */ - droppedAttributesCount: number; - - /** Span events */ - events: IEvent[]; - - /** Span droppedEventsCount */ - droppedEventsCount: number; - - /** Span links */ - links: ILink[]; - - /** Span droppedLinksCount */ - droppedLinksCount: number; - - /** Span status */ - status: IStatus; -} - /** * SpanKind is the type of span. Can be used to specify additional relationships between spans * in addition to a parent/child relationship. @@ -144,17 +68,8 @@ export enum ESpanKind { SPAN_KIND_CONSUMER = 5, } -/** Properties of a Status. */ -export interface IStatus { - /** Status message */ - message?: string; - - /** Status code */ - code: EStatusCode; -} - /** StatusCode enum. */ -export const enum EStatusCode { +export enum EStatusCode { /** The default status. */ STATUS_CODE_UNSET = 0, /** The Span has been evaluated by an Application developers or Operator to have completed successfully. */ @@ -163,35 +78,73 @@ export const enum EStatusCode { STATUS_CODE_ERROR = 2, } -/** Properties of an Event. */ -export interface IEvent { - /** Event timeUnixNano */ - timeUnixNano: Fixed64; - - /** Event name */ - name: string; - - /** Event attributes */ - attributes: IKeyValue[]; - - /** Event droppedAttributesCount */ - droppedAttributesCount: number; -} - -/** Properties of a Link. */ -export interface ILink { - /** Link traceId */ - traceId: string | Uint8Array; - - /** Link spanId */ - spanId: string | Uint8Array; - - /** Link traceState */ - traceState?: string; - - /** Link attributes */ - attributes: IKeyValue[]; - - /** Link droppedAttributesCount */ - droppedAttributesCount: number; -} +export const OtelTraceTypes = Type.Module({ + IExportTraceServiceRequest: Type.Object({ + resourceSpans: Type.Optional(Type.Array(Type.Ref("IResourceSpans"))), + }), + IResourceSpans: Type.Object({ + resource: Type.Optional(TResource), + scopeSpans: Type.Array(Type.Ref("IScopeSpans")), + schemaUrl: Type.Optional(Type.String()), + }), + IScopeSpans: Type.Object({ + scope: Type.Optional(TInstrumentationScope), + spans: Type.Optional(Type.Array(Type.Ref("ISpan"))), + schemaUrl: Type.Optional(Type.Union([Type.String(), Type.Null()])), + }), + ISpan: Type.Object({ + traceId: Type.Union([Type.String(), Type.Uint8Array()]), + spanId: Type.Union([Type.String(), Type.Uint8Array()]), + traceState: Type.Optional(Type.Union([Type.String(), Type.Null()])), + parentSpanId: Type.Optional(Type.Union([Type.String(), Type.Uint8Array()])), + name: Type.String(), + kind: Type.Enum(ESpanKind), + startTimeUnixNano: TFixed64, + endTimeUnixNano: TFixed64, + attributes: Type.Array(TKeyValue), + droppedAttributesCount: Type.Number(), + events: Type.Array(Type.Ref("IEvent")), + droppedEventsCount: Type.Number(), + links: Type.Array(Type.Ref("ILink")), + droppedLinksCount: Type.Number(), + status: Type.Ref("IStatus"), + }), + IStatus: Type.Object({ + message: Type.Optional(Type.String()), + code: Type.Enum(EStatusCode), + }), + IEvent: Type.Object({ + timeUnixNano: TFixed64, + name: Type.String(), + attributes: Type.Array(TKeyValue), + droppedAttributesCount: Type.Number(), + }), + ILink: Type.Object({ + traceId: Type.Union([Type.String(), Type.Uint8Array()]), + spanId: Type.Union([Type.String(), Type.Uint8Array()]), + traceState: Type.Optional(Type.String()), + attributes: Type.Array(TKeyValue), + droppedAttributesCount: Type.Number(), + }), +}); + +export const TExportTraceServiceRequest = OtelTraceTypes.Import("IExportTraceServiceRequest"); +export type IExportTraceServiceRequest = Static; + +export const TResourceSpans = OtelTraceTypes.Import("IResourceSpans"); +export type IResourceSpans = Static; + +export const TScopeSpans = OtelTraceTypes.Import("IScopeSpans"); +export type IScopeSpans = Static; + +export const TSpan = OtelTraceTypes.Import("ISpan"); +export type ISpan = Static; + +export const TStatus = OtelTraceTypes.Import("IStatus"); +export type IStatus = Static; + +export const TEvent = OtelTraceTypes.Import("IEvent"); +export type IEvent = Static; + +export const TLink = OtelTraceTypes.Import("ILink"); +export type ILink = Static; diff --git a/package-lock.json b/package-lock.json index cc662cb348f..76b7395ca67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1167,6 +1167,7 @@ "@opentelemetry/sdk-logs": "0.56.0", "@opentelemetry/sdk-metrics": "1.29.0", "@opentelemetry/sdk-trace-base": "1.29.0", + "@sinclair/typebox": "0.34.11", "protobufjs": "^7.3.0" }, "devDependencies": { @@ -1186,7 +1187,7 @@ "nyc": "15.1.0", "protobufjs-cli": "1.1.3", "ts-loader": "9.5.1", - "typescript": "4.4.4", + "typescript": "5.7.2", "webpack": "5.96.1" }, "engines": { @@ -1196,6 +1197,26 @@ "@opentelemetry/api": "^1.3.0" } }, + "experimental/packages/otlp-transformer/node_modules/@sinclair/typebox": { + "version": "0.34.11", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.11.tgz", + "integrity": "sha512-zE9pWGVSG82z+sFO+oUmqmqRVm8Wg5sVhmljYi1fDhLOSphBBy939QmC/qXcKFWqTiRJ6keyG4y75bIoTPRBAw==", + "license": "MIT" + }, + "experimental/packages/otlp-transformer/node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "experimental/packages/sampler-jaeger-remote": { "name": "@opentelemetry/sampler-jaeger-remote", "version": "0.56.0", @@ -32466,6 +32487,7 @@ "@opentelemetry/sdk-logs": "0.56.0", "@opentelemetry/sdk-metrics": "1.29.0", "@opentelemetry/sdk-trace-base": "1.29.0", + "@sinclair/typebox": "0.34.11", "@types/mocha": "10.0.10", "@types/webpack-env": "1.16.3", "babel-plugin-istanbul": "7.0.0", @@ -32482,8 +32504,21 @@ "protobufjs": "^7.3.0", "protobufjs-cli": "1.1.3", "ts-loader": "9.5.1", - "typescript": "4.4.4", + "typescript": "5.7.2", "webpack": "5.96.1" + }, + "dependencies": { + "@sinclair/typebox": { + "version": "0.34.11", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.11.tgz", + "integrity": "sha512-zE9pWGVSG82z+sFO+oUmqmqRVm8Wg5sVhmljYi1fDhLOSphBBy939QmC/qXcKFWqTiRJ6keyG4y75bIoTPRBAw==" + }, + "typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true + } } }, "@opentelemetry/propagator-b3": {