Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 26 additions & 0 deletions examples/redis/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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.
*/

'use strict';

const baseConfig = require('../../eslint.config');

module.exports = {
...baseConfig,
env: {
node: true,
},
};
3 changes: 3 additions & 0 deletions examples/redis/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"description": "Example of Redis integration with OpenTelemetry",
"main": "index.js",
"scripts": {
"lint": "eslint . --ext=ts,js,mjs",
"lint:fix": "eslint . --ext=ts,js,mjs --fix",
"docker:start": "docker run -d -p 6379:6379 --name otel-redis redis:alpine",
"docker:stop": "docker stop otel-redis && docker rm otel-redis",
"zipkin:server": "cross-env EXPORTER=zipkin ts-node src/server.ts",
Expand Down Expand Up @@ -37,6 +39,7 @@
"@opentelemetry/instrumentation": "^0.48.0",
"@opentelemetry/instrumentation-http": "^0.48.0",
"@opentelemetry/instrumentation-redis": "^0.32.0",
"@opentelemetry/resources": "^1.0.0",
"@opentelemetry/sdk-trace-base": "^1.0.0",
"@opentelemetry/sdk-trace-node": "^1.0.0",
"@opentelemetry/semantic-conventions": "^1.27.0",
Expand Down
62 changes: 44 additions & 18 deletions examples/redis/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,55 @@
'use strict';
/*
* 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 { setupTracing } from "./tracer";
const tracer = setupTracing('example-redis-client');
import * as api from '@opentelemetry/api';
import { default as axios } from 'axios';
import * as axios from 'axios';
// eslint-disable-next-line import/extensions
import { setupTracing } from './tracer';

const tracer = setupTracing('example-redis-client');

function makeRequest() {
async function makeRequest() {
const span = tracer.startSpan('client.makeRequest()', {
kind: api.SpanKind.CLIENT,
});

api.context.with(api.trace.setSpan(api.ROOT_CONTEXT, span), async () => {
try {
const res = await axios.get('http://localhost:8080/run_test');
span.setStatus({ code: api.SpanStatusCode.OK });
console.log(res.statusText);
} catch (e) {
if(e instanceof Error) {
span.setStatus({ code: api.SpanStatusCode.ERROR, message: e.message });
await api.context.with(
api.trace.setSpan(api.ROOT_CONTEXT, span),
async () => {
try {
const res = await axios.get('http://localhost:8080/run_test');
span.setStatus({ code: api.SpanStatusCode.OK });
console.log(res.statusText);
} catch (e) {
if (e instanceof Error) {
span.setStatus({
code: api.SpanStatusCode.ERROR,
message: e.message,
});
}
}
span.end();
console.log(
'Sleeping 5 seconds before shutdown to ensure all records are flushed.'
);
setTimeout(() => {
console.log('Completed.');
}, 5000);
}
span.end();
console.log('Sleeping 5 seconds before shutdown to ensure all records are flushed.');
setTimeout(() => { console.log('Completed.'); }, 5000);
});
);
}

makeRequest();
makeRequest().catch(err => console.log(err));
28 changes: 22 additions & 6 deletions examples/redis/src/express-tracer-handlers.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
'use strict';
/*
* 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 api from '@opentelemetry/api';

export function getMiddlewareTracer(tracer: api.Tracer) {
return (req: any, res: any, next: any) => {
const span = tracer.startSpan(`express.middleware.tracer(${req.method} ${req.path})`, {
kind: api.SpanKind.SERVER,
});
const span = tracer.startSpan(
`express.middleware.tracer(${req.method} ${req.path})`,
{
kind: api.SpanKind.SERVER,
}
);

// End this span before sending out the response
const originalSend = res.send;
Expand All @@ -22,12 +39,11 @@ export function getMiddlewareTracer(tracer: api.Tracer) {
export function getErrorTracer(tracer: api.Tracer) {
return (err: any, _req: any, res: any, _next: any) => {
console.error('Caught error', err.message);
const span = api.trace.getSpan(api.context.active())
const span = api.trace.getSpan(api.context.active());

if (span) {
span.setStatus({ code: api.SpanStatusCode.ERROR, message: err.message });
}
res.status(500).send(err.message);
};
}

45 changes: 32 additions & 13 deletions examples/redis/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
'use strict';

import { setupTracing } from './tracer'
const tracer = setupTracing('example-redis-server');
/*
* 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.
*/

// Require in rest of modules
import * as express from 'express';
import axios from 'axios';
import * as tracerHandlers from './express-tracer-handlers';
import * as axios from 'axios';
import { randomBytes } from 'crypto';
const redisPromise = require('./setup-redis').redis;
// eslint-disable-next-line import/extensions
import { setupTracing } from './tracer';
// eslint-disable-next-line import/extensions
import * as tracerHandlers from './express-tracer-handlers';

const tracer = setupTracing('example-redis-server');
// eslint-disable-next-line import/extensions
const { redisPromise } = require('./setup-redis');

// Setup express
const app = express();
Expand All @@ -32,7 +49,7 @@ async function setupRoutes() {
}
});

app.get('/:cmd', (req: any , res: any) => {
app.get('/:cmd', (req: any, res: any) => {
if (!req.query.args) {
res.status(400).send('No args provided');
return;
Expand All @@ -54,8 +71,10 @@ async function setupRoutes() {

// Setup express routes & middleware
app.use(tracerHandlers.getMiddlewareTracer(tracer));
setupRoutes().then(() => {
app.use(tracerHandlers.getErrorTracer(tracer));
app.listen(PORT);
console.log(`Listening on http://localhost:${PORT}`);
});
setupRoutes()
.then(() => {
app.use(tracerHandlers.getErrorTracer(tracer));
app.listen(PORT);
console.log(`Listening on http://localhost:${PORT}`);
})
.catch(err => console.log(err));
27 changes: 20 additions & 7 deletions examples/redis/src/setup-redis.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
'use strict';
/*
* 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 {createClient} from 'redis';
import { createClient } from 'redis';

const client = createClient('redis://localhost:6379');
const redisPromise = new Promise(((resolve, reject) => {
// eslint-disable-next-line import/prefer-default-export
export const redisPromise = new Promise((resolve, reject) => {
client.once('ready', () => {
resolve(client);
});
client.once('error', (error) => {
client.once('error', error => {
reject(error);
});
}));

exports.redis = redisPromise;
});
26 changes: 18 additions & 8 deletions examples/redis/src/tracer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
'use strict';
/*
* 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 api from '@opentelemetry/api';
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
Expand All @@ -13,6 +27,7 @@ import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';

const EXPORTER = process.env.EXPORTER || '';

// eslint-disable-next-line import/prefer-default-export
export const setupTracing = (serviceName: string) => {
let exporter;
if (EXPORTER.toLowerCase().startsWith('z')) {
Expand All @@ -25,19 +40,14 @@ export const setupTracing = (serviceName: string) => {
resource: new Resource({
[ATTR_SERVICE_NAME]: serviceName,
}),
spanProcessors: [
new SimpleSpanProcessor(exporter),
]
spanProcessors: [new SimpleSpanProcessor(exporter)],
});

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

registerInstrumentations({
instrumentations: [
new HttpInstrumentation(),
new RedisInstrumentation(),
],
instrumentations: [new HttpInstrumentation(), new RedisInstrumentation()],
tracerProvider: provider,
});

Expand Down