diff --git a/examples/express/README.md b/examples/express/README.md index 5794a5077e..d0251ba8fa 100644 --- a/examples/express/README.md +++ b/examples/express/README.md @@ -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 @@ -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 and click the "RUN QUERY" button to view -recent traces, then click "SHOW" on a given trace. - -

Zipkin UI with trace

- -### 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 , select a service (e.g. "example-express-client"), click "Find Traces", then click on a trace to view it. diff --git a/examples/express/images/zipkin.jpg b/examples/express/images/zipkin.jpg deleted file mode 100644 index 5b13e03c78..0000000000 Binary files a/examples/express/images/zipkin.jpg and /dev/null differ diff --git a/examples/express/package.json b/examples/express/package.json index ab47e5bb3a..b5b3049f0a 100644 --- a/examples/express/package.json +++ b/examples/express/package.json @@ -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": { @@ -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" } diff --git a/examples/express/src/tracer.ts b/examples/express/src/tracer.ts index 4ad569644f..b86e92b712 100644 --- a/examples/express/src/tracer.ts +++ b/examples/express/src/tracer.ts @@ -1,29 +1,19 @@ '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()), }); @@ -31,21 +21,19 @@ export const setupTracing = (serviceName: string) => { 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; @@ -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); }, @@ -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"; }