diff --git a/examples/express/.npmrc b/examples/express/.npmrc new file mode 100644 index 0000000000..43c97e719a --- /dev/null +++ b/examples/express/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/examples/express/README.md b/examples/express/README.md index dd72656ff5..b1cec5b854 100644 --- a/examples/express/README.md +++ b/examples/express/README.md @@ -13,11 +13,7 @@ shows key aspects of tracing such as ## Installation ```sh -# from this directory, install all necessary dependencies from the workspace -npm run setup - -# OR alternatively, install dependencies from npm as a standalone example app -npm install --workspaces=false +npm install ``` Setup [Zipkin Tracing](https://zipkin.io/pages/quickstart.html) @@ -28,47 +24,39 @@ Setup [Jaeger Tracing](https://www.jaegertracing.io/docs/latest/getting-started/ ### Zipkin -- Run the server - - ```sh - # from this directory - $ npm run zipkin:server - ``` +Run the server: -- Run the client +```sh +npm run zipkin:server +``` - ```sh - # from this directory - npm run zipkin:client - ``` +Then run the client in a separate terminal: -#### Zipkin UI +```sh +npm run zipkin:client +``` -`zipkin:server` script should output the `traceid` in the terminal (e.g `traceid: 4815c3d576d930189725f1f1d1bdfcc6`). -Go to Zipkin with your browser (e.g ) +After a short time, the generated traces should be available in the Zipkin UI. +Visit and click the "RUN QUERY" button to view +recent traces, then click "SHOW" on a given trace.

### Jaeger -- Run the server +Run the server: - ```sh - # from this directory - $ npm run jaeger:server - ``` - -- Run the client +```sh +npm run jaeger:server +``` - ```sh - # from this directory - npm run jaeger:client - ``` +Then run the client in a separate terminal: -#### Jaeger UI +```sh +npm run jaeger:client +``` -`jaeger:server` script should output the `traceid` in the terminal (e.g `traceid: 4815c3d576d930189725f1f1d1bdfcc6`). -Go to Jaeger with your browser (e.g ) +Visit the Jaeger UI at , select a service (e.g. "example-express-client"), click "Find Traces", then click on a trace to view it.

diff --git a/examples/express/package.json b/examples/express/package.json index bc98d21c86..6055ecc2fd 100644 --- a/examples/express/package.json +++ b/examples/express/package.json @@ -8,8 +8,7 @@ "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", - "compile": "tsc -p .", - "setup": "cd ../../../../ && npm ci && cd plugins/node/opentelemetry-instrumentation-express && npm run compile && cd examples && npm run compile" + "compile": "tsc -p ." }, "repository": { "type": "git", diff --git a/examples/express/tsconfig.json b/examples/express/tsconfig.json index 5a768b7e2c..1220a445aa 100644 --- a/examples/express/tsconfig.json +++ b/examples/express/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../tsconfig.json", + "extends": "../../tsconfig.base", "compilerOptions": { "noEmit": true, "rootDir": ".", diff --git a/plugins/node/opentelemetry-instrumentation-express/.eslintignore b/plugins/node/opentelemetry-instrumentation-express/.eslintignore index 514cc95d43..378eac25d3 100644 --- a/plugins/node/opentelemetry-instrumentation-express/.eslintignore +++ b/plugins/node/opentelemetry-instrumentation-express/.eslintignore @@ -1,2 +1 @@ build -examples diff --git a/plugins/node/opentelemetry-instrumentation-express/README.md b/plugins/node/opentelemetry-instrumentation-express/README.md index 3bcb67989b..3169c7237e 100644 --- a/plugins/node/opentelemetry-instrumentation-express/README.md +++ b/plugins/node/opentelemetry-instrumentation-express/README.md @@ -45,7 +45,7 @@ registerInstrumentations({ }); ``` -See [examples](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-express/examples) for a short example. +See [examples/express](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/examples/express) for a short example. ### Caveats diff --git a/plugins/node/opentelemetry-instrumentation-express/examples/README.md b/plugins/node/opentelemetry-instrumentation-express/examples/README.md deleted file mode 100644 index dd72656ff5..0000000000 --- a/plugins/node/opentelemetry-instrumentation-express/examples/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# 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. - -This is a simple example that demonstrates tracing calls made to Express API. The example -shows key aspects of tracing such as - -- Root Span (on Client) -- Child Span (on Client) -- Span Events -- Span Attributes - -## Installation - -```sh -# from this directory, install all necessary dependencies from the workspace -npm run setup - -# OR alternatively, install dependencies from npm as a standalone example app -npm install --workspaces=false -``` - -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 - # from this directory - $ npm run zipkin:server - ``` - -- Run the client - - ```sh - # from this directory - npm run zipkin:client - ``` - -#### Zipkin UI - -`zipkin:server` script should output the `traceid` in the terminal (e.g `traceid: 4815c3d576d930189725f1f1d1bdfcc6`). -Go to Zipkin with your browser (e.g ) - -

- -### Jaeger - -- Run the server - - ```sh - # from this directory - $ npm run jaeger:server - ``` - -- Run the client - - ```sh - # from this directory - npm run jaeger:client - ``` - -#### Jaeger UI - -`jaeger:server` script should output the `traceid` in the terminal (e.g `traceid: 4815c3d576d930189725f1f1d1bdfcc6`). -Go to Jaeger with your browser (e.g ) - -

- -## Useful links - -- For more information on OpenTelemetry, visit: -- For more information on OpenTelemetry for Node.js, visit: - -## LICENSE - -Apache License 2.0 diff --git a/plugins/node/opentelemetry-instrumentation-express/examples/images/jaeger.jpg b/plugins/node/opentelemetry-instrumentation-express/examples/images/jaeger.jpg deleted file mode 100644 index c4afe9e030..0000000000 Binary files a/plugins/node/opentelemetry-instrumentation-express/examples/images/jaeger.jpg and /dev/null differ diff --git a/plugins/node/opentelemetry-instrumentation-express/examples/images/zipkin.jpg b/plugins/node/opentelemetry-instrumentation-express/examples/images/zipkin.jpg deleted file mode 100644 index 5b13e03c78..0000000000 Binary files a/plugins/node/opentelemetry-instrumentation-express/examples/images/zipkin.jpg and /dev/null differ diff --git a/plugins/node/opentelemetry-instrumentation-express/examples/package.json b/plugins/node/opentelemetry-instrumentation-express/examples/package.json deleted file mode 100644 index bc98d21c86..0000000000 --- a/plugins/node/opentelemetry-instrumentation-express/examples/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "express-example", - "private": true, - "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", - "compile": "tsc -p .", - "setup": "cd ../../../../ && npm ci && cd plugins/node/opentelemetry-instrumentation-express && npm run compile && cd examples && npm run compile" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/open-telemetry/opentelemetry-js-contrib.git", - "directory": "plugins/node/opentelemetry-instrumentation-express" - }, - "keywords": [ - "opentelemetry", - "express", - "tracing" - ], - "engines": { - "node": ">=14" - }, - "author": "OpenTelemetry Authors", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/open-telemetry/opentelemetry-js-contrib/issues" - }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-express/examples#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/semantic-conventions": "^1.18.1", - "axios": "^1.6.0", - "cross-env": "^7.0.3", - "express": "^4.17.1" - }, - "devDependencies": { - "@types/express": "^4.17.13", - "ts-node": "^10.6.0", - "typescript": "4.4.4" - } -} diff --git a/plugins/node/opentelemetry-instrumentation-express/examples/src/client.ts b/plugins/node/opentelemetry-instrumentation-express/examples/src/client.ts deleted file mode 100644 index 6a39414d09..0000000000 --- a/plugins/node/opentelemetry-instrumentation-express/examples/src/client.ts +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -// eslint-disable-next-line import/order -import { setupTracing } from "./tracer"; -const tracer = setupTracing('example-express-client'); - -import * as api from '@opentelemetry/api'; -import { default as axios } from 'axios'; - -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'); - console.log('status:', res.statusText); - span.setStatus({ code: api.SpanStatusCode.OK }); - } catch (e) { - if (e instanceof Error) { - console.log('failed:', e.message); - 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); - }); -} - -makeRequest(); diff --git a/plugins/node/opentelemetry-instrumentation-express/examples/src/server.ts b/plugins/node/opentelemetry-instrumentation-express/examples/src/server.ts deleted file mode 100644 index 37cec8819e..0000000000 --- a/plugins/node/opentelemetry-instrumentation-express/examples/src/server.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { setupTracing } from './tracer' - -setupTracing('example-express-server'); - -// Require in rest of modules -import * as express from 'express'; -import { default as axios } from 'axios'; -import { RequestHandler } from "express"; - -// Setup express -const app = express(); -const PORT = 8080; - -const getCrudController = () => { - const router = express.Router(); - const resources: any[] = []; - router.get('/', (req, res) => res.send(resources)); - router.post('/', (req, res) => { - resources.push(req.body); - return res.status(201).send(req.body); - }); - return router; -}; - -const authMiddleware: RequestHandler = (req, res, next) => { - const { authorization } = req.headers; - if (authorization && authorization.includes('secret_token')) { - next(); - } else { - res.sendStatus(401); - } -}; - -app.use(express.json()); -app.get('/health', (req, res) => res.status(200).send("HEALTHY")); // endpoint that is called by framework/cluster -app.get('/run_test', async (req, res) => { - // Calls another endpoint of the same API, somewhat mimicing an external API call - const createdCat = await axios.post(`http://localhost:${PORT}/cats`, { - name: 'Tom', - friends: [ - 'Jerry', - ], - }, { - headers: { - Authorization: 'secret_token', - }, - }); - - return res.status(201).send(createdCat.data); -}); -app.use('/cats', authMiddleware, getCrudController()); - -app.listen(PORT, () => { - console.log(`Listening on http://localhost:${PORT}`); -}); diff --git a/plugins/node/opentelemetry-instrumentation-express/examples/src/tracer.ts b/plugins/node/opentelemetry-instrumentation-express/examples/src/tracer.ts deleted file mode 100644 index 93a1515f69..0000000000 --- a/plugins/node/opentelemetry-instrumentation-express/examples/src/tracer.ts +++ /dev/null @@ -1,69 +0,0 @@ -'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 { 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 { SemanticAttributes, SemanticResourceAttributes as ResourceAttributesSC } from '@opentelemetry/semantic-conventions'; - -const Exporter = (process.env.EXPORTER || '').toLowerCase().startsWith('z') ? ZipkinExporter : OTLPTraceExporter; -import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'; -const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http'); - -export const setupTracing = (serviceName: string) => { - const provider = new NodeTracerProvider({ - resource: new Resource({ - [ResourceAttributesSC.SERVICE_NAME]: serviceName, - }), - sampler: filterSampler(ignoreHealthCheck, new AlwaysOnSampler()), - }); - registerInstrumentations({ - tracerProvider: provider, - instrumentations: [ - // Express instrumentation expects HTTP layer to be instrumented - HttpInstrumentation, - ExpressInstrumentation, - ], - }); - - const exporter = new Exporter({ - serviceName, - }); - - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); - - // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings - provider.register(); - - return opentelemetry.trace.getTracer(serviceName); -}; - -type FilterFunction = (spanName: string, spanKind: SpanKind, attributes: Attributes) => boolean; - -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 parent.shouldSample(ctx, tid, spanName, spanKind, attr, links); - }, - toString() { - return `FilterSampler(${parent.toString()})`; - } - } -} - -function ignoreHealthCheck(spanName: string, spanKind: SpanKind, attributes: Attributes) { - return spanKind !== opentelemetry.SpanKind.SERVER || attributes[SemanticAttributes.HTTP_ROUTE] !== "/health"; -} diff --git a/plugins/node/opentelemetry-instrumentation-express/examples/tsconfig.json b/plugins/node/opentelemetry-instrumentation-express/examples/tsconfig.json deleted file mode 100644 index 5a768b7e2c..0000000000 --- a/plugins/node/opentelemetry-instrumentation-express/examples/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "noEmit": true, - "rootDir": ".", - }, - "include": [ - "src/**/*.ts", - ] -} diff --git a/plugins/node/opentelemetry-instrumentation-express/package.json b/plugins/node/opentelemetry-instrumentation-express/package.json index 57510cb72d..6d0c09dbef 100644 --- a/plugins/node/opentelemetry-instrumentation-express/package.json +++ b/plugins/node/opentelemetry-instrumentation-express/package.json @@ -16,7 +16,6 @@ "prewatch": "npm run precompile", "version:update": "node ../../../scripts/version-update.js", "compile": "tsc -p .", - "compile:examples": "cd examples && npm run compile", "prepublishOnly": "npm run compile", "watch": "tsc -w" },