The Problem
Developers need a step‑by‑step playground for adding metrics, logs, and traces to Kubernetes workloads. The repo supplies ready‑made manifests, Dockerfiles and small Node‑/Go services that demonstrate each observability layer, but the material is not packaged for repeatable CI/CD or safe reuse.
What This Does
The repository is split into daily labs. Day 4 contains two Node.js services (day-4/application/service-a and service-b) that expose custom Prometheus metrics via prom-client and ship with Dockerfiles. Day 7 provides two Go micro‑services (microservice-a and microservice-b) that are instrumented with OpenTelemetry and run via Docker‑Compose. Supporting Kubernetes manifests live under day‑4/kubernetes-manifest and day‑7/k8s-manifests. Documentation files (README.md, metrics_instrumentation_analysis.md, etc.) explain the observability concepts for each day.
How It Is Wired
Execution starts at the language‑specific entry points:
- Node.js services –
day-4/application/service-a/index.jsandservice-b/index.jscreate an HTTP server, register asimulateAsyncTaskfunction and alogginghelper, then expose/metrics. Both import a localtracing.jsmodule that configures OpenTelemetry tracing. The internal call graph shows eachindex.jsimports its owntracing.js(1 import edge per service) and calls no other internal functions, giving an instability of 1 for the index files and 0 for the tracing modules.
- Go services –
day-7/microservice-a/main.goandmicroservice-b/main.gobootstrap an OpenTelemetry collector using the YAML atotel-collector-config.yaml, start an HTTP server, and perform a single outbound HTTP request (the only function that reaches outside the repo). Each service is built by its Dockerfile (day-7/microservice-a/dockerfile,microservice-b/dockerfile) and orchestrated withdocker-compose.yml.
All manifests reference the Docker images built from these Dockerfiles, but no CI pipeline validates the builds. The only cross‑service interaction is the shared tracing configuration, which is duplicated verbatim in both tracing.js files (see the high‑severity duplicated‑code finding).
How To Use It
# Clone the repo
git clone https://github.com/moses-y/observability-zero-to-hero
cd observability-zero-to-hero
# Day 4 – Node services
cd day-4/application/service-a
npm ci # installs from package-lock.json
docker build -t svc-a .
docker run -p 8080:8080 svc-a
# Day 7 – Go services (Docker‑Compose)
cd ../../day-7/microservice-a
docker compose up -d # uses docker-compose.yml
Configuration – Both Node services read no external env vars; the Go services load environment variables from the tracked .env files (these should be removed per the high‑severity secret issue). The OpenTelemetry collector config is in otel-collector-config.yaml.
Running – Access /metrics on the Node containers (http://localhost:8080/metrics). The Go services expose their own HTTP endpoints as defined in docker-compose.yml.
Real‑World Use
A SRE team could fork the repo to spin up a disposable observability lab: run the Dockerfiles to generate instrumented services, apply the Kubernetes manifests to a dev cluster, and experiment with Prometheus alerts, Grafana dashboards, and Jaeger traces without impacting production workloads.
Code Health & Issues
- HIGH – Duplicated code blocks –
day-4/application/service-a/tracing.js,service-b/tracing.js,day-4/test.sh,day-7/microservice-a/test.sh, etc., repeat 140 six‑line snippets. Fix: extract shared helpers into a common module. - HIGH – No LICENSE – repository root lacks a license file. Fix: add MIT or Apache‑2.0.
- HIGH – Missing build gate – Dockerfiles (e.g.,
day-4/application/service-a/Dockerfile) are not tied to any CI workflow. Fix: add a GitHub Actions workflow that builds the image and validates manifests. - HIGH – Committed
.env– secrets inday-7/microservice-a/.envandmicroservice-b/.env. Fix: remove from git, add to.gitignore, rotate credentials, provide a template. - MEDIUM – No Dependabot/Renovate – 4 manifest files exist but no update bot. Fix: add
.github/dependabot.yml. - MEDIUM – Base image not pinned – Dockerfile uses
node:18-alpinewithout digest. Fix: referencenode:18-alpine@sha256:<digest>. - MEDIUM – No pre‑commit secret scan – No gate to catch secret leaks. Fix: add a pre‑commit hook with a secret‑scanner.
- MEDIUM – Container runs as root – Dockerfile lacks a non‑root
USER. Fix: create an unprivileged user and switch to it. - SDLC – No CI pipeline –
.github/absent. - Tests – Present – 4 test files exist but are not hooked into any CI step.
The Bottom Line
The repo delivers a hands‑on, day‑by‑day guide to instrumenting Kubernetes workloads with Prometheus, Grafana, EFK, Jaeger and OpenTelemetry. It is useful for learning and prototyping, but production‑grade adoption requires adding a license, removing committed secrets, pinning base images, and introducing CI/CD gates to enforce builds and security checks. Engineers ready to refactor duplicated tracing code and integrate automated pipelines will find the material a solid foundation.