diff --git a/package-lock.json b/package-lock.json index 07d243c6..6ab28a34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@commitlint/config-conventional": "^17.8.1", "@ibm/telemetry-config-schema": "^0.2.0", "@opentelemetry/api": "^1.6.0", + "@opentelemetry/exporter-metrics-otlp-http": "^0.44.0", "@opentelemetry/resources": "^1.17.1", "@opentelemetry/sdk-metrics": "^1.17.1", "@opentelemetry/semantic-conventions": "^1.17.1", @@ -1177,6 +1178,18 @@ "node": ">=8.0.0" } }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.44.0.tgz", + "integrity": "sha512-OctojdKGmXHKAJa4/Ml+Nf7MD9jtYXvZyP64xTh0pNTmtgaTdWW3FURri2DdB/+l7YxRy0tYYZS3/tYEM1pj3w==", + "dev": true, + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/@opentelemetry/core": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.17.1.tgz", @@ -1192,6 +1205,60 @@ "@opentelemetry/api": ">=1.0.0 <1.7.0" } }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.44.0.tgz", + "integrity": "sha512-OiEkP9XWbh5ufjnP+xe8EQ2LShMY5f1NYBm9W/BgLaHPtlMNZnR7JB1t6Ut4gaZ7LA/yFnyrB0TnZcxntpBZ3Q==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-metrics": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.44.0.tgz", + "integrity": "sha512-DKQqRrfVMe96aSLZiCgIesLcMLfnWH8d4bTpLB1JbU+SAQJ7nVCAfS9U36mjFCVhvNDD7gwfCNrxqFMCHq6FUw==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.44.0.tgz", + "integrity": "sha512-1/KC+aHM1oGEsXyNy7QoxpvErxGdzt26bg9VHyNb4TDILkUFdwrnywnxPc6lXZ6h/8T8Mt718UWOKjNHC514kQ==", + "dev": true, + "dependencies": { + "@opentelemetry/api-logs": "0.44.0", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-logs": "0.44.0", + "@opentelemetry/sdk-metrics": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.7.0" + } + }, "node_modules/@opentelemetry/resources": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.17.1.tgz", @@ -1208,6 +1275,23 @@ "@opentelemetry/api": ">=1.0.0 <1.7.0" } }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.44.0.tgz", + "integrity": "sha512-UN3ofh9Jj54gIgrSXNRWAoaH6iPvrrjed5YAtqO9cW65U+5QPzk1Rv95vjAcY9VTrmMWvuqgEK1CYObG6Hu4OQ==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.7.0", + "@opentelemetry/api-logs": ">=0.39.1" + } + }, "node_modules/@opentelemetry/sdk-metrics": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.17.1.tgz", @@ -1225,6 +1309,23 @@ "@opentelemetry/api": ">=1.3.0 <1.7.0" } }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.17.1.tgz", + "integrity": "sha512-pfSJJSjZj5jkCJUQZicSpzN8Iz9UKMryPWikZRGObPnJo6cUSoKkjZh6BM3j+D47G4olMBN+YZKYqkFM1L6zNA==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/semantic-conventions": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.7.0" + } + }, "node_modules/@opentelemetry/semantic-conventions": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.17.1.tgz", diff --git a/package.json b/package.json index e5e3fce6..566a7d0d 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@commitlint/config-conventional": "^17.8.1", "@ibm/telemetry-config-schema": "^0.2.0", "@opentelemetry/api": "^1.6.0", + "@opentelemetry/exporter-metrics-otlp-http": "^0.44.0", "@opentelemetry/resources": "^1.17.1", "@opentelemetry/sdk-metrics": "^1.17.1", "@opentelemetry/semantic-conventions": "^1.17.1", diff --git a/src/main/core/custom-resource-attributes.ts b/src/main/core/custom-resource-attributes.ts index 837c7afb..c9c5aa61 100644 --- a/src/main/core/custom-resource-attributes.ts +++ b/src/main/core/custom-resource-attributes.ts @@ -4,7 +4,6 @@ * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ - export const CustomResourceAttributes = Object.freeze({ // // General attributes diff --git a/src/main/core/initialize-open-telemetry.ts b/src/main/core/initialize-open-telemetry.ts index da9a56f1..33537265 100644 --- a/src/main/core/initialize-open-telemetry.ts +++ b/src/main/core/initialize-open-telemetry.ts @@ -20,8 +20,7 @@ import { ManualMetricReader } from './manual-metric-reader.js' function initializeOpenTelemetry(config: Attributes) { const resource = Resource.default().merge( new Resource({ - // By default, remove the service name attribute, since it is unused - [SemanticResourceAttributes.SERVICE_NAME]: undefined, + [SemanticResourceAttributes.SERVICE_NAME]: 'IBM Telemetry', ...config }) ) diff --git a/src/main/core/manual-metric-reader.ts b/src/main/core/manual-metric-reader.ts index 5a5b556b..9cf14822 100644 --- a/src/main/core/manual-metric-reader.ts +++ b/src/main/core/manual-metric-reader.ts @@ -4,33 +4,15 @@ * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ -import { type CollectionResult, type DataPoint, MetricReader } from '@opentelemetry/sdk-metrics' +import { type CollectionResult, MetricReader } from '@opentelemetry/sdk-metrics' import { type CommonReaderOptions } from '@opentelemetry/sdk-metrics/build/src/types.js' -interface UnlockedDataPoint extends DataPoint { - startTime: DataPoint['startTime'] - endTime: DataPoint['endTime'] -} - /** * A metric reader that can be invoked manually with `collect()` to obtain its metrics. */ export class ManualMetricReader extends MetricReader { override async collect(options?: CommonReaderOptions | undefined): Promise { - const results = await super.collect(options) - - // Zero out all startTime and EndTime attributes in data points - results.resourceMetrics.scopeMetrics.forEach((scopeMetric) => { - scopeMetric.metrics.forEach((metric) => { - metric.dataPoints.forEach((dataPoint) => { - const unlocked = dataPoint as UnlockedDataPoint - unlocked.startTime = [0, 0] - unlocked.endTime = [0, 0] - }) - }) - }) - - return results + return await super.collect(options) } protected override async onShutdown(): Promise { diff --git a/src/main/core/scope.ts b/src/main/core/scope.ts index 9d2c90f8..7bb6b342 100644 --- a/src/main/core/scope.ts +++ b/src/main/core/scope.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ import { type ConfigSchema } from '@ibm/telemetry-config-schema' -import opentelemetry, { type Counter, type Meter } from '@opentelemetry/api' +import opentelemetry, { type Counter, type Meter, ValueType } from '@opentelemetry/api' import { Loggable } from './log/loggable.js' import { type Logger } from './log/logger.js' @@ -74,7 +74,9 @@ export abstract class Scope extends Loggable { // Ensure a counter exists if (this.metrics[dataPoint.name] === undefined) { - this.metrics[dataPoint.name] = this.scopeMeter.createCounter(dataPoint.name) + this.metrics[dataPoint.name] = this.scopeMeter.createCounter(dataPoint.name, { + valueType: ValueType.INT + }) } // Log the metric diff --git a/src/main/telemetry-collector.ts b/src/main/telemetry-collector.ts index 0fd52eca..9db1aa97 100644 --- a/src/main/telemetry-collector.ts +++ b/src/main/telemetry-collector.ts @@ -6,6 +6,8 @@ */ import { type ConfigSchema } from '@ibm/telemetry-config-schema' +// import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http' +// import { AggregationTemporality } from '@opentelemetry/sdk-metrics' import { type Schema } from 'ajv' import { anonymize } from './core/anonymize.js' @@ -107,6 +109,19 @@ export class TelemetryCollector { - transmit the data to the remote server */ + // const exporter = new OTLPMetricExporter({ + // url: 'http://localhost:3000/v1/metrics', + // headers: { + // // This is where we could define project-specific headers to "authenticate" requests + // Authorization: 'Bearer abc123' + // }, + // temporalityPreference: AggregationTemporality.DELTA + // }) + + // exporter.export(results.resourceMetrics, (exportResult) => { + // console.log(exportResult) + // }) + this.logger.debug('Collection results:') this.logger.debug(JSON.stringify(results, undefined, 2)) }