Skip to content

Commit

Permalink
Proto update to latest to support arrays and maps (open-telemetry#1339)
Browse files Browse the repository at this point in the history
  • Loading branch information
obecny authored and jonahrosenblum committed Aug 6, 2020
1 parent b956e9c commit ab0de32
Show file tree
Hide file tree
Showing 23 changed files with 576 additions and 167 deletions.
14 changes: 7 additions & 7 deletions examples/collector-exporter-node/docker/collector-config.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
receivers:
otlp:
{}
# keep it when upgrading to version 0.5+
# protocols:
# grpc:
# http:
# endpoint: localhost:55680
protocols:
grpc:
http:
cors_allowed_origins:
- http://*
- https://*

exporters:
zipkin:
url: "http://zipkin-all-in-one:9411/api/v2/spans"
endpoint: "http://zipkin-all-in-one:9411/api/v2/spans"

processors:
batch:
Expand Down
11 changes: 10 additions & 1 deletion examples/collector-exporter-node/docker/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@ version: "3"
services:
# Collector
collector:
image: otel/opentelemetry-collector:0.4.0
image: otel/opentelemetry-collector:latest
# image: otel/opentelemetry-collector:0.6.0
command: ["--config=/conf/collector-config.yaml", "--log-level=DEBUG"]
networks:
- otelcol
volumes:
- ./collector-config.yaml:/conf/collector-config.yaml
ports:
- "55680:55680"
- "55681:55681"
depends_on:
- zipkin-all-in-one

# Zipkin
zipkin-all-in-one:
image: openzipkin/zipkin:latest
networks:
- otelcol
ports:
- "9411:9411"

networks:
otelcol:
10 changes: 10 additions & 0 deletions examples/collector-exporter-node/start.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
'use strict';

const opentelemetry = require('@opentelemetry/api');
// const { ConsoleLogger, LogLevel} = require('@opentelemetry/core');
const { BasicTracerProvider, ConsoleSpanExporter, SimpleSpanProcessor } = require('@opentelemetry/tracing');
const { CollectorTraceExporter, CollectorProtocolNode } = require('@opentelemetry/exporter-collector');

const exporter = new CollectorTraceExporter({
serviceName: 'basic-service',
// logger: new ConsoleLogger(LogLevel.DEBUG),
// headers: {
// foo: 'bar'
// },
Expand Down Expand Up @@ -48,6 +50,14 @@ function doWork(parent) {
// Set attributes to the span.
span.setAttribute('key', 'value');

span.setAttribute('mapAndArrayValue', [
0, 1, 2.25, 'otel', {
foo: 'bar',
baz: 'json',
array: [1, 2, 'boom'],
},
]);

// Annotate our span to capture metadata about our operation
span.addEvent('invoking doWork');

Expand Down
2 changes: 1 addition & 1 deletion examples/tracer-web/examples/user-interaction/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const providerWithZone = new WebTracerProvider({
plugins: [
new UserInteractionPlugin(),
new XMLHttpRequestPlugin({
ignoreUrls: [/localhost:8090\/sockjs-node/],
ignoreUrls: [/localhost/],
propagateTraceHeaderCorsUrls: [
'http://localhost:8090'
]
Expand Down
29 changes: 26 additions & 3 deletions packages/opentelemetry-exporter-collector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { WebTracerProvider } from '@opentelemetry/web';
import { CollectorTraceExporter } from '@opentelemetry/exporter-collector';

const collectorOptions = {
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is http://localhost:55680/v1/trace
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is http://localhost:55681/v1/trace
headers: {}, //an optional object containing custom headers to be sent with each request
};

Expand Down Expand Up @@ -118,10 +118,33 @@ const { CollectorExporter, CollectorTransportNode } = require('@opentelemetry/e
const collectorOptions = {
protocolNode: CollectorTransportNode.HTTP_JSON,
serviceName: 'basic-service',
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is http://localhost:55680/v1/trace
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is http://localhost:55681/v1/trace
headers: {
foo: 'bar'
}, //an optional object containing custom headers to be sent with each request will only work with json over http
}, //an optional object containing custom headers to be sent with each request will only work with http
};

const provider = new BasicTracerProvider();
const exporter = new CollectorExporter(collectorOptions);
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));

provider.register();

```

## Usage in Node - PROTO over http

```js
const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/tracing');
const { CollectorExporter, CollectorTransportNode } = require('@opentelemetry/exporter-collector');

const collectorOptions = {
protocolNode: CollectorTransportNode.HTTP_PROTO,
serviceName: 'basic-service',
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is http://localhost:55681/v1/trace
headers: {
foo: 'bar'
}, //an optional object containing custom headers to be sent with each request will only work with http
};

const provider = new BasicTracerProvider();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { sendWithBeacon, sendWithXhr } from './util';
import { parseHeaders } from '../../util';

const DEFAULT_SERVICE_NAME = 'collector-trace-exporter';
const DEFAULT_COLLECTOR_URL = 'http://localhost:55680/v1/trace';
const DEFAULT_COLLECTOR_URL = 'http://localhost:55681/v1/trace';

/**
* Collector Trace Exporter for Web
Expand All @@ -35,9 +35,6 @@ export class CollectorTraceExporter
collectorTypes.opentelemetryProto.collector.trace.v1.ExportTraceServiceRequest
>
implements SpanExporter {
DEFAULT_HEADERS: Record<string, string> = {
[collectorTypes.OT_REQUEST_HEADER]: '1',
};
private _headers: Record<string, string>;
private _useXHR: boolean = false;

Expand All @@ -46,10 +43,13 @@ export class CollectorTraceExporter
*/
constructor(config: CollectorExporterConfigBrowser = {}) {
super(config);
this._headers =
parseHeaders(config.headers, this.logger) || this.DEFAULT_HEADERS;
this._useXHR =
!!config.headers || typeof navigator.sendBeacon !== 'function';
if (this._useXHR) {
this._headers = parseHeaders(config.headers, this.logger);
} else {
this._headers = {};
}
}

onInit(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { toCollectorExportMetricServiceRequest } from '../../transformMetrics';

const DEFAULT_SERVICE_NAME = 'collector-metric-exporter';
const DEFAULT_COLLECTOR_URL_GRPC = 'localhost:55680';
const DEFAULT_COLLECTOR_URL_JSON = 'http://localhost:55680/v1/metrics';
const DEFAULT_COLLECTOR_URL_JSON = 'http://localhost:55681/v1/metrics';

/**
* Collector Metric Exporter for Node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import { toCollectorExportTraceServiceRequest } from '../../transform';

const DEFAULT_SERVICE_NAME = 'collector-trace-exporter';
const DEFAULT_COLLECTOR_URL_GRPC = 'localhost:55680';
const DEFAULT_COLLECTOR_URL_JSON = 'http://localhost:55680/v1/trace';
const DEFAULT_COLLECTOR_URL_JSON_PROTO = 'http://localhost:55680/v1/trace';
const DEFAULT_COLLECTOR_URL_JSON = 'http://localhost:55681/v1/trace';
const DEFAULT_COLLECTOR_URL_JSON_PROTO = 'http://localhost:55681/v1/trace';

/**
* Collector Trace Exporter for Node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function removeProtocol(url: string): string {
* @param onSuccess
* @param onError
*/
export function sendDataUsingHttp<ExportItem, ServiceRequest>(
export function sendWithHttp<ExportItem, ServiceRequest>(
collector: CollectorExporterNodeBase<ExportItem, ServiceRequest>,
data: string | Buffer,
contentType: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import * as collectorTypes from '../../types';
import { CollectorExporterNodeBase } from './CollectorExporterNodeBase';
import { CollectorExporterConfigNode } from './types';
import { sendDataUsingHttp } from './util';
import { sendWithHttp } from './util';

export function initWithJson<ExportItem, ServiceRequest>(
_collector: CollectorExporterNodeBase<ExportItem, ServiceRequest>,
Expand All @@ -34,7 +34,7 @@ export function sendWithJson<ExportItem, ServiceRequest>(
): void {
const serviceRequest = collector.convert(objects);

sendDataUsingHttp(
sendWithHttp(
collector,
JSON.stringify(serviceRequest),
'application/json',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import * as protobufjs from 'protobufjs';
import * as collectorTypes from '../../types';
import { CollectorExporterNodeBase } from './CollectorExporterNodeBase';
import { CollectorExporterConfigNode } from './types';
import { sendDataUsingHttp } from './util';
import { sendWithHttp } from './util';

let ExportTraceServiceRequestProto: Type | undefined;

Expand Down Expand Up @@ -60,7 +60,7 @@ export function sendWithJsonProto<ExportItem, ServiceRequest>(
if (message) {
const body = ExportTraceServiceRequestProto?.encode(message).finish();
if (body) {
sendDataUsingHttp(
sendWithHttp(
collector,
Buffer.from(body),
'application/x-protobuf',
Expand Down
66 changes: 49 additions & 17 deletions packages/opentelemetry-exporter-collector/src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,47 +30,79 @@ import {
opentelemetryProto,
CollectorExporterConfigBase,
} from './types';
import ValueType = opentelemetryProto.common.v1.ValueType;

/**
* Converts attributes
* Converts attributes to KeyValue array
* @param attributes
*/
export function toCollectorAttributes(
attributes: Attributes
): opentelemetryProto.common.v1.AttributeKeyValue[] {
): opentelemetryProto.common.v1.KeyValue[] {
return Object.keys(attributes).map(key => {
return toCollectorAttributeKeyValue(key, attributes[key]);
});
}

/**
* Converts key and value to AttributeKeyValue
* Converts array of unknown value to ArrayValue
* @param values
*/
export function toCollectorArrayValue(
values: unknown[]
): opentelemetryProto.common.v1.ArrayValue {
return {
values: values.map(value => toCollectorAnyValue(value)),
};
}

/**
* Converts attributes to KeyValueList
* @param attributes
*/
export function toCollectorKeyValueList(
attributes: Attributes
): opentelemetryProto.common.v1.KeyValueList {
return {
values: toCollectorAttributes(attributes),
};
}

/**
* Converts key and unknown value to KeyValue
* @param value event value
*/
export function toCollectorAttributeKeyValue(
key: string,
value: unknown
): opentelemetryProto.common.v1.AttributeKeyValue {
let aType: opentelemetryProto.common.v1.ValueType = ValueType.STRING;
const AttributeKeyValue: opentelemetryProto.common.v1.AttributeKeyValue = {
): opentelemetryProto.common.v1.KeyValue {
const anyValue = toCollectorAnyValue(value);
return {
key,
type: 0,
value: anyValue,
};
}

/**
* Converts unknown value to AnyValue
* @param value
*/
export function toCollectorAnyValue(
value: unknown
): opentelemetryProto.common.v1.AnyValue {
const anyValue: opentelemetryProto.common.v1.AnyValue = {};
if (typeof value === 'string') {
AttributeKeyValue.stringValue = value;
anyValue.stringValue = value;
} else if (typeof value === 'boolean') {
aType = ValueType.BOOL;
AttributeKeyValue.boolValue = value;
anyValue.boolValue = value;
} else if (typeof value === 'number') {
// all numbers will be treated as double
aType = ValueType.DOUBLE;
AttributeKeyValue.doubleValue = value;
anyValue.doubleValue = value;
} else if (Array.isArray(value)) {
anyValue.arrayValue = toCollectorArrayValue(value);
} else if (value) {
anyValue.kvlistValue = toCollectorKeyValueList(value as Attributes);
}

AttributeKeyValue.type = aType;

return AttributeKeyValue;
return anyValue;
}

/**
Expand Down
Loading

0 comments on commit ab0de32

Please sign in to comment.