This repository contains a fully containerized, multi-tenant observability stack. It demonstrates how to collect logs, metrics, and traces from isolated application workloads and route them securely to dedicated multi-tenant backends using Grafana Alloy as a high-performance telemetry pipeline.
The architecture is divided into three distinct layers:
- Telemetry Generators (Applications): Two Python microservices instrumented with OpenTelemetry SDKs. They export telemetry in the OTLP format.
- Routing Agent (Collector): Grafana Alloy receives the incoming OTLP traffic. It reads the service.namespace resource attribute and injects the corresponding tenant ID into the HTTP header.
- Multi-Tenant Storage (Backends): Mimir (metrics), Loki (logs), and Tempo (traces) enforce tenant isolation using the X-Scope-OrgID HTTP header.
. ├── apps/ │ ├── backend/ │ │ ├── app.py # Simulates batch-processor telemetry │ │ ├── Dockerfile # Lowercase "D" for BuildKit compatibility │ │ └── requirements.txt # OpenTelemetry Python SDK libraries │ └── frontend/ │ ├── app.py # Simulates frontend-api HTTP telemetry │ ├── Dockerfile # Container build definition │ └── requirements.txt # Pinned dependency versions ├── config/ │ ├── alloy.config # Grafana Alloy processing pipeline │ ├── loki.yaml # Loki local storage & multi-tenancy rules │ ├── mimir.yaml # Mimir TSDB & active tenant rules │ ├── tempo.yaml # Tempo OTLP receiver endpoints & trace blocks │ └── grafana-datasources.yaml # Automated datasource provisioning └── docker-compose.yaml # Complete 7-service orchestration blueprint
Isolation boundaries are defined in the configurations through the following configurations:
- Mimir & Tempo: Activated with multitenancy_enabled: true
- Loki: Activated with auth_enabled: true
With these flags enabled, any request arriving at the storage gateways must include the X-Scope-OrgID header, or it will be rejected.
- Docker Desktop running on macOS/Linux/Windows
- Terminal CLI
Compile the instrumented application containers:
docker compose build team-frontend team-backend
Pull the remaining pipeline, storage, and visualization images:
docker compose pull --ignore-buildable
Launch the platform in detached mode:
docker compose up -d
- Grafana: http://localhost:3000 (Visualize isolated dashboards)
- Grafana Alloy UI: http://localhost:12345 (Inspect processing pipeline components)
To stop the containers and free up ports without deleting your collected telemetry volumes, run:
docker compose down
To completely remove the stack along with all stored metrics, logs, and traces, run:
docker compose down -v
Built with 💙 as part of the Multi-Tenant Observability with Alloy challenge on nextwork.ai.