Skip to content
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
62dd4da
add dex guide
mfranzon Jan 29, 2025
576743e
more work dex guide
mfranzon Mar 12, 2025
e036e68
Merge branch 'docker:main' into main
mfranzon Mar 12, 2025
0eeabb0
Merge branch 'main' of github.com:mfranzon/docs
mfranzon Mar 12, 2025
2c12ba0
add conclusions
mfranzon Mar 12, 2025
47edef8
Update content/guides/dex.md
mfranzon Mar 26, 2025
8fdaeff
Update content/guides/dex.md
mfranzon Mar 26, 2025
2b53f8e
Update content/guides/dex.md
mfranzon Mar 26, 2025
09145ad
Update content/guides/dex.md
mfranzon Mar 26, 2025
9c039f2
Update content/guides/dex.md
mfranzon Mar 26, 2025
51bc0e8
Update content/guides/dex.md
mfranzon Mar 26, 2025
e4be9d3
Update content/guides/dex.md
mfranzon Mar 26, 2025
be4b242
Update content/guides/dex.md
mfranzon Mar 26, 2025
89b489c
Update content/guides/dex.md
mfranzon Mar 26, 2025
1cc50e1
Update content/guides/dex.md
mfranzon Mar 26, 2025
ccb86db
Update content/guides/dex.md
mfranzon Mar 26, 2025
6a7a934
add Dex to vale accept.txt
mfranzon Mar 26, 2025
99250df
Merge branch 'docker:main' into main
mfranzon Jul 29, 2025
1d3e72d
add otel guide
mfranzon Jul 29, 2025
d06f810
Fix JS tag
sarahsanders-docker Aug 20, 2025
a766d31
fix vale failure
sarahsanders-docker Aug 20, 2025
3c6ba02
fix value failure
sarahsanders-docker Aug 20, 2025
8a1761f
capitalization
sarahsanders-docker Aug 20, 2025
75be8b2
capitalization
sarahsanders-docker Aug 20, 2025
96f1a38
add ticks
sarahsanders-docker Aug 20, 2025
e7f667a
add observability tag
mfranzon Aug 27, 2025
24a02dd
Merge branch 'main' into main
mfranzon Aug 27, 2025
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
1 change: 1 addition & 0 deletions _vale/config/vocabularies/Docker/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ deprovisioning
deserialization
deserialize
Dev
Dex
Dev Environments?
Dex
displayName
Expand Down
200 changes: 200 additions & 0 deletions content/guides/opentelemetry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
---
title: Instrumenting a JavaScript App with OpenTelemetry
description: &desc Learn how to instrument a JavaScript application using OpenTelemetry in a Dockerized environment.
keywords: OpenTelemetry, observability, tracing
linktitle: Instrumenting JS Apps with OpenTelemetry
summary: *desc
tags: [app-dev, observability]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

observability is failing in the build check because it is not defined yet.

To fix this:

  1. Go to docs/content/tags/ and add a new observability folder
  2. In that folder, add an _index.md file with the following content:
---
title: Observability
---

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

languages: [js]
params:
time: 10 minutes
---

OpenTelemetry (OTEL) is an open-source observability framework that provides a set of APIs, SDKs, and tools for collecting telemetry data, such as metrics, logs, and traces, from applications. With OpenTelemetry, developers can obtain valuable insights into how their services perform in production or during local development.

A key component of OpenTelemetry is the OpenTelemetry Protocol (OTLP) a general-purpose, vendor-agnostic protocol designed to transmit telemetry data efficiently and reliably. OTLP supports multiple data types (traces, metrics, logs) over HTTP or gRPC, making it the default and recommended protocol for communication between instrumented applications, the OpenTelemetry Collector, and backends such as Jaeger or Prometheus.

This guide walks you through how to instrument a simple Node.js application with OpenTelemetry and run both the app and a collector using Docker. This setup is ideal for local development and testing observability before integrating with external observability platforms like Prometheus, Jaeger, or Grafana.

In this guide, you'll learn how to:

- How to set up OpenTelemetry in a Node.js app.
- How to run an OpenTelemetry Collector in Docker.
- How to visualize traces with Jaeger.
- How to use Docker Compose to manage the full observability stack.

## Using OpenTelemetry with Docker

the official [docker image for opentelemetry](https://hub.docker.com/r/otel/opentelemetry-collector-contrib) provides a convenient way to deploy and manage dex instances. Opentelemetry is available for various cpu architectures, including amd64, armv7, and arm64, ensuring compatibility with different devices and platforms. Same for the [Jaeger docekr image](https://hub.docker.com/r/jaegertracing/jaeger).

## Prerequisites

[Docker Compose](/compose/): Recommended for managing multi-container Docker applications.

Basic knowledge of Node.js and Docker.

## Project Structure

Create the project directory:
```bash
mkdir otel-js-app
cd otel-js-app
```

```bash
otel-js-app/
├── docker-compose.yaml
├── collector-config.yaml
├── app/
│ ├── package.json
│ ├── app.js
│ └── tracer.js
```

## Create a Simple Node.js App

Initialize a basic Node.js app:

```bash
mkdir app && cd app
npm init -y
npm install express @opentelemetry/api @opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-http
```

Now, add the application logic:

```js
// app/app.js
const express = require('express');
require('./tracer'); // Initialize OpenTelemetry

const app = express();

app.get('/', (req, res) => {
res.send('Hello from OpenTelemetry demo app!');
});

const PORT = 3000;
app.listen(PORT, () => {
console.log(`App listening at http://localhost:${PORT}`);
});
```

## Configure OpenTelemetry Tracing

Create the tracer configuration file:

```js
// app/tracer.js
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');

const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: 'http://collector:4318/v1/traces',
}),
instrumentations: [getNodeAutoInstrumentations()],
});

sdk.start();
```

## Configure the OpenTelemetry Collector

Create a collector-config.yaml file at the root:

```yaml
# collector-config.yaml
receivers:
otlp:
protocols:
http:

exporters:
logging:
loglevel: debug
jaeger:
endpoint: jaeger:14250
tls:
insecure: true

service:
pipelines:
traces:
receivers: [otlp]
exporters: [logging, jaeger]
```

## Add Docker Compose Configuration

Create the `docker-compose.yaml` file:

```yaml
version: '3.9'

services:
app:
build: ./app
ports:
- "3000:3000"
environment:
- NODE_ENV=development
depends_on:
- collector

collector:
image: otel/opentelemetry-collector:latest
volumes:
- ./collector-config.yaml:/etc/otelcol/config.yaml
command: ["--config=/etc/otelcol/config.yaml"]
ports:
- "4318:4318" # OTLP

jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686" # UI
- "14250:14250" # Collector gRPC
```

Now, add the `Dockerfile` inside the `app/` folder:

```dockerfile
# app/Dockerfile
FROM node:18

WORKDIR /usr/src/app
COPY . .
RUN npm install

CMD ["node", "app.js"]
```

## Start the Stack

Start all services with Docker Compose:

```bash
docker compose up --build
```

Once the services are running:

Visit your app at [http://localhost:3000](http://localhost:3000)

View traces at [http://localhost:16686](http://localhost:16686) in the Jaeger UI

## Verify Traces in Jaeger

After visiting your app's root endpoint, open Jaeger’s UI, search for the service (default is usually unknown_service unless explicitly named), and check the traces.

You should see spans for the HTTP request, middleware, and auto-instrumented libraries.

## Conclusion

You now have a fully functional OpenTelemetry setup using Docker Compose. You've instrumented a basic JavaScript app to export traces and visualized them using Jaeger. This architecture is extendable for more complex applications and observability pipelines using Prometheus, Grafana, or cloud-native exporters.

For advanced topics such as custom span creation, metrics, and logs, consult the OpenTelemetry JavaScript docs.