Skip to content

Commit

Permalink
Merge branch 'main' into aws-sdk-component-owner-trivikr
Browse files Browse the repository at this point in the history
  • Loading branch information
pichlermarc authored Dec 1, 2024
2 parents 9098772 + 0fc1ed3 commit 45e964b
Show file tree
Hide file tree
Showing 18 changed files with 107 additions and 120 deletions.
46 changes: 18 additions & 28 deletions examples/express/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Overview

OpenTelemetry Express Instrumentation allows the user to automatically collect trace data and export them to the backend of choice (we can use Zipkin or Jaeger for this example), to give observability to distributed systems.
OpenTelemetry Express Instrumentation allows the user to automatically collect trace data and export them to the backend of choice (we use Jaeger for this example), to give observability to distributed systems.

This is a simple example that demonstrates tracing calls made to Express API. The example
shows key aspects of tracing such as
Expand All @@ -17,44 +17,34 @@ shows key aspects of tracing such as
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)

## Run the Application

### Zipkin

Run the server:

```sh
npm run zipkin:server
Start Jaeger in Docker for receiving tracing data (see [the Jaeger docs](https://www.jaegertracing.io/docs/2.0/getting-started/#in-docker) for more details about running Jaeger):

```bash
docker run --rm --name jaeger \
-p 5778:5778 \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
-p 14250:14250 \
-p 14268:14268 \
-p 9411:9411 \
jaegertracing/jaeger:2.0.0 \
--set receivers.otlp.protocols.http.endpoint=0.0.0.0:4318 \
--set receivers.otlp.protocols.grpc.endpoint=0.0.0.0:4317
```

Then run the client in a separate terminal:

```sh
npm run zipkin:client
```

After a short time, the generated traces should be available in the Zipkin UI.
Visit <http://localhost:9411/zipkin> and click the "RUN QUERY" button to view
recent traces, then click "SHOW" on a given trace.

<p align="center"><img alt="Zipkin UI with trace" src="./images/zipkin.jpg?raw=true"/></p>

### Jaeger
## Run the Application

Run the server:

```sh
npm run jaeger:server
npm run server
```

Then run the client in a separate terminal:

```sh
npm run jaeger:client
npm run client
```

Visit the Jaeger UI at <http://localhost:16686/search>, select a service (e.g. "example-express-client"), click "Find Traces", then click on a trace to view it.
Expand Down
Binary file removed examples/express/images/zipkin.jpg
Binary file not shown.
26 changes: 11 additions & 15 deletions examples/express/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
"version": "0.1.0",
"description": "Example of Express integration with OpenTelemetry",
"scripts": {
"zipkin:server": "cross-env EXPORTER=zipkin ts-node src/server.ts",
"zipkin:client": "cross-env EXPORTER=zipkin ts-node src/client.ts",
"jaeger:server": "cross-env EXPORTER=jaeger ts-node src/server.ts",
"jaeger:client": "cross-env EXPORTER=jaeger ts-node src/client.ts",
"server": "ts-node src/server.ts",
"client": "ts-node src/client.ts",
"compile": "tsc -p ."
},
"repository": {
Expand All @@ -30,23 +28,21 @@
},
"homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/examples/express#readme",
"dependencies": {
"@opentelemetry/api": "^1.3.0",
"@opentelemetry/exporter-jaeger": "^1.18.1",
"@opentelemetry/exporter-trace-otlp-proto": "^0.48.0",
"@opentelemetry/exporter-zipkin": "^1.18.1",
"@opentelemetry/instrumentation": "^0.48.0",
"@opentelemetry/instrumentation-express": "^0.34.1",
"@opentelemetry/instrumentation-http": "^0.48.0",
"@opentelemetry/resources": "^1.18.1",
"@opentelemetry/sdk-trace-base": "^1.18.1",
"@opentelemetry/sdk-trace-node": "^1.18.1",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.54.2",
"@opentelemetry/instrumentation": "^0.54.2",
"@opentelemetry/instrumentation-express": "^0.44.0",
"@opentelemetry/instrumentation-http": "^0.54.2",
"@opentelemetry/resources": "^1.27.0",
"@opentelemetry/sdk-trace-base": "^1.27.0",
"@opentelemetry/sdk-trace-node": "^1.27.0",
"@opentelemetry/semantic-conventions": "^1.27.0",
"axios": "^1.6.0",
"cross-env": "^7.0.3",
"express": "^4.17.1"
},
"devDependencies": {
"@types/express": "^4.17.13",
"@types/node": "18.18.14",
"ts-node": "^10.6.0",
"typescript": "4.4.4"
}
Expand Down
32 changes: 10 additions & 22 deletions examples/express/src/tracer.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,39 @@
'use strict';

import { SpanKind, Attributes } from "@opentelemetry/api";

const opentelemetry = require('@opentelemetry/api');

// Not functionally required but gives some insight what happens behind the scenes
const { diag, DiagConsoleLogger, DiagLogLevel } = opentelemetry;
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);

import { trace, SamplingDecision, SpanKind, Attributes } from '@opentelemetry/api';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { Sampler, AlwaysOnSampler, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
import { Resource } from '@opentelemetry/resources';
import { SEMRESATTRS_SERVICE_NAME, SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';

const Exporter = (process.env.EXPORTER || '').toLowerCase().startsWith('z') ? ZipkinExporter : OTLPTraceExporter;
import { ATTR_SERVICE_NAME, ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';

export const setupTracing = (serviceName: string) => {
const provider = new NodeTracerProvider({
resource: new Resource({
[SEMRESATTRS_SERVICE_NAME]: serviceName,
[ATTR_SERVICE_NAME]: serviceName,
}),
sampler: filterSampler(ignoreHealthCheck, new AlwaysOnSampler()),
});
registerInstrumentations({
tracerProvider: provider,
instrumentations: [
// Express instrumentation expects HTTP layer to be instrumented
HttpInstrumentation,
ExpressInstrumentation,
new HttpInstrumentation(),
new ExpressInstrumentation(),
],
});

const exporter = new Exporter({
serviceName,
});
const exporter = new OTLPTraceExporter({});

provider.addSpanProcessor(new SimpleSpanProcessor(exporter));

// Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings
provider.register();

return opentelemetry.trace.getTracer(serviceName);
return trace.getTracer(serviceName);
};

type FilterFunction = (spanName: string, spanKind: SpanKind, attributes: Attributes) => boolean;
Expand All @@ -54,7 +42,7 @@ function filterSampler(filterFn: FilterFunction, parent: Sampler): Sampler {
return {
shouldSample(ctx, tid, spanName, spanKind, attr, links) {
if (!filterFn(spanName, spanKind, attr)) {
return { decision: opentelemetry.SamplingDecision.NOT_RECORD };
return { decision: SamplingDecision.NOT_RECORD };
}
return parent.shouldSample(ctx, tid, spanName, spanKind, attr, links);
},
Expand All @@ -65,5 +53,5 @@ function filterSampler(filterFn: FilterFunction, parent: Sampler): Sampler {
}

function ignoreHealthCheck(spanName: string, spanKind: SpanKind, attributes: Attributes) {
return spanKind !== opentelemetry.SpanKind.SERVER || attributes[SEMATTRS_HTTP_ROUTE] !== "/health";
return spanKind !== SpanKind.SERVER || attributes[ATTR_HTTP_ROUTE] !== "/health";
}
21 changes: 10 additions & 11 deletions examples/mongodb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,20 @@
"url": "https://github.com/open-telemetry/opentelemetry-js-contrib/issues"
},
"dependencies": {
"@opentelemetry/api": "^1.0.0",
"@opentelemetry/exporter-jaeger": "^1.0.0",
"@opentelemetry/exporter-zipkin": "^1.0.0",
"@opentelemetry/instrumentation": "^0.48.0",
"@opentelemetry/instrumentation-http": "^0.48.0",
"@opentelemetry/instrumentation-mongodb": "^0.32.0",
"@opentelemetry/sdk-trace-node": "^1.0.0",
"@opentelemetry/sdk-trace-base": "^1.0.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/exporter-zipkin": "^1.27.0",
"@opentelemetry/instrumentation": "^0.54.2",
"@opentelemetry/instrumentation-http": "^0.54.2",
"@opentelemetry/instrumentation-mongodb": "^0.48.0",
"@opentelemetry/sdk-trace-node": "^1.27.0",
"@opentelemetry/sdk-trace-base": "^1.27.0",
"@opentelemetry/semantic-conventions": "^1.27.0",
"mongodb": "^3.6.11"
"mongodb": "^6.10.0"
},
"homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib#readme",
"devDependencies": {
"cross-env": "^7.0.3",
"ts-node": "^10.6.0",
"typescript": "4.4.4"
"ts-node": "^10.9.2",
"typescript": "5.6.3"
}
}
44 changes: 24 additions & 20 deletions examples/mongodb/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ import * as api from '@opentelemetry/api';

import { setupTracing } from './tracer';

setupTracing('example-mongodb-server')
setupTracing('example-mongodb-server');

import { accessDB } from './utils';

import * as http from 'http';
import { IncomingMessage, ServerResponse } from 'http';
import * as mongodb from 'mongodb';
import {Collection} from "mongodb";
import { Collection } from 'mongodb';

const DB_NAME = 'mydb'
const COLLECTION_NAME = 'users'
const DB_NAME = 'mydb';
const COLLECTION_NAME = 'users';
const URL = `mongodb://localhost:27017/${DB_NAME}`;

let db: mongodb.Db;
Expand All @@ -28,7 +28,6 @@ function startServer(port: number) {
throw err;
});


// Creates a server
const server = http.createServer(handleRequest);
// Starts the server
Expand All @@ -40,16 +39,20 @@ function startServer(port: number) {
/** A function which handles requests and send response. */
function handleRequest(request: IncomingMessage, response: ServerResponse) {
const currentSpan = api.trace.getSpan(api.context.active());
// display traceID in the terminal
const traceId = currentSpan?.spanContext();
console.log(`traceid: ${traceId}`);
console.log(`Jaeger URL: http://localhost:16686/trace/${traceId}`);
console.log(`Zipkin URL: http://localhost:9411/zipkin/traces/${traceId}`);
if (currentSpan) {
// display traceID in the terminal
const { traceId } = currentSpan?.spanContext();
console.log(`traceid: ${traceId}`);
console.log(`Jaeger URL: http://localhost:16686/trace/${traceId}`);
console.log(`Zipkin URL: http://localhost:9411/zipkin/traces/${traceId}`);
} else {
console.log('No active span found');
}

try {
const body = [];
request.on('error', (err) => console.log(err));
request.on('data', (chunk) => body.push(chunk));
request.on('error', err => console.log(err));
request.on('data', chunk => body.push(chunk));
request.on('end', async () => {
if (request.url === '/collection/') {
handleCreateCollection(response);
Expand All @@ -71,12 +74,13 @@ startServer(8080);
function handleInsertQuery(response: ServerResponse) {
const obj = { name: 'John', age: '20' };
const usersCollection: Collection = db.collection(COLLECTION_NAME);
usersCollection.insertOne(obj)
usersCollection
.insertOne(obj)
.then(() => {
console.log('1 document inserted');
// find document to test context propagation using callback
usersCollection.findOne({}, function () {
response.end();
// find document to test context
usersCollection.findOne({}).then(res => {
console.log(JSON.stringify(res));
});
})
.catch(err => {
Expand All @@ -87,16 +91,16 @@ function handleInsertQuery(response: ServerResponse) {

function handleGetQuery(response: ServerResponse) {
const usersCollection: Collection = db.collection(COLLECTION_NAME);
usersCollection.
find({})
usersCollection
.find({})
.toArray()
.then(() => {
console.log('1 document served');
response.end();
})
.catch(err => {
throw err;
})
});
}

function handleCreateCollection(response: ServerResponse) {
Expand All @@ -108,7 +112,7 @@ function handleCreateCollection(response: ServerResponse) {
.catch(err => {
console.log('Error code:', err.code);
response.end(err.message);
});
});
}

function handleNotFound(response: ServerResponse) {
Expand Down
13 changes: 6 additions & 7 deletions examples/mongodb/src/tracer.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import * as api from "@opentelemetry/api";
import * as api from '@opentelemetry/api';

import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { Resource } from '@opentelemetry/resources';
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb';
import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions';

import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';

export const setupTracing = (serviceName: string): api.Tracer => {
const provider = new NodeTracerProvider({
resource: new Resource({
[SEMRESATTRS_SERVICE_NAME]: serviceName
})
[ATTR_SERVICE_NAME]: serviceName,
}),
});

// Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings
Expand All @@ -32,7 +31,7 @@ export const setupTracing = (serviceName: string): api.Tracer => {
});

provider.addSpanProcessor(new SimpleSpanProcessor(new ZipkinExporter()));
provider.addSpanProcessor(new SimpleSpanProcessor(new JaegerExporter()));
provider.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter()));

return api.trace.getTracer('mongodb-example');
};
1 change: 1 addition & 0 deletions examples/web/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
14 changes: 13 additions & 1 deletion examples/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,26 @@ This example shows how to use [@opentelemetry/sdk-trace-web][] with different in
npm install
```

## Start a collector and trace viewer

Optionally, you can use the provided Docker Compose file to start an OpenTelemetry Collector and a Zipkin to view collected traces.
You can skip this step if you have your own collector already setup.

```sh
npm run docker:start
```

## Run the Application

```sh
# from this directory
npm start
```

By default, the application will run on port `8090`.
- Open the application at <http://localhost:8090>.
- Click around in each of the example sub-paths to create some tracing data.
- Open Zipkin at <http://127.0.0.1:9411/zipkin/> and search for some traces (click "Run Query").


## More information

Expand Down
Loading

0 comments on commit 45e964b

Please sign in to comment.