Overview
Overview
observability is a foundational concept in modern software development and DevOps.
What Is an Observability Stack?
An observability stack is a set of tools and practices that allow you to understand what's happening inside your application or system, especially when things go wrong.
It helps you answer:
- βWhy is my app slow?β
- βWhy did this service fail?β
- βWhat caused this spike in traffic?β
π Core Pillars of Observability
There are three key types of data in an observability stack, often called the 3 Pillars:
Pillar | Description | Example Tools |
---|---|---|
Metrics | Numeric time-series data about your system (e.g., CPU usage, requests/sec) | Prometheus, InfluxDB |
Logs | Textual records of events (e.g., error messages, request logs) | Loki, ELK (Elasticsearch, Logstash, Kibana), Fluentd |
Traces | End-to-end request flows through a system (e.g., what microservices were called and how long they took) | Jaeger, Zipkin, OpenTelemetry |
π§± Typical Observability Stack
Hereβs a commonly used open-source observability stack:
Layer | Tool | Role |
---|---|---|
Metrics | Prometheus | Collects & stores metrics |
Visualization | Grafana | Dashboards & alerts using Prometheus |
Logs | Loki | Stores and queries logs |
Tracing | Jaeger or Tempo | Tracks request paths across services |
Instrumentation | OpenTelemetry | Common API for collecting data |
π§ Why Is It Useful?
- Detect outages or slowdowns early
- Pinpoint bottlenecks and errors
- Provide alerts to engineers
- Improve incident response time
- Help with root cause analysis
π FastAPI + Observability Stack (Example)
For your case with FastAPI:
- Metrics: Use
prometheus_client
to expose/metrics
- Prometheus: Scrapes that endpoint
- Grafana: Visualizes metrics
- (Optional) Add logs (with Loki) and tracing (with OpenTelemetry)
Setting up Observability Stack for FastAPI
Here's a basic Observability Stack for a FastAPI app using:
- π‘ FastAPI
- π΅ Prometheus (metrics collector)
- π’ Grafana (dashboard/visualizer)
Later, you can extend it with logging (e.g. Loki
) and tracing (e.g. Jaeger
).
π³ Docker Compose Setup
Here's a minimal docker-compose.yml
for:
- Your FastAPI app
- Prometheus
- Grafana
π Folder Structure
my-observability-stack/
β
βββ docker-compose.yml
βββ app/
β βββ main.py
β βββ requirements.txt
βββ prometheus/
β βββ prometheus.yml
π¦ docker-compose.yml
version: "3.8"
services:
fastapi:
build: ./app
ports:
- "8000:8000"
networks:
- monitor-net
prometheus:
image: prom/prometheus
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
networks:
- monitor-net
grafana:
image: grafana/grafana
ports:
- "3000:3000"
networks:
- monitor-net
networks:
monitor-net:
π§ prometheus/prometheus.yml
global:
scrape_interval: 5s
scrape_configs:
- job_name: "fastapi"
static_configs:
- targets: ["fastapi:8000"]
π app/main.py
from fastapi import FastAPI, Request
from prometheus_client import start_http_server, Counter, generate_latest
from prometheus_client import CONTENT_TYPE_LATEST
from starlette.responses import Response
import uvicorn
REQUEST_COUNTER = Counter("http_requests_total", "Total HTTP Requests")
app = FastAPI()
@app.middleware("http")
async def add_metrics_middleware(request: Request, call_next):
REQUEST_COUNTER.inc()
response = await call_next(request)
return response
@app.get("/")
def read_root():
return {"message": "Hello from FastAPI!"}
@app.get("/metrics")
def metrics():
return Response(generate_latest(), media_type=CONTENT_TYPE_LATEST)
π¦ app/requirements.txt
πββοΈ Build and Run
From the project root:
π Access URLs
Tool | URL |
---|---|
FastAPI | http://localhost:8000 |
Metrics | http://localhost:8000/metrics |
Prometheus | http://localhost:9090 |
Grafana | http://localhost:3000 |
Grafana login:
admin / admin
(change after login)
π In Grafana
-
Go to
http://localhost:3000
-
Add data source:
- Type: Prometheus
- URL:
http://prometheus:9090
-
Create a dashboard with a panel.
- Use query:
http_requests_total
- Use query:
β Next Steps
Once you get this working:
- Add Loki for logging
- Add Tempo or Jaeger for tracing
- Use OpenTelemetry for standardized instrumentation
Would you like me to add logging (Loki) or tracing (Jaeger) next?
text-based, flowchart-style diagram VISULIZATION
Docker Compose Observability Stack with:
- FastAPI App
- Prometheus
- Grafana
+----------------------------+
| FastAPI Application |
| - Runs on port 8000 |
| - Exposes /metrics |
+----------------------------+
|
V
+----------------------------+
| Prometheus |
| - Scrapes /metrics |
| - Stores time-series data |
| - Uses prometheus.yml |
+----------------------------+
|
V
+----------------------------+
| Grafana |
| - Connects to Prometheus |
| - Visualizes metrics |
| - Dashboards & Alerts |
+----------------------------+
|
V
+----------------------------+
| You (User) |
| - View metrics in browser |
| - Analyze, debug, monitor |
+----------------------------+
π Docker Compose Networking
All services are on the same Docker network, so they can reach each other by container name:
- Prometheus can scrape FastAPI via
http://fastapi:8000/metrics
- Grafana connects to Prometheus via
http://prometheus:9090
π¦ Updated Docker Compose Diagram (Text-Based)
+----------------------------+
| FastAPI Application |
| - Exposes: |
| β’ /metrics (Prometheus)|
| β’ Logs (Loki) |
| β’ Traces (Jaeger) |
+----------------------------+
| | |
| | |
V V V
+-----------+ +----------+ +----------+
| Prometheus| | Loki | | Jaeger |
| Metrics | | Logs | | Traces |
+-----------+ +----------+ +----------+
\ | /
\ | /
V V V
+------------------------+
| Grafana |
| - Dashboards (All Data)|
+------------------------+
|
V
+------------------+
| You (Developer)|
+------------------+
π³ Next Step: Add Loki and Jaeger to docker-compose.yml
Would you like me to:
- π§ Give you the full updated
docker-compose.yml
with Loki & Jaeger? - π Provide file structure + config files (e.g. for Loki and Promtail)?
- β Or just a minimal Loki & Jaeger config added to your existing stack?
Let me know your preference, and Iβll tailor it for you.