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(otlp-grpc-exporter-base): use statically generated protobuf code #3705

Merged
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7bfd12a
feat(otlp-grpc-exporter-base): use generated protos
pichlermarc Mar 8, 2023
e5ce22e
feat(otlp-grpc-exporter-otlp): remove submodule step from postcompile
pichlermarc Mar 29, 2023
ac133ad
feat(otlp-grpc-exporter-otlp): address protos concurrency problem
pichlermarc Mar 29, 2023
a9c22ce
feat(otlp-grpc-exporter-otlp): undo re-ordering of scripts in package…
pichlermarc Mar 29, 2023
56ca2d3
fix(changlog): add changelog entry
pichlermarc Mar 29, 2023
0923df9
feat(otlp-grpc-exporter-otlp): move proto code generation script
pichlermarc Mar 29, 2023
2ed678f
feat(otlp-grpc-exporter-otlp): delete copied proto script
pichlermarc Mar 29, 2023
1f760dd
feat(otlp-grpc-exporter-otlp): remove unused client path from tsconfi…
pichlermarc Mar 29, 2023
ec3ccd0
feat(otlp-grpc-exporter-otlp): clean up
pichlermarc Mar 29, 2023
c6d01dd
feat(otlp-grpc-exporter-otlp): clean up
pichlermarc Mar 29, 2023
f285019
Merge branch 'main' into use-generated-grpc
pichlermarc Mar 30, 2023
1f14ad2
feat(otlp-exporter-grpc-base): fix up package.json
pichlermarc Mar 30, 2023
9bc203c
Merge branch 'main' into use-generated-grpc
pichlermarc Mar 31, 2023
c5bc39a
feat(otlp-exporter-grpc-base): remove protos from package
pichlermarc Mar 31, 2023
84c39d4
feat(otlp-exporter-grpc-base): collapse serialization into one line
pichlermarc Mar 31, 2023
3fd3e51
feat(otlp-exporter-grpc-base): rename ExportRequestType to ExportType
pichlermarc Mar 31, 2023
fbd2d28
feat(otlp-exporter-grpc-base): use type import for protobufjs
pichlermarc Mar 31, 2023
d62daab
feat(otlp-exporter-grpc-base): remove proto-loader dependency
pichlermarc Apr 3, 2023
5e702fc
Merge branch 'main' into use-generated-grpc
pichlermarc Apr 3, 2023
09ad75f
Merge branch 'main' into use-generated-grpc
pichlermarc Apr 4, 2023
ccad4b5
Merge branch 'main' into use-generated-grpc
dyladan Apr 7, 2023
073b01a
feat(otlp-exporter-grpc-base): only run submodule once in top-level c…
pichlermarc Apr 11, 2023
9891f60
Merge branch 'main' into use-generated-grpc
pichlermarc Apr 26, 2023
cd8dbfe
feat(otlp-grpc-exporter-base): add logs client
pichlermarc Apr 26, 2023
eb3bb5b
Merge branch 'main' into use-generated-grpc
pichlermarc Apr 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ All notable changes to experimental packages in this project will be documented

### :rocket: (Enhancement)

* feat(otlp-grpc-exporter-base): use statically generated protobuf code [#3705](https://github.com/open-telemetry/opentelemetry-js/pull/3705) @pichlermarc

### :bug: (Bug Fix)

* fix(sdk-node): only set DiagConsoleLogger when OTEL_LOG_LEVEL is set [#3693](https://github.com/open-telemetry/opentelemetry-js/pull/3672) @pichlermarc
Expand Down
2 changes: 2 additions & 0 deletions experimental/packages/otlp-grpc-exporter-base/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
src/generated/*
!src/generated/.gitkeep
14 changes: 7 additions & 7 deletions experimental/packages/otlp-grpc-exporter-base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@
"scripts": {
"prepublishOnly": "npm run compile",
"codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../../",
"compile": "tsc --build",
"compile": "npm run protos && tsc --build",
"clean": "tsc --build --clean",
"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",
"protos": "npm run submodule && node ../../../scripts/generate-protos.js",
"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'",
"version": "node ../../../scripts/version-update.js",
"watch": "npm run protos:copy && tsc -w",
"watch": "npm run protos && tsc -w",
"precompile": "lerna run version --scope $(npm pkg get name) --include-dependencies",
"prewatch": "npm run precompile"
},
Expand All @@ -40,7 +39,6 @@
"build/src/**/*.js",
"build/src/**/*.js.map",
"build/src/**/*.d.ts",
"build/protos/**/*.proto",
"doc",
"LICENSE",
"README.md"
Expand All @@ -65,7 +63,8 @@
"sinon": "15.0.0",
"ts-loader": "8.4.0",
"ts-mocha": "10.0.0",
"typescript": "4.4.4"
"typescript": "4.4.4",
"protobufjs-cli": "1.0.2"
},
"peerDependencies": {
"@opentelemetry/api": "^1.0.0"
Expand All @@ -74,7 +73,8 @@
"@grpc/grpc-js": "^1.7.1",
"@grpc/proto-loader": "^0.7.3",
pichlermarc marked this conversation as resolved.
Show resolved Hide resolved
"@opentelemetry/core": "1.11.0",
"@opentelemetry/otlp-exporter-base": "0.37.0"
"@opentelemetry/otlp-exporter-base": "0.37.0",
"protobufjs": "^7.2.2"
dyladan marked this conversation as resolved.
Show resolved Hide resolved
},
"homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-grpc-exporter-base",
"sideEffects": false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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 * as root from './generated/root';
import * as grpc from '@grpc/grpc-js';
import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer';
import { ExportType } from './internal-types';
import IExportMetricsServiceResponse = root.opentelemetry.proto.collector.metrics.v1.IExportMetricsServiceResponse;

const responseType = root.opentelemetry.proto.collector.metrics.v1
dyladan marked this conversation as resolved.
Show resolved Hide resolved
.ExportMetricsServiceResponse as ExportType<IExportMetricsServiceResponse>;

const requestType = root.opentelemetry.proto.collector.metrics.v1
.ExportMetricsServiceRequest as ExportType<IExportMetricsServiceRequest>;

const metricsServiceDefinition = {
export: {
path: '/opentelemetry.proto.collector.metrics.v1.MetricsService/Export',
requestStream: false,
responseStream: false,
requestSerialize: (arg: IExportMetricsServiceRequest) => {
return Buffer.from(requestType.encode(arg).finish());
},
requestDeserialize: (arg: Buffer) => {
return requestType.decode(arg);
},
responseSerialize: (arg: IExportMetricsServiceResponse) => {
return Buffer.from(responseType.encode(arg).finish());
},
responseDeserialize: (arg: Buffer) => {
return responseType.decode(arg);
},
},
};

// Creates a new instance of a gRPC service client for OTLP metrics
export const MetricExportServiceClient: grpc.ServiceClientConstructor =
grpc.makeGenericClientConstructor(
metricsServiceDefinition,
'MetricsExportService'
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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 * as root from './generated/root';
import * as grpc from '@grpc/grpc-js';
import { IExportTraceServiceRequest } from '@opentelemetry/otlp-transformer';
import { ExportType } from './internal-types';
import IExportTraceServiceResponse = root.opentelemetry.proto.collector.trace.v1.IExportTraceServiceResponse;

const responseType = root.opentelemetry.proto.collector.trace.v1
.ExportTraceServiceResponse as ExportType<IExportTraceServiceResponse>;

const requestType = root.opentelemetry.proto.collector.trace.v1
.ExportTraceServiceRequest as ExportType<IExportTraceServiceRequest>;

const traceServiceDefinition = {
export: {
path: '/opentelemetry.proto.collector.trace.v1.TraceService/Export',
requestStream: false,
responseStream: false,
requestSerialize: (arg: IExportTraceServiceRequest) => {
return Buffer.from(requestType.encode(arg).finish());
},
requestDeserialize: (arg: Buffer) => {
return requestType.decode(arg);
},
responseSerialize: (arg: IExportTraceServiceResponse) => {
return Buffer.from(responseType.encode(arg).finish());
},
responseDeserialize: (arg: Buffer) => {
return responseType.decode(arg);
},
},
};

// Creates a new instance of a gRPC service client for exporting OTLP traces
export const TraceExportServiceClient: grpc.ServiceClientConstructor =
grpc.makeGenericClientConstructor(
traceServiceDefinition,
'TraceExportService'
);
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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 type * as protobuf from 'protobufjs';

export interface ExportType<T, R = T & { toJSON: () => unknown }> {
encode(message: T, writer?: protobuf.Writer): protobuf.Writer;
decode(reader: protobuf.Reader | Uint8Array, length?: number): R;
}
dyladan marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ export interface GRPCQueueItem<ExportedItem> {
/**
* Service Client for sending spans or metrics
*/
export interface ServiceClient extends grpc.Client {
export interface ServiceClient {
export: (
request: any,
metadata: grpc.Metadata,
options: grpc.CallOptions,
callback: Function
) => {};

close(): void;
}

/**
Expand Down
71 changes: 28 additions & 43 deletions experimental/packages/otlp-grpc-exporter-base/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/

import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import { diag } from '@opentelemetry/api';
import { getEnv, globalErrorHandler } from '@opentelemetry/core';
import * as path from 'path';
Expand All @@ -28,11 +27,14 @@ import {
ServiceClientType,
} from './types';
import {
CompressionAlgorithm,
ExportServiceError,
OTLPExporterError,
CompressionAlgorithm,
} from '@opentelemetry/otlp-exporter-base';

import { MetricExportServiceClient } from './MetricsExportServiceClient';
import { TraceExportServiceClient } from './TraceExportServiceClient';

export const DEFAULT_COLLECTOR_URL = 'http://localhost:4317';

export function onInit<ExportItem, ServiceRequest>(
Expand All @@ -46,50 +48,33 @@ export function onInit<ExportItem, ServiceRequest>(
collector.getUrlFromConfig(config)
);

const includeDirs = [path.resolve(__dirname, '..', 'protos')];

protoLoader
.load(collector.getServiceProtoPath(), {
keepCase: false,
longs: String,
enums: String,
defaults: true,
oneofs: true,
includeDirs,
})
.then(packageDefinition => {
const packageObject: any = grpc.loadPackageDefinition(packageDefinition);

const options = {
'grpc.default_compression_algorithm': collector.compression,
};
try {
if (collector.getServiceClientType() === ServiceClientType.SPANS) {
const client = new TraceExportServiceClient(collector.url, credentials, {
'grpc.default_compression_algorithm': collector.compression.valueOf(),
});

if (collector.getServiceClientType() === ServiceClientType.SPANS) {
collector.serviceClient =
new packageObject.opentelemetry.proto.collector.trace.v1.TraceService(
collector.url,
credentials,
options
);
} else {
collector.serviceClient =
new packageObject.opentelemetry.proto.collector.metrics.v1.MetricsService(
collector.url,
credentials,
options
);
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
collector.serviceClient = client;
} else if (collector.getServiceClientType() === ServiceClientType.METRICS) {
const client = new MetricExportServiceClient(collector.url, credentials, {
'grpc.default_compression_algorithm': collector.compression.valueOf(),
});

if (collector.grpcQueue.length > 0) {
const queue = collector.grpcQueue.splice(0);
queue.forEach((item: GRPCQueueItem<ExportItem>) => {
collector.send(item.objects, item.onSuccess, item.onError);
});
}
})
.catch(err => {
globalErrorHandler(err);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
collector.serviceClient = client;
}
} catch (err) {
globalErrorHandler(err);
}
if (collector.grpcQueue.length > 0) {
const queue = collector.grpcQueue.splice(0);
queue.forEach((item: GRPCQueueItem<ExportItem>) => {
collector.send(item.objects, item.onSuccess, item.onError);
});
}
}

export function send<ExportItem, ServiceRequest>(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"outDir": "build",
"rootDir": "."
},
"include": [
"src/**/*.ts",
"src/generated/*.js",
"src/generated/**/*.js",
"src/generated/**/*.ts",
"test/**/*.ts"
],
"references": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"clean": "tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
"protos": "npm run submodule && node scripts/protos.js",
"protos": "npm run submodule && node ../../../scripts/generate-protos.js",
"submodule": "git submodule sync --recursive && git submodule update --init --recursive",
"version": "node ../../../scripts/version-update.js",
"watch": "npm run protos && tsc -w tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@
"description": "OpenTelemetry is a distributed tracing and stats collection framework.",
"scripts": {
"precompile": "lerna run version",
"compile": "lerna run protos && tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
"compile": "lerna run protos --concurrency=1 && tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
pichlermarc marked this conversation as resolved.
Show resolved Hide resolved
"prewatch": "npm run precompile",
"watch": "tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
"clean": "tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
"postinstall": "npm run update-ts-configs && npm run bootstrap",
"postcompile": "npm run submodule && npm run protos:copy",
"submodule": "git submodule sync --recursive && git submodule update --init --recursive",
"protos:copy": "lerna run protos:copy",
"version:update": "lerna run version:update",
"test": "lerna run test",
"test:browser": "lerna run test:browser",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
const cp = require('child_process');
const path = require('path');

const generatedPath = path.resolve(__dirname, '../src/generated');
const protosPath = path.resolve(__dirname, '../protos');
const appRoot = process.cwd();

const generatedPath = path.resolve(appRoot, './src/generated');
const protosPath = path.resolve(appRoot, './protos');
const protos = [
'opentelemetry/proto/common/v1/common.proto',
'opentelemetry/proto/resource/v1/resource.proto',
Expand Down Expand Up @@ -33,15 +35,15 @@ function exec(command, argv) {
}

function pbts(pbjsOutFile) {
const pbtsPath = path.resolve(__dirname, '../node_modules/.bin/pbts');
const pbtsPath = path.resolve(appRoot, './node_modules/.bin/pbts');
const pbtsOptions = [
'-o', path.join(generatedPath, 'root.d.ts'),
];
return exec(pbtsPath, [...pbtsOptions, pbjsOutFile]);
}

async function pbjs(files) {
const pbjsPath = path.resolve(__dirname, '../node_modules/.bin/pbjs');
const pbjsPath = path.resolve(appRoot, './node_modules/.bin/pbjs');
const outFile = path.join(generatedPath, 'root.js');
const pbjsOptions = [
'-t', 'static-module',
Expand Down