@emeryld/obs-stack 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +4 -0
- package/README.md +65 -76
- package/configs/tempo.yaml +3 -2
- package/docker-compose.yml +2 -1
- package/package.json +1 -1
package/.env.example
CHANGED
|
@@ -7,6 +7,10 @@ GRAFANA_PASS=admin
|
|
|
7
7
|
OTEL_OTLP_HTTP_PORT=4318
|
|
8
8
|
OTEL_OTLP_GRPC_PORT=4317
|
|
9
9
|
|
|
10
|
+
# When pointing services outside the stack at the collector, use these values.
|
|
11
|
+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:${OTEL_OTLP_HTTP_PORT}
|
|
12
|
+
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
|
|
13
|
+
|
|
10
14
|
# Loki + Tempo query ports exposed to host
|
|
11
15
|
LOKI_PORT=3100
|
|
12
16
|
TEMPO_HTTP_PORT=3200
|
package/README.md
CHANGED
|
@@ -1,141 +1,130 @@
|
|
|
1
|
-
# Observability
|
|
1
|
+
# Observability stack
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A Docker Compose bundle that wires Grafana, Tempo, Loki, and an OpenTelemetry Collector together with a lightweight Node CLI for managing the stack from anywhere in the workspace.
|
|
4
4
|
|
|
5
5
|
## Getting started
|
|
6
6
|
|
|
7
|
-
1.
|
|
7
|
+
1. Bootstrapping the monorepo so the CLI is available:
|
|
8
8
|
```bash
|
|
9
|
-
|
|
9
|
+
pnpm install
|
|
10
10
|
```
|
|
11
|
-
2.
|
|
12
|
-
3. Run the CLI from the repo root (it walks the stack directory automatically):
|
|
11
|
+
2. Copy the sample environment file into place near the stack so you can override the default ports/credentials:
|
|
13
12
|
```bash
|
|
14
|
-
|
|
13
|
+
cp packages/obs-stack/.env.example packages/obs-stack/.env
|
|
15
14
|
```
|
|
16
|
-
|
|
15
|
+
3. Tweak any ports or credentials in `packages/obs-stack/.env` if you hit conflicts. The compose stack already declares persistent volumes (`grafana-data`, `tempo-data`, `loki-data`) so dashboards, traces, and logs survive restarts.
|
|
16
|
+
4. Bring the stack up from the repository root (the CLI auto-resolves the stack directory for you):
|
|
17
17
|
```bash
|
|
18
|
-
pnpm --filter @
|
|
18
|
+
pnpm --filter @emeryld/obs-stack obs-stack up
|
|
19
|
+
```
|
|
20
|
+
5. Inspect the endpoints reported by the CLI:
|
|
21
|
+
```bash
|
|
22
|
+
pnpm --filter @emeryld/obs-stack obs-stack urls
|
|
19
23
|
```
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
The CLI loads `packages/obs-stack/.env` and also merges in any `.env` file that lives beside the directory where you run the command, so you can keep machine-specific overrides outside of version control.
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
- `obs-stack down`: stops the containers without removing volumes.
|
|
25
|
-
- `obs-stack reset`: stops the stack and deletes the data volumes (`down -v`).
|
|
26
|
-
- `obs-stack status`: shows `docker compose ps` for the stack.
|
|
27
|
-
- `obs-stack logs`: tails the combined logs of all services.
|
|
28
|
-
- `obs-stack urls`: prints Grafana, Tempo, Loki, and OTLP endpoints using the current `.env` values.
|
|
27
|
+
## CLI commands
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
- `obs-stack up [...]` – starts the stack (`docker compose up -d` plus any extra args you pass).
|
|
30
|
+
- `obs-stack down [...]` – stops the containers without deleting persistent volumes.
|
|
31
|
+
- `obs-stack reset [...]` – runs `docker compose down -v` so you can start from scratch.
|
|
32
|
+
- `obs-stack status [...]` – shows `docker compose ps` for the stack so you can see container health.
|
|
33
|
+
- `obs-stack logs [...]` – tails all services (`docker compose logs --follow --tail 100 [...]`). Pass service names or additional flags to limit the stream.
|
|
34
|
+
- `obs-stack urls` – prints the Grafana, Tempo, Loki, and OTLP host endpoints using your current `.env` overrides.
|
|
31
35
|
|
|
32
|
-
Each command
|
|
36
|
+
Each command ensures both `docker` and `docker compose` are available before delegating to Compose. Run the CLI from the workspace root via `pnpm --filter @emeryld/obs-stack obs-stack <command>` so it can find the Compose file and configs, or `cd packages/obs-stack` and run the same command if you prefer.
|
|
33
37
|
|
|
34
38
|
## Interactive menu
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
Run the CLI with no arguments to launch the helper menu from a terminal:
|
|
37
41
|
|
|
38
42
|
```bash
|
|
39
|
-
pnpm --filter @
|
|
43
|
+
pnpm --filter @emeryld/obs-stack obs-stack
|
|
40
44
|
```
|
|
41
45
|
|
|
42
|
-
|
|
46
|
+
You can also pass `menu`, `--menu`, `--interactive`, or `-m` to open it explicitly. The menu lets you pick bring-up, stop, reset, status, logs, or URLs by pressing the numbered keys.
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
The legacy `obs-stack-menu` binary is still published (and available via `pnpm --filter @emeryld/obs-stack obs-stack-menu`) for backwards compatibility.
|
|
45
49
|
|
|
46
50
|
## Environment variables
|
|
47
51
|
|
|
48
52
|
| Name | Description | Default |
|
|
49
53
|
| --- | --- | --- |
|
|
50
|
-
| `GRAFANA_PORT` | Host port
|
|
54
|
+
| `GRAFANA_PORT` | Host port forwarded to Grafana | `3000` |
|
|
51
55
|
| `GRAFANA_USER` | Grafana admin user (provisioned) | `admin` |
|
|
52
56
|
| `GRAFANA_PASS` | Grafana admin password (provisioned) | `admin` |
|
|
53
|
-
| `OTEL_OTLP_HTTP_PORT` | Host port forwarded to OTLP HTTP (`4318` inside
|
|
54
|
-
| `OTEL_OTLP_GRPC_PORT` | Host port forwarded to OTLP gRPC (`4317` inside
|
|
57
|
+
| `OTEL_OTLP_HTTP_PORT` | Host port forwarded to OTLP HTTP (`4318` inside the collector) | `4318` |
|
|
58
|
+
| `OTEL_OTLP_GRPC_PORT` | Host port forwarded to OTLP gRPC (`4317` inside the collector) | `4317` |
|
|
55
59
|
| `LOKI_PORT` | Host port forwarded to Loki query API (`3100`) | `3100` |
|
|
56
60
|
| `TEMPO_HTTP_PORT` | Host port forwarded to Tempo query API (`3200`) | `3200` |
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
## Code examples
|
|
62
|
+
Override any of these by editing `packages/obs-stack/.env`, creating another `.env` alongside your working directory, or exporting the variables before running the CLI.
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
## Example workflows
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
### Bringing the stack up, checking status, and watching URLs
|
|
65
67
|
|
|
66
68
|
```bash
|
|
67
|
-
cp packages/
|
|
68
|
-
pnpm
|
|
69
|
-
pnpm
|
|
70
|
-
pnpm
|
|
71
|
-
pnpm
|
|
69
|
+
cp packages/obs-stack/.env.example packages/obs-stack/.env
|
|
70
|
+
pnpm obs-stack up
|
|
71
|
+
pnpm obs-stack status
|
|
72
|
+
pnpm obs-stack urls
|
|
73
|
+
pnpm obs-stack logs # add service names or flags if you need to scope the output
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
`obs-stack urls` prints the host ports for Grafana, Tempo, Loki, and both OTLP
|
|
75
|
-
|
|
76
|
-
### Run a backend against the stack
|
|
77
|
-
|
|
78
|
-
Point your node service at the collector that just started, ensuring telemetry is bootstrapped before requesting anything:
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:${OTEL_OTLP_HTTP_PORT}
|
|
82
|
-
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
|
|
83
|
-
export OTEL_SERVICE_NAME=my-local-api
|
|
84
|
-
export OTEL_RESOURCE_ATTRIBUTES=environment=local
|
|
85
|
-
|
|
86
|
-
NODE_OPTIONS="--require ./node_modules/@rumbl/otel-bootstrap/dist/otel.cjs" \
|
|
87
|
-
node dist/server.js
|
|
88
|
-
```
|
|
76
|
+
`obs-stack urls` prints the host ports for Grafana, Tempo, Loki, and both OTLP endpoints so you can plug them into clients or instrumentation.
|
|
89
77
|
|
|
90
|
-
|
|
78
|
+
### Running a backend against the stack
|
|
91
79
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
- `import "@rumbl/otel-bootstrap";` before anything else in your application entry point, or
|
|
100
|
-
- preload the bootstrap via `NODE_OPTIONS="--require ./node_modules/@rumbl/otel-bootstrap/dist/otel.cjs"` when running `node dist/server.js`.
|
|
101
|
-
2. Point your backend at the collector depending on where it runs:
|
|
102
|
-
- **Shared Docker network** (backend runs via another compose service):
|
|
80
|
+
1. Install `@emeryld/otel-bootstrap` into your backend workspace:
|
|
81
|
+
```bash
|
|
82
|
+
pnpm add @emeryld/otel-bootstrap
|
|
83
|
+
```
|
|
84
|
+
Then either `import "@emeryld/otel-bootstrap";` as early as possible in your entry point or preload it via `NODE_OPTIONS="--require ./node_modules/@emeryld/otel-bootstrap/dist/otel.cjs"` when running node so traces + logs are configured automatically.
|
|
85
|
+
2. Point the backend at the collector depending on its network scope:
|
|
86
|
+
- Backend running inside the Compose network (see the override example below):
|
|
103
87
|
```env
|
|
104
88
|
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
|
|
105
89
|
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
|
|
106
90
|
```
|
|
107
|
-
-
|
|
91
|
+
- Backend running outside the Docker stack (e.g., on your host or in another service):
|
|
108
92
|
```env
|
|
109
93
|
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:${OTEL_OTLP_HTTP_PORT}
|
|
110
94
|
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
|
|
111
95
|
```
|
|
112
|
-
3. Keep `OTEL_SERVICE_NAME` and `OTEL_RESOURCE_ATTRIBUTES` defined
|
|
113
|
-
|
|
96
|
+
3. Keep `OTEL_SERVICE_NAME` and `OTEL_RESOURCE_ATTRIBUTES` defined so traces/logs carry meaningful service metadata.
|
|
97
|
+
|
|
98
|
+
Once telemetry is flowing, Grafana Explore (Tempo + Loki) will start showing traces and logs with matching `trace_id` values.
|
|
114
99
|
|
|
115
|
-
|
|
100
|
+
### Running the backend + stack together
|
|
116
101
|
|
|
117
|
-
|
|
102
|
+
If you want your backend inside the same Docker network as the observability stack (so it can target `otel-collector` by name and share volumes), use the override example:
|
|
118
103
|
|
|
119
104
|
```bash
|
|
120
|
-
cd packages/
|
|
105
|
+
cd packages/obs-stack
|
|
121
106
|
docker compose -f docker-compose.yml -f examples/docker-compose.override.yml up -d
|
|
122
107
|
```
|
|
123
108
|
|
|
124
|
-
Adjust the `backend` service
|
|
109
|
+
Adjust the `backend` service inside `examples/docker-compose.override.yml` to match your build image, ports, and runtime command. The override already makes the service depend on `otel-collector` and sets its OTLP exports to `http://otel-collector:4318`.
|
|
110
|
+
|
|
111
|
+
## Grafana provisioning
|
|
112
|
+
|
|
113
|
+
Grafana relies on the datasources defined in `grafana/provisioning/datasources/datasources.yaml` to wire up Loki and Tempo automatically. You never need to configure the data sources manually—just open Grafana at the URL reported by `obs-stack urls`.
|
|
125
114
|
|
|
126
115
|
## Troubleshooting
|
|
127
116
|
|
|
128
|
-
- **
|
|
129
|
-
- **Grafana
|
|
130
|
-
- **Collector
|
|
131
|
-
- **`docker compose` not
|
|
117
|
+
- **Ports already in use**: edit `packages/obs-stack/.env` (or your local override), then run `pnpm --filter @emeryld/obs-stack obs-stack reset` to recreate the stack with the new settings.
|
|
118
|
+
- **Grafana dashboards missing**: ensure the `grafana/provisioning` folder is mounted (the CLI runs from the package root) and restart Grafana via `obs-stack reset`.
|
|
119
|
+
- **Collector fails to start**: make sure the collector can resolve `tempo` and `loki`. The CLI always runs Compose inside the package directory so no host networking is required.
|
|
120
|
+
- **`docker compose` not on PATH**: install Docker Desktop (Mac/Windows) or Docker Engine with the Compose plugin (Linux) so both `docker` and `docker compose` can run.
|
|
132
121
|
|
|
133
122
|
## Tests
|
|
134
123
|
|
|
135
|
-
The package
|
|
124
|
+
The package ships with a lightweight Node test suite that enforces that the Compose stack is wired up the way the README describes. Run it with:
|
|
136
125
|
|
|
137
126
|
```bash
|
|
138
|
-
pnpm --filter @
|
|
127
|
+
pnpm --filter @emeryld/obs-stack test
|
|
139
128
|
```
|
|
140
129
|
|
|
141
|
-
|
|
130
|
+
The tests check that the services/all volumes exist, host networking is avoided, Grafana data sources point at the local Loki/Tempo, the collector exports to both Loki and Tempo, configs keep 24h retention, and the env example still documents the exposed ports.
|
package/configs/tempo.yaml
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
server:
|
|
2
2
|
http_listen_port: 3200
|
|
3
|
-
grpc_listen_port:
|
|
3
|
+
grpc_listen_port: 9095 # or remove this line entirely to use default
|
|
4
4
|
|
|
5
5
|
distributor:
|
|
6
6
|
receivers:
|
|
7
7
|
otlp:
|
|
8
8
|
protocols:
|
|
9
|
-
grpc:
|
|
9
|
+
grpc:
|
|
10
|
+
endpoint: 0.0.0.0:4317
|
|
10
11
|
|
|
11
12
|
storage:
|
|
12
13
|
trace:
|
package/docker-compose.yml
CHANGED
|
@@ -9,7 +9,7 @@ services:
|
|
|
9
9
|
GF_AUTH_ANONYMOUS_ENABLED: "true"
|
|
10
10
|
volumes:
|
|
11
11
|
- grafana-data:/var/lib/grafana
|
|
12
|
-
- ./grafana:/etc/grafana/provisioning
|
|
12
|
+
- ./grafana/provisioning:/etc/grafana/provisioning
|
|
13
13
|
depends_on:
|
|
14
14
|
- loki
|
|
15
15
|
- tempo
|
|
@@ -17,6 +17,7 @@ services:
|
|
|
17
17
|
|
|
18
18
|
tempo:
|
|
19
19
|
image: grafana/tempo:2.9.0
|
|
20
|
+
user: "0:0"
|
|
20
21
|
ports:
|
|
21
22
|
- "${TEMPO_HTTP_PORT}:3200"
|
|
22
23
|
command:
|