Skip to content

Commit

Permalink
Collector exporter (#552)
Browse files Browse the repository at this point in the history
* chore: linting

* feat(collector-exporter): new exporter for opentelemetry collector

* chore: updating readme

* chore: undo auto lint fix - which is wrong

* chore: updates after comments

* chore: renaming util to transform

* chore: renaming types, last comments from review

* chore: adding missing links

* chore: fixes after comments

* chore: fixes after comments

* chore: fixes after comments

* chore: updating jsdoc

* chore: enabling attributes

* chore: adding script to generate package version file

* chore: naming

* chore: adding todo

* chore: updating types for link

* chore: fixing typo

* chore: removing unnecessary typing

* chore: const for enum

* chore: adding missing interface for message event

* chore: adding timestamp example

* chore: changes after review

* chore: adding case when the exporter is shutdown but export is called

* chore: adding missing header for request to prevent instrumentation
  • Loading branch information
obecny authored and mayurkale22 committed Dec 4, 2019
1 parent c14d122 commit b58ad10
Show file tree
Hide file tree
Showing 45 changed files with 2,878 additions and 14 deletions.
24 changes: 24 additions & 0 deletions examples/basic-tracer-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ $ npm install
Setup [Zipkin Tracing](https://zipkin.io/pages/quickstart.html)
or
Setup [Jaeger Tracing](https://www.jaegertracing.io/docs/latest/getting-started/#all-in-one)
or
Setup [Collector Exporter](https://github.com/open-telemetry/opentelemetry-exporter-collector)


## Run the Application

Expand Down Expand Up @@ -57,6 +60,24 @@ Click on the trace to view its details.

<p align="center"><img src="./images/jaeger-ui-detail.png?raw=true"/></p>

### Collector Exporter
You can use the [opentelemetry-collector][opentelemetry-collector-url] docker container.
For that please make sure you have [docker](https://docs.docker.com/) installed
- Run the docker container
```sh
$ # from this directory
$ # open telemetry
$ npm run collector:docker:ot
$ # at any time you can stop it
$ npm run collector:docker:stop
```

#### Collector Exporter - Zipkin UI
The [opentelemetry-collector][opentelemetry-collector-url]
docker container is using [Zipkin Exporter](#zipkin).
You can define more exporters without changing the instrumented code.
To use default [Zipkin Exporter](#zipkin) please follow the section [Zipkin UI](#zipkin-ui) only

### Export to multiple exporters

- Run the sample
Expand All @@ -75,3 +96,6 @@ Click on the trace to view its details.
## LICENSE

Apache License 2.0


[opentelemetry-collector-url]: https://github.com/open-telemetry/opentelemetry-exporter-collector
18 changes: 18 additions & 0 deletions examples/basic-tracer-node/docker/ot/collector-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
receivers:
opencensus:
endpoint: 0.0.0.0:55678

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

processors:
batch:
queued_retry:

service:
pipelines:
traces:
receivers: [opencensus]
exporters: [zipkin]
processors: [batch, queued_retry]
19 changes: 19 additions & 0 deletions examples/basic-tracer-node/docker/ot/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: "2"
services:

# Collector
collector:
image: otelcol:latest
command: ["--config=/conf/collector-config.yaml", "--log-level=DEBUG"]
volumes:
- ./collector-config.yaml:/conf/collector-config.yaml
ports:
- "55678:55678"
depends_on:
- zipkin-all-in-one

# Zipkin
zipkin-all-in-one:
image: openzipkin/zipkin:latest
ports:
- "9411:9411"
7 changes: 5 additions & 2 deletions examples/basic-tracer-node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@ const opentelemetry = require('@opentelemetry/core');
const { BasicTracer, SimpleSpanProcessor } = require('@opentelemetry/tracing');
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
const { CollectorExporter } = require('@opentelemetry/exporter-collector');

const options = {
serviceName: 'basic-service'
}
};

// Initialize an exporter depending on how we were started
let exporter;

const EXPORTER = process.env.EXPORTER || '';
if (EXPORTER.toLowerCase().startsWith('z')) {
exporter = new ZipkinExporter(options);
} else {
} else if (EXPORTER.toLowerCase().startsWith('j')) {
exporter = new JaegerExporter(options);
} else {
exporter = new CollectorExporter(options);
}

const tracer = new BasicTracer();
Expand Down
7 changes: 6 additions & 1 deletion examples/basic-tracer-node/multi_exporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const opentelemetry = require('@opentelemetry/core');
const { BasicTracer, BatchSpanProcessor, SimpleSpanProcessor } = require('@opentelemetry/tracing');
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
const { CollectorExporter } = require('@opentelemetry/exporter-collector');

const tracer = new BasicTracer();

Expand All @@ -10,7 +11,8 @@ const jaegerExporter = new JaegerExporter({
serviceName: 'basic-service',
// The default flush interval is 5 seconds.
flushInterval: 2000
})
});
const collectorExporter = new CollectorExporter({serviceName: 'basic-service'});

// It is recommended to use this BatchSpanProcessor for better performance
// and optimization, especially in production.
Expand All @@ -22,6 +24,8 @@ tracer.addSpanProcessor(new BatchSpanProcessor(zipkinExporter, {
// it's internal client already handles the spans with batching logic.
tracer.addSpanProcessor(new SimpleSpanProcessor(jaegerExporter));

tracer.addSpanProcessor(new SimpleSpanProcessor(collectorExporter));

// Initialize the OpenTelemetry APIs to use the BasicTracer bindings
opentelemetry.initGlobalTracer(tracer);

Expand All @@ -36,6 +40,7 @@ span.end();
// flush and close the connection.
zipkinExporter.shutdown();
jaegerExporter.shutdown();
collectorExporter.shutdown();

function doWork(parent) {
// Start another span. In this example, the main method already started a
Expand Down
4 changes: 4 additions & 0 deletions examples/basic-tracer-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"scripts": {
"zipkin:basic": "cross-env EXPORTER=zipkin node ./index.js",
"jaeger:basic": "cross-env EXPORTER=jaeger node ./index.js",
"collector:basic": "cross-env EXPORTER=collector node ./index.js",
"collector:docker:ot": "cd ./docker/ot && docker-compose down && docker-compose up",
"collector:docker:stop": "cd ./docker/ot && docker-compose down",
"multi_exporter": "node ./multi_exporter.js"
},
"repository": {
Expand All @@ -28,6 +31,7 @@
},
"dependencies": {
"@opentelemetry/core": "^0.2.0",
"@opentelemetry/exporter-collector": "^0.2.0",
"@opentelemetry/exporter-jaeger": "^0.2.0",
"@opentelemetry/exporter-zipkin": "^0.2.0",
"@opentelemetry/tracing": "^0.2.0"
Expand Down
2 changes: 1 addition & 1 deletion examples/tracer-web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</head>

<body>
Example of using Web Tracer with document load plugin and console exporter
Example of using Web Tracer with document load plugin with console exporter and collector exporter
<script type="text/javascript" src="/bundle.js"></script>
<br/>
<button id="button1">Test WebTracer with ZoneScopeManager - async</button>
Expand Down
2 changes: 2 additions & 0 deletions examples/tracer-web/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/tracing
import { WebTracer } from '@opentelemetry/web';
import { DocumentLoad } from '@opentelemetry/plugin-document-load';
import { ZoneScopeManager } from '@opentelemetry/scope-zone';
import { CollectorExporter } from '@opentelemetry/exporter-collector'

const webTracer = new WebTracer({
plugins: [
Expand All @@ -17,6 +18,7 @@ const webTracerWithZone = new WebTracer({
]
});
webTracerWithZone.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
webTracerWithZone.addSpanProcessor(new SimpleSpanProcessor(new CollectorExporter()));

console.log('Current span is window', webTracerWithZone.getCurrentSpan() === window);

Expand Down
1 change: 1 addition & 0 deletions examples/tracer-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"webpack-merge": "^4.2.2"
},
"dependencies": {
"@opentelemetry/exporter-collector": "^0.2.0",
"@opentelemetry/plugin-document-load": "^0.2.0",
"@opentelemetry/scope-zone": "^0.2.0",
"@opentelemetry/tracing": "^0.2.0",
Expand Down
6 changes: 4 additions & 2 deletions packages/opentelemetry-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
"clean": "rimraf build/*",
"check": "gts check",
"precompile": "tsc --version",
"compile": "tsc -p .",
"compile": "npm run version:update && tsc -p .",
"fix": "gts fix",
"prepare": "npm run compile"
"prepare": "npm run compile",
"version:update": "node scripts/version-update.js",
"watch": "tsc -w"
},
"keywords": [
"opentelemetry",
Expand Down
47 changes: 47 additions & 0 deletions packages/opentelemetry-core/scripts/version-update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*!
* Copyright 2019, 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.
*/

const license =
`/*!
* Copyright 2019, 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.
*/
`;

const fs = require('fs');
const path = require('path');

const appRoot = path.resolve(__dirname);
const fileUrl = path.resolve(`${appRoot}/../src/common/version.ts`);
const packageJsonUrl = path.resolve(`${appRoot}/../package.json`);
const pjson = require(packageJsonUrl);
const content = `
// this is autogenerated file, see scripts/version-update.js
export const VERSION = '${pjson.version}';
`;

fs.writeFileSync(fileUrl, `${license}${content}`);
58 changes: 50 additions & 8 deletions packages/opentelemetry-core/src/common/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ import { TimeOriginLegacy } from './types';
const NANOSECOND_DIGITS = 9;
const SECOND_TO_NANOSECONDS = Math.pow(10, NANOSECOND_DIGITS);

// Converts a number to HrTime
/**
* Converts a number to HrTime
* @param epochMillis
*/
function numberToHrtime(epochMillis: number): types.HrTime {
const epochSeconds = epochMillis / 1000;
// Decimals only.
Expand All @@ -42,7 +45,10 @@ function getTimeOrigin(): number {
return timeOrigin;
}

// Returns an hrtime calculated via performance component.
/**
* Returns an hrtime calculated via performance component.
* @param performanceNow
*/
export function hrTime(performanceNow?: number): types.HrTime {
const timeOrigin = numberToHrtime(getTimeOrigin());
const now = numberToHrtime(
Expand All @@ -61,7 +67,11 @@ export function hrTime(performanceNow?: number): types.HrTime {
return [seconds, nanos];
}

// Converts a TimeInput to an HrTime, defaults to _hrtime().
/**
*
* Converts a TimeInput to an HrTime, defaults to _hrtime().
* @param time
*/
export function timeInputToHrTime(time: types.TimeInput): types.HrTime {
// process.hrtime
if (isTimeInputHrTime(time)) {
Expand All @@ -81,7 +91,11 @@ export function timeInputToHrTime(time: types.TimeInput): types.HrTime {
}
}

// Returns a duration of two hrTime.
/**
* Returns a duration of two hrTime.
* @param startTime
* @param endTime
*/
export function hrTimeDuration(
startTime: types.HrTime,
endTime: types.HrTime
Expand All @@ -99,21 +113,46 @@ export function hrTimeDuration(
return [seconds, nanos];
}

// Convert hrTime to nanoseconds.
/**
* Convert hrTime to timestamp, for example "2019-05-14T17:00:00.000123456Z"
* @param hrTime
*/
export function hrTimeToTimeStamp(hrTime: types.HrTime): string {
const precision = NANOSECOND_DIGITS;
const tmp = `${'0'.repeat(precision)}${hrTime[1]}Z`;
const nanoString = tmp.substr(tmp.length - precision - 1);
const date = new Date(hrTime[0] * 1000).toISOString();
return date.replace('000Z', nanoString);
}

/**
* Convert hrTime to nanoseconds.
* @param hrTime
*/
export function hrTimeToNanoseconds(hrTime: types.HrTime): number {
return hrTime[0] * SECOND_TO_NANOSECONDS + hrTime[1];
}

// Convert hrTime to milliseconds.
/**
* Convert hrTime to milliseconds.
* @param hrTime
*/
export function hrTimeToMilliseconds(hrTime: types.HrTime): number {
return Math.round(hrTime[0] * 1e3 + hrTime[1] / 1e6);
}

// Convert hrTime to microseconds.
/**
* Convert hrTime to microseconds.
* @param hrTime
*/
export function hrTimeToMicroseconds(hrTime: types.HrTime): number {
return Math.round(hrTime[0] * 1e6 + hrTime[1] / 1e3);
}

/**
* check if time is HrTime
* @param value
*/
export function isTimeInputHrTime(value: unknown) {
return (
Array.isArray(value) &&
Expand All @@ -123,7 +162,10 @@ export function isTimeInputHrTime(value: unknown) {
);
}

// check if input value is a correct types.TimeInput
/**
* check if input value is a correct types.TimeInput
* @param value
*/
export function isTimeInput(value: unknown) {
return (
isTimeInputHrTime(value) ||
Expand Down
18 changes: 18 additions & 0 deletions packages/opentelemetry-core/src/common/version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*!
* Copyright 2019, 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.
*/

// this is autogenerated file, see scripts/version-update.js
export const VERSION = '0.2.0';
1 change: 1 addition & 0 deletions packages/opentelemetry-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export * from './common/ConsoleLogger';
export * from './common/NoopLogger';
export * from './common/time';
export * from './common/types';
export * from './common/version';
export * from './context/propagation/B3Format';
export * from './context/propagation/BinaryTraceContext';
export * from './context/propagation/HttpTraceContext';
Expand Down
Loading

0 comments on commit b58ad10

Please sign in to comment.