Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(proto): add @opentelemetry/proto package #2691

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0090664
feat(proto): add @opentelemetry/proto package
dyladan Dec 28, 2021
7e876b3
chore: autogenerate proto files on compile
dyladan Dec 28, 2021
d38c380
chore: add proto to tsconfig
dyladan Dec 28, 2021
27137ca
chore: add proto to submodle
dyladan Dec 28, 2021
00edec0
chore: add generate to lerna precompile
dyladan Dec 28, 2021
1a55158
chore: download submodules before compile
dyladan Dec 28, 2021
e8e4e2c
chore: move submodule to precompile
dyladan Dec 28, 2021
64312d3
chore: convert proto to protobufjs
dyladan Dec 29, 2021
27133e2
Merge remote-tracking branch 'origin/main' into generated-proto
dyladan Dec 29, 2021
2fd6f9c
chore(proto): export metrics function
dyladan Dec 29, 2021
76667f0
feat: add client classes for proto services
dyladan Jan 4, 2022
2042b28
Merge remote-tracking branch 'origin/main' into generated-proto
dyladan Jan 5, 2022
7efc596
Merge remote-tracking branch 'origin/main' into generated-proto
dyladan Jan 14, 2022
95c82e6
docs(proto): add readme to proto package
dyladan Jan 14, 2022
39b5868
chore: revert use of draft proto package in exporter
dyladan Jan 25, 2022
7c34f85
Merge remote-tracking branch 'origin/main' into generated-proto
dyladan Jan 25, 2022
fce9183
deps(proto): add mkdirp for platform-agnostic builds
dyladan Jan 25, 2022
ba0bb72
chore: lint
dyladan Jan 25, 2022
4bff0c1
Rename opentelemetry-proto to proto
dyladan Jan 25, 2022
d470e19
chore(proto): esm builds
dyladan Jan 25, 2022
1b02224
chore: fix proto submodule
dyladan Jan 25, 2022
7f4d14b
chore: fix compilation
dyladan Jan 25, 2022
0a6f13c
test(proto): test in browser
dyladan Jan 25, 2022
165e0c3
deps(proto): clean up dependencies
dyladan Jan 25, 2022
1e76d3a
Merge remote-tracking branch 'origin/main' into generated-proto
dyladan Jan 28, 2022
9598df7
chore: remove errant ms conversion
dyladan Jan 28, 2022
0305016
feat(proto): kvlistvalue conversion in anyValue
dyladan Jan 28, 2022
7bb1804
chore(proto): indent with 2 spaces
dyladan Jan 28, 2022
834bd62
docs(proto): add missing readme link
dyladan Jan 28, 2022
f254fc1
fix(proto): use hex for span and trace ids
dyladan Jan 28, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
[submodule "experimental/packages/opentelemetry-exporter-metrics-otlp-proto/protos"]
path = experimental/packages/opentelemetry-exporter-metrics-otlp-proto/protos
url = https://github.com/open-telemetry/opentelemetry-proto.git
[submodule "experimental/packages/opentelemetry-proto/opentelemetry-proto"]
path = experimental/packages/opentelemetry-proto/opentelemetry-proto
url = https://github.com/open-telemetry/opentelemetry-proto.git
2 changes: 2 additions & 0 deletions experimental/packages/opentelemetry-proto/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build
src/opentelemetry
8 changes: 8 additions & 0 deletions experimental/packages/opentelemetry-proto/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
"env": {
"mocha": true,
"commonjs": true,
"shared-node-browser": true
},
...require('../../../eslint.config.js')
}
1 change: 1 addition & 0 deletions experimental/packages/opentelemetry-proto/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/opentelemetry
19 changes: 19 additions & 0 deletions experimental/packages/opentelemetry-proto/compile_proto.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash

OUT_DIR="../src"
TS_OUT_DIR="../src"
IN_DIR="./opentelemetry"
PROTOC="$(npm bin)/grpc_tools_node_protoc"
PROTOC_GEN_TS_PATH="$(npm bin)/protoc-gen-ts"
PROTOC_GEN_GRPC_PATH="$(npm bin)/grpc_tools_node_protoc_plugin"

cd opentelemetry-proto

$PROTOC \
-I="./" \
--plugin=protoc-gen-ts=$PROTOC_GEN_TS_PATH \
--js_out=import_style=commonjs:$OUT_DIR \
--ts_out=$TS_OUT_DIR \
opentelemetry/proto/collector/logs/v1/logs_service.proto \
opentelemetry/proto/collector/metrics/v1/metrics_service.proto \
opentelemetry/proto/collector/trace/v1/trace_service.proto
Submodule opentelemetry-proto added at 7d4cbe
72 changes: 72 additions & 0 deletions experimental/packages/opentelemetry-proto/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"name": "@opentelemetry/proto",
"private": true,
"version": "0.27.0",
"description": "OpenTelemetry Collector Metrics Exporter allows user to send collected metrics to the OpenTelemetry Collector",
dyladan marked this conversation as resolved.
Show resolved Hide resolved
"main": "build/src/index.js",
"types": "build/src/index.d.ts",
"repository": "open-telemetry/opentelemetry-js",
"scripts": {
"compile": "tsc --build",
"generate": "./compile_proto.sh",
dyladan marked this conversation as resolved.
Show resolved Hide resolved
"clean": "tsc --build --clean && rimraf src/opentelemetry",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
"postcompile": "npm run submodule && npm run protos:copy",
"protos:copy": "cpx protos/opentelemetry/**/*.* build/protos/opentelemetry",
"submodule": "git submodule sync --recursive && git submodule update --init --recursive",
"tdd": "npm run test -- --watch-extensions ts --watch",
"test": "nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'",
"watch": "npm run protos:copy && tsc -w",
"precompile": "npm run generate",
"prewatch": "npm run precompile"
},
"keywords": [
"opentelemetry",
"nodejs",
"grpc",
"tracing",
"profiling",
"metrics",
"stats"
],
"author": "OpenTelemetry Authors",
"license": "Apache-2.0",
"engines": {
"node": ">=8.0.0"
},
"files": [
"build/src/**/*.js",
"build/src/**/*.js.map",
"build/src/**/*.d.ts",
"build/protos/**/*.proto",
"doc",
"LICENSE",
"README.md"
],
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"@opentelemetry/api": "^1.0.3"
},
"devDependencies": {
"@babel/core": "7.16.0",
"@types/google-protobuf": "3.15.5",
"@types/mocha": "8.2.3",
"grpc-tools": "1.11.2",
"mocha": "7.2.0",
"protoc-gen-ts": "0.8.1",
"rimraf": "3.0.2",
"typescript": "4.4.4"
},
"dependencies": {
"@opentelemetry/api-metrics": "0.27.0",
"@opentelemetry/core": "1.0.1",
"@opentelemetry/resources": "1.0.1",
"@opentelemetry/sdk-metrics-base": "0.27.0",
"@opentelemetry/sdk-trace-base": "1.0.1",
"@grpc/grpc-js": "1.4.5",
"google-protobuf": "3.19.1"
}
}
53 changes: 53 additions & 0 deletions experimental/packages/opentelemetry-proto/src/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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.
*/
import { SpanAttributes } from '@opentelemetry/api';
import { opentelemetry as common } from './opentelemetry/proto/common/v1/common';

const MAX_INTEGER_VALUE = 2147483647;
const MIN_INTEGER_VALUE = -2147483648;

export function toAttributes(
attributes: SpanAttributes
): common.proto.common.v1.KeyValue[] {
return Object.keys(attributes).map(key => toKeyValue(key, attributes[key]));
}

export function toKeyValue(
key: string,
value: unknown
): common.proto.common.v1.KeyValue {
return common.proto.common.v1.KeyValue.fromObject({
key: key,
value: toAnyValue(value),
})
}

export function toAnyValue(value: unknown): common.proto.common.v1.AnyValue {
return common.proto.common.v1.AnyValue.fromObject({
string_value: typeof value === 'string' ? value : undefined,
double_value: typeof value === 'number' && Number.isInteger(value) ? value : undefined,
int_value:
typeof value === 'number' &&
!Number.isInteger(value) &&
value > MIN_INTEGER_VALUE &&
value < MAX_INTEGER_VALUE
? value
: undefined,
bool_value: typeof value === 'boolean' ? value : undefined,
bytes_value: value instanceof Buffer ? value : undefined,
array_value: Array.isArray(value) ? { values: value.map(v => toAnyValue(v)) } : undefined,
})
}
16 changes: 16 additions & 0 deletions experimental/packages/opentelemetry-proto/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* 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 * from './trace';
135 changes: 135 additions & 0 deletions experimental/packages/opentelemetry-proto/src/metrics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* 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.
*/
import { ValueType } from '@opentelemetry/api-metrics';
import { hrTimeToNanoseconds } from '@opentelemetry/core';
import { AggregatorKind, MetricKind, MetricRecord, Point, Histogram } from '@opentelemetry/sdk-metrics-base';
import { toAttributes } from './common';
import { opentelemetry as metrics_service } from './opentelemetry/proto/collector/metrics/v1/metrics_service';
import { opentelemetry as metrics } from './opentelemetry/proto/metrics/v1/metrics';

export function createExportMetricsServiceRequest(metricRecords: MetricRecord[], startTime: number): metrics_service.proto.collector.metrics.v1.ExportMetricsServiceRequest | null {
if (metricRecords.length === 0) {
return null;
}

const resource = metricRecords[0].resource;

return metrics_service.proto.collector.metrics.v1.ExportMetricsServiceRequest.fromObject({
resource_metrics: [{
resource: {
attributes: toAttributes(resource.attributes),
dropped_attributes_count: 0,
},
instrumentation_library_metrics: [{
instrumentation_library: { name: metricRecords[0].instrumentationLibrary.name, version: metricRecords[0].instrumentationLibrary.version },
schema_url: metricRecords[0].instrumentationLibrary.schemaUrl,
metrics: metricRecords.map(m => toMetric(m, startTime)),
}],
}],
});
}

function toMetric(metric: MetricRecord, startTime: number): metrics.proto.metrics.v1.Metric {
return metrics.proto.metrics.v1.Metric.fromObject({
description: metric.descriptor.description,
name: metric.descriptor.name,
unit: metric.descriptor.unit,
sum: isSum(metric) ? toSum(metric, startTime) : undefined,
gauge: metric.aggregator.kind === AggregatorKind.LAST_VALUE ? toGauge(metric, startTime) : undefined,
histogram: metric.aggregator.kind === AggregatorKind.HISTOGRAM ? toHistogram(metric, startTime) : undefined,
});
}

function isSum(metric: MetricRecord) {
return metric.aggregator.kind === AggregatorKind.SUM ||
metric.descriptor.metricKind === MetricKind.OBSERVABLE_COUNTER ||
metric.descriptor.metricKind === MetricKind.OBSERVABLE_UP_DOWN_COUNTER;
}

function toAggregationTemporality(
metric: MetricRecord
): metrics.proto.metrics.v1.AggregationTemporality {
if (metric.descriptor.metricKind === MetricKind.OBSERVABLE_GAUGE) {
return metrics.proto.metrics.v1.AggregationTemporality.AGGREGATION_TEMPORALITY_UNSPECIFIED;
}

return metric.aggregationTemporality;
}

function toSum(
metric: MetricRecord,
startTime: number
): metrics.proto.metrics.v1.Sum {
return metrics.proto.metrics.v1.Sum.fromObject({
data_points: [toNumberDataPoint(metric, startTime)],
is_monotonic:
metric.descriptor.metricKind === MetricKind.COUNTER ||
metric.descriptor.metricKind === MetricKind.OBSERVABLE_COUNTER,
aggregation_temporality: toAggregationTemporality(metric),
})
}

function toGauge(
metric: MetricRecord,
startTime: number
): metrics.proto.metrics.v1.Gauge {
return metrics.proto.metrics.v1.Gauge.fromObject({
data_points: [toNumberDataPoint(metric, startTime)],
})
}

function toHistogram(
metric: MetricRecord,
startTime: number
): metrics.proto.metrics.v1.Histogram {
return metrics.proto.metrics.v1.Histogram.fromObject({
data_points: [toHistogramDataPoint(metric, startTime)],
aggregation_temporality: toAggregationTemporality(metric),
});
}

function toNumberDataPoint(
metric: MetricRecord,
startTime: number
): metrics.proto.metrics.v1.NumberDataPoint {
return metrics.proto.metrics.v1.NumberDataPoint.fromObject({
attributes: toAttributes(metric.attributes),
as_int: metric.descriptor.valueType === ValueType.INT ? metric.aggregator.toPoint().value as number : undefined,
as_double: metric.descriptor.valueType === ValueType.DOUBLE ? metric.aggregator.toPoint().value as number : undefined,
start_time_unix_nano: startTime,
time_unix_nano: hrTimeToNanoseconds(
metric.aggregator.toPoint().timestamp
),
});
}

function toHistogramDataPoint(
metric: MetricRecord,
startTime: number
): metrics.proto.metrics.v1.HistogramDataPoint {
const point = metric.aggregator.toPoint() as Point<Histogram>
return metrics.proto.metrics.v1.HistogramDataPoint.fromObject({
attributes: toAttributes(metric.attributes),
bucket_counts: point.value.buckets.counts,
explicit_bounds: point.value.buckets.boundaries,
count: point.value.count,
sum: point.value.sum,
start_time_unix_nano: startTime,
time_unix_nano: hrTimeToNanoseconds(
metric.aggregator.toPoint().timestamp
),
})
}
Loading