A production-style distributed system demonstrating end-to-end observability using OpenTelemetry across HTTP services, Kafka messaging, and PostgreSQL, with trace propagation, failure simulation, and real distributed tracing visualization using Jaeger.
This project shows how modern cloud-native systems are instrumented and debugged using OpenTelemetry.
Modern distributed systems are hard to debug because requests travel across multiple services and asynchronous systems like message queues and databases.
This project demonstrates:
- Distributed tracing across services
- Context propagation over Kafka
- Failure simulation and debugging using traces
- OpenTelemetry Collector pipeline setup
- Real-world tracing visualization with Jaeger
Project flow:
Client -> HTTP API -> Kafka -> Consumer -> Postgres DB- HTTP Auto instumentation
- Mannual Kafka Instrumentation
- Context Propagation as request flows through the API to Kafka and DB.
- Baggage Propagation for deliberate failuer injection
- OpenTelemetry Collector pipeline setup
- Jaeger visualization
- Backend Service - Go
- Event streaming - Kafka
- Database - PostgreSQL
- Instrumentation - OpenTelemetry Go SDK
- Trace visualization - Jaeger
- Orchestrating the application - Docker
- Clone the repo:
git clone https://github.com/yaten2302/otel-playground
cd otel-playground- Start infra
docker compose up -dThis starts:
- Kafka
- PostgreSQL
- Jaeger
- OpenTelemetry Collector
- Create
.envfile and add:
DATABASE_URL=postgres://<user>:<password>@localhost:5432/<database_name>?sslmode=disable- Create the Postgres table using the following command:
CREATE TABLE orders (
order_id TEXT PRIMARY KEY,
customer_id TEXT NOT NULL,
amount INT NOT NULL,
created_at TIMESTAMP NOT NULL
);- Start the application:
go run .Server starts at localhost:8000
Send a request - curl -X POST "http://localhost:8000/orders?customer_id=123&amount=100"
- View traces:
Open Jaeger UI - http://localhost:16686
Select service - orders-service
The API allows injecting failures to observe how traces help debugging.
-
Normal flow -
curl -X POST "http://localhost:8000/orders?customer_id=1&amount=100" -
Break Context Propagation -
curl -X POST "http://localhost:8000/orders?customer_id=1&amount=100&fail=context"
There are a lot of failures present in failures.go file, select and and add ?fail={fail_type}.
Contributions and improvements are always welcome :)
