Set up comprehensive monitoring for FastAPI applications using Prometheus metrics collection and Grafana dashboards. Configure custom metrics, alerting rules, and real-time visualization for API performance tracking.
Prerequisites
- Python 3.8+
- Root or sudo access
- 4GB RAM minimum
- Basic FastAPI knowledge
What this solves
FastAPI applications in production need comprehensive monitoring to track performance, errors, and resource usage. This tutorial sets up Prometheus to collect metrics from your FastAPI app and Grafana to visualize them with custom dashboards and alerts.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you get the latest versions.
sudo apt update && sudo apt upgrade -y
Create a monitoring user
Create a dedicated user for monitoring services to enhance security.
sudo useradd --no-create-home --shell /bin/false monitoring
sudo mkdir -p /etc/prometheus /etc/grafana /var/lib/prometheus /var/lib/grafana
sudo chown monitoring:monitoring /etc/prometheus /var/lib/prometheus
sudo chown monitoring:monitoring /etc/grafana /var/lib/grafana
Install Python dependencies for FastAPI metrics
Install the required Python packages to add Prometheus metrics to your FastAPI application.
pip3 install prometheus-client prometheus-fastapi-instrumentator uvicorn[standard]
Configure FastAPI application with metrics
Create a sample FastAPI application with built-in Prometheus metrics endpoint.
from fastapi import FastAPI, HTTPException
from prometheus_fastapi_instrumentator import Instrumentator
from prometheus_client import Counter, Histogram, generate_latest, CONTENT_TYPE_LATEST
import time
import random
app = FastAPI(title="FastAPI Monitoring Demo")
Initialize Prometheus instrumentator
instrumentator = Instrumentator(
should_group_status_codes=False,
should_ignore_untemplated=True,
should_instrument_requests_inprogress=True,
excluded_handlers=["/metrics"],
env_var_name="ENABLE_METRICS",
inprogress_name="fastapi_inprogress",
inprogress_labels=True,
)
Custom metrics
REQUEST_COUNT = Counter(
'fastapi_requests_total',
'Total requests',
['method', 'endpoint', 'status_code']
)
REQUEST_DURATION = Histogram(
'fastapi_request_duration_seconds',
'Request duration',
['method', 'endpoint']
)
ERROR_COUNT = Counter(
'fastapi_errors_total',
'Total errors',
['endpoint', 'error_type']
)
Instrument the app
instrumentator.instrument(app).expose(app)
@app.get("/")
async def root():
REQUEST_COUNT.labels(method="GET", endpoint="/", status_code="200").inc()
return {"message": "Hello World", "status": "healthy"}
@app.get("/health")
async def health_check():
REQUEST_COUNT.labels(method="GET", endpoint="/health", status_code="200").inc()
return {"status": "ok", "timestamp": time.time()}
@app.get("/slow")
async def slow_endpoint():
start_time = time.time()
# Simulate slow processing
await asyncio.sleep(random.uniform(1, 3))
duration = time.time() - start_time
REQUEST_DURATION.labels(method="GET", endpoint="/slow").observe(duration)
REQUEST_COUNT.labels(method="GET", endpoint="/slow", status_code="200").inc()
return {"message": "Slow response", "duration": duration}
@app.get("/error")
async def error_endpoint():
if random.choice([True, False]):
ERROR_COUNT.labels(endpoint="/error", error_type="random_error").inc()
REQUEST_COUNT.labels(method="GET", endpoint="/error", status_code="500").inc()
raise HTTPException(status_code=500, detail="Random error occurred")
REQUEST_COUNT.labels(method="GET", endpoint="/error", status_code="200").inc()
return {"message": "No error this time"}
Create FastAPI systemd service
Set up the FastAPI application as a systemd service for automatic startup and management.
[Unit]
Description=FastAPI Application
After=network.target
[Service]
Type=exec
User=monitoring
Group=monitoring
WorkingDirectory=/opt/fastapi-app
ExecStart=/usr/bin/python3 -m uvicorn main:app --host 0.0.0.0 --port 8000
Restart=always
RestartSec=3
Environment=ENABLE_METRICS=1
[Install]
WantedBy=multi-user.target
Download and install Prometheus
Download the latest Prometheus binary and set up the installation.
cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v2.48.0/prometheus-2.48.0.linux-amd64.tar.gz
tar xzf prometheus-2.48.0.linux-amd64.tar.gz
sudo cp prometheus-2.48.0.linux-amd64/prometheus /usr/local/bin/
sudo cp prometheus-2.48.0.linux-amd64/promtool /usr/local/bin/
sudo chown monitoring:monitoring /usr/local/bin/prometheus /usr/local/bin/promtool
rm -rf prometheus-2.48.0.linux-amd64*
Configure Prometheus
Create the Prometheus configuration file with scraping targets for your FastAPI application.
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "/etc/prometheus/fastapi_rules.yml"
alerting:
alertmanagers:
- static_configs:
- targets: []
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'fastapi'
static_configs:
- targets: ['localhost:8000']
metrics_path: '/metrics'
scrape_interval: 5s
scrape_timeout: 5s
- job_name: 'node-exporter'
static_configs:
- targets: ['localhost:9100']
scrape_interval: 15s
Create Prometheus alerting rules
Set up alerting rules for FastAPI application monitoring.
groups:
- name: fastapi_alerts
rules:
- alert: FastAPIHighErrorRate
expr: rate(fastapi_errors_total[5m]) > 0.1
for: 2m
labels:
severity: warning
annotations:
summary: "High error rate detected in FastAPI application"
description: "Error rate is {{ $value }} errors per second"
- alert: FastAPIHighLatency
expr: histogram_quantile(0.95, rate(fastapi_request_duration_seconds_bucket[5m])) > 2
for: 5m
labels:
severity: warning
annotations:
summary: "High latency detected in FastAPI application"
description: "95th percentile latency is {{ $value }} seconds"
- alert: FastAPIDown
expr: up{job="fastapi"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "FastAPI application is down"
description: "FastAPI application has been down for more than 1 minute"
- alert: FastAPIHighRequestRate
expr: rate(fastapi_requests_total[5m]) > 100
for: 2m
labels:
severity: info
annotations:
summary: "High request rate detected"
description: "Request rate is {{ $value }} requests per second"
Install Node Exporter
Install Node Exporter to collect system metrics alongside application metrics.
cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
tar xzf node_exporter-1.7.0.linux-amd64.tar.gz
sudo cp node_exporter-1.7.0.linux-amd64/node_exporter /usr/local/bin/
sudo chown monitoring:monitoring /usr/local/bin/node_exporter
rm -rf node_exporter-1.7.0.linux-amd64*
Create Node Exporter systemd service
Set up Node Exporter as a systemd service.
[Unit]
Description=Node Exporter
After=network.target
[Service]
Type=simple
User=monitoring
Group=monitoring
ExecStart=/usr/local/bin/node_exporter
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Create Prometheus systemd service
Set up Prometheus as a systemd service with proper configuration.
[Unit]
Description=Prometheus
After=network.target
[Service]
Type=simple
User=monitoring
Group=monitoring
ExecStart=/usr/local/bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries \
--web.listen-address=0.0.0.0:9090 \
--web.enable-lifecycle
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Install Grafana
Install Grafana for creating monitoring dashboards and visualizations.
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install -y grafana
Configure Grafana
Set up Grafana configuration with security settings and data source configuration.
[server]
http_port = 3000
domain = example.com
root_url = http://example.com:3000
[security]
admin_user = admin
admin_password = secure_password_here
secret_key = change_this_secret_key
disable_gravatar = true
[users]
allow_sign_up = false
allow_org_create = false
[auth.anonymous]
enabled = false
[database]
type = sqlite3
path = grafana.db
[alerting]
enabled = true
Set proper file permissions
Ensure all files have correct ownership and permissions for security.
sudo chown -R monitoring:monitoring /etc/prometheus /var/lib/prometheus
sudo chown -R grafana:grafana /etc/grafana /var/lib/grafana
sudo chmod -R 755 /etc/prometheus
sudo chmod 644 /etc/prometheus/prometheus.yml /etc/prometheus/fastapi_rules.yml
sudo chmod 755 /opt/fastapi-app
sudo chmod 644 /opt/fastapi-app/main.py
Start and enable all services
Start all monitoring services and enable them to start automatically on boot.
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
sudo systemctl enable --now prometheus
sudo systemctl enable --now grafana-server
sudo systemctl enable --now fastapi-app
Configure firewall rules
Open the necessary ports for Prometheus, Grafana, and your FastAPI application.
sudo ufw allow 3000/tcp comment 'Grafana'
sudo ufw allow 9090/tcp comment 'Prometheus'
sudo ufw allow 8000/tcp comment 'FastAPI'
sudo ufw --force enable
Create Grafana dashboard JSON
Create a comprehensive dashboard configuration for FastAPI monitoring.
{
"dashboard": {
"id": null,
"title": "FastAPI Monitoring",
"tags": ["fastapi", "monitoring"],
"timezone": "browser",
"panels": [
{
"id": 1,
"title": "Request Rate",
"type": "stat",
"targets": [
{
"expr": "rate(fastapi_requests_total[5m])",
"legendFormat": "Requests/sec"
}
],
"gridPos": {"h": 8, "w": 6, "x": 0, "y": 0}
},
{
"id": 2,
"title": "Error Rate",
"type": "stat",
"targets": [
{
"expr": "rate(fastapi_errors_total[5m])",
"legendFormat": "Errors/sec"
}
],
"gridPos": {"h": 8, "w": 6, "x": 6, "y": 0}
},
{
"id": 3,
"title": "Response Time (95th percentile)",
"type": "stat",
"targets": [
{
"expr": "histogram_quantile(0.95, rate(fastapi_request_duration_seconds_bucket[5m]))",
"legendFormat": "95th percentile"
}
],
"gridPos": {"h": 8, "w": 6, "x": 12, "y": 0}
},
{
"id": 4,
"title": "Active Requests",
"type": "stat",
"targets": [
{
"expr": "fastapi_inprogress",
"legendFormat": "In Progress"
}
],
"gridPos": {"h": 8, "w": 6, "x": 18, "y": 0}
}
],
"time": {
"from": "now-1h",
"to": "now"
},
"refresh": "5s"
}
}
Configure Grafana dashboards
Access Grafana web interface
Open your browser and navigate to Grafana to complete the setup.
http://your_server_ip:3000
Login with admin/secure_password_here (or the password you set in the configuration).
Add Prometheus data source
Configure Grafana to use Prometheus as a data source for metrics collection.
- Go to Configuration > Data Sources
- Click "Add data source"
- Select "Prometheus"
- Set URL to
http://localhost:9090 - Click "Save & Test"
Import FastAPI dashboard
Import the custom dashboard for comprehensive FastAPI monitoring.
curl -X POST \
http://admin:secure_password_here@localhost:3000/api/dashboards/db \
-H 'Content-Type: application/json' \
-d @/tmp/fastapi-dashboard.json
Verify your setup
# Check all services are running
sudo systemctl status prometheus node_exporter grafana-server fastapi-app
Test FastAPI metrics endpoint
curl http://localhost:8000/metrics
Test Prometheus targets
curl http://localhost:9090/api/v1/targets
Generate some test traffic
for i in {1..10}; do curl http://localhost:8000/ && curl http://localhost:8000/slow; done
Check Prometheus is scraping metrics
curl "http://localhost:9090/api/v1/query?query=fastapi_requests_total"
Verify Grafana is accessible
curl -I http://localhost:3000
Set up alerting
Configure Grafana alerting
Set up alert notifications for critical FastAPI metrics.
In Grafana:
- Go to Alerting > Notification channels
- Add an email notification channel
- Create alert rules for high error rates and latency
- Test the notification system
Test alerting rules
Verify that Prometheus alerting rules are working correctly.
# Check if rules are loaded
curl http://localhost:9090/api/v1/rules
Trigger error alerts by calling error endpoint
for i in {1..20}; do curl http://localhost:8000/error; done
Check active alerts
curl http://localhost:9090/api/v1/alerts
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Prometheus can't scrape FastAPI metrics | FastAPI app not exposing /metrics endpoint | Check Instrumentator configuration and restart FastAPI service |
| Grafana can't connect to Prometheus | Prometheus not running or firewall blocking | sudo systemctl status prometheus and check port 9090 |
| No metrics appearing in Grafana | Data source configuration incorrect | Verify Prometheus URL is http://localhost:9090 |
| Permission denied errors | Incorrect file ownership | sudo chown -R monitoring:monitoring /var/lib/prometheus |
| FastAPI service won't start | Port already in use or missing dependencies | Check port 8000 availability and install Python packages |
| Alerts not firing | Alert rules syntax error | sudo /usr/local/bin/promtool check rules /etc/prometheus/fastapi_rules.yml |
Next steps
- Monitor Node.js applications with Prometheus and Grafana
- Deploy FastAPI applications with Docker Compose
- Configure FastAPI database connection pooling with PostgreSQL
- Set up Prometheus and Grafana monitoring stack with Docker Compose
- Implement FastAPI JWT authentication and OAuth2 security
- Configure FastAPI production logging with ELK stack
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly NC='\033[0m'
# Configuration
readonly PROMETHEUS_VERSION="2.47.2"
readonly GRAFANA_VERSION="10.2.0"
readonly MONITORING_USER="monitoring"
readonly FASTAPI_DIR="/opt/fastapi-app"
# Usage function
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -h, --help Show this help message"
echo " --no-firewall Skip firewall configuration"
exit 1
}
# Parse arguments
CONFIGURE_FIREWALL=true
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help) usage ;;
--no-firewall) CONFIGURE_FIREWALL=false; shift ;;
*) echo "Unknown option: $1"; usage ;;
esac
done
# Logging functions
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Cleanup function
cleanup() {
log_error "Installation failed. Cleaning up..."
systemctl stop prometheus grafana-server fastapi-app 2>/dev/null || true
systemctl disable prometheus grafana-server fastapi-app 2>/dev/null || true
userdel -r $MONITORING_USER 2>/dev/null || true
rm -rf /etc/prometheus /etc/grafana /var/lib/prometheus /var/lib/grafana $FASTAPI_DIR
rm -f /etc/systemd/system/{prometheus,grafana-server,fastapi-app}.service
}
trap cleanup ERR
# Check prerequisites
check_prerequisites() {
if [[ $EUID -ne 0 ]]; then
log_error "This script must be run as root"
exit 1
fi
if ! command -v curl &> /dev/null; then
log_error "curl is required but not installed"
exit 1
fi
}
# Detect distribution
detect_distro() {
if [[ ! -f /etc/os-release ]]; then
log_error "Cannot detect distribution"
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update && apt upgrade -y"
PKG_INSTALL="apt install -y"
PYTHON_PKG="python3-pip"
FIREWALL_CMD="ufw"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
PYTHON_PKG="python3-pip"
FIREWALL_CMD="firewall-cmd"
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
PYTHON_PKG="python3-pip"
FIREWALL_CMD="firewall-cmd"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
log_info "Detected distribution: $ID"
}
# Update system packages
update_system() {
echo "[1/10] Updating system packages..."
$PKG_UPDATE
$PKG_INSTALL curl wget tar $PYTHON_PKG
}
# Create monitoring user
create_monitoring_user() {
echo "[2/10] Creating monitoring user and directories..."
if ! id $MONITORING_USER &>/dev/null; then
useradd --no-create-home --shell /bin/false $MONITORING_USER
fi
mkdir -p /etc/prometheus /etc/grafana /var/lib/prometheus /var/lib/grafana $FASTAPI_DIR
chown $MONITORING_USER:$MONITORING_USER /etc/prometheus /var/lib/prometheus
chown $MONITORING_USER:$MONITORING_USER /etc/grafana /var/lib/grafana
chown $MONITORING_USER:$MONITORING_USER $FASTAPI_DIR
}
# Install Python dependencies
install_python_deps() {
echo "[3/10] Installing Python dependencies..."
pip3 install prometheus-client prometheus-fastapi-instrumentator uvicorn[standard] fastapi
}
# Create FastAPI application
create_fastapi_app() {
echo "[4/10] Creating FastAPI application..."
cat > $FASTAPI_DIR/main.py << 'EOF'
from fastapi import FastAPI, HTTPException
from prometheus_fastapi_instrumentator import Instrumentator
from prometheus_client import Counter, Histogram
import time
import random
import asyncio
app = FastAPI(title="FastAPI Monitoring Demo")
instrumentator = Instrumentator(
should_group_status_codes=False,
should_ignore_untemplated=True,
should_instrument_requests_inprogress=True,
excluded_handlers=["/metrics"],
)
REQUEST_COUNT = Counter('fastapi_requests_total', 'Total requests', ['method', 'endpoint', 'status_code'])
REQUEST_DURATION = Histogram('fastapi_request_duration_seconds', 'Request duration', ['method', 'endpoint'])
ERROR_COUNT = Counter('fastapi_errors_total', 'Total errors', ['endpoint', 'error_type'])
instrumentator.instrument(app).expose(app)
@app.get("/")
async def root():
REQUEST_COUNT.labels(method="GET", endpoint="/", status_code="200").inc()
return {"message": "Hello World", "status": "healthy"}
@app.get("/health")
async def health_check():
REQUEST_COUNT.labels(method="GET", endpoint="/health", status_code="200").inc()
return {"status": "ok", "timestamp": time.time()}
@app.get("/slow")
async def slow_endpoint():
start_time = time.time()
await asyncio.sleep(random.uniform(1, 3))
duration = time.time() - start_time
REQUEST_DURATION.labels(method="GET", endpoint="/slow").observe(duration)
REQUEST_COUNT.labels(method="GET", endpoint="/slow", status_code="200").inc()
return {"message": "Slow response", "duration": duration}
@app.get("/error")
async def error_endpoint():
if random.choice([True, False]):
ERROR_COUNT.labels(endpoint="/error", error_type="random_error").inc()
REQUEST_COUNT.labels(method="GET", endpoint="/error", status_code="500").inc()
raise HTTPException(status_code=500, detail="Random error occurred")
REQUEST_COUNT.labels(method="GET", endpoint="/error", status_code="200").inc()
return {"message": "No error this time"}
EOF
chown $MONITORING_USER:$MONITORING_USER $FASTAPI_DIR/main.py
}
# Create FastAPI systemd service
create_fastapi_service() {
echo "[5/10] Creating FastAPI systemd service..."
cat > /etc/systemd/system/fastapi-app.service << EOF
[Unit]
Description=FastAPI Application
After=network.target
[Service]
Type=exec
User=$MONITORING_USER
Group=$MONITORING_USER
WorkingDirectory=$FASTAPI_DIR
ExecStart=/usr/bin/python3 -m uvicorn main:app --host 0.0.0.0 --port 8000
Restart=always
RestartSec=3
Environment=ENABLE_METRICS=1
[Install]
WantedBy=multi-user.target
EOF
}
# Install Prometheus
install_prometheus() {
echo "[6/10] Installing Prometheus..."
cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v${PROMETHEUS_VERSION}/prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz
tar xzf prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz
cp prometheus-${PROMETHEUS_VERSION}.linux-amd64/{prometheus,promtool} /usr/local/bin/
chown $MONITORING_USER:$MONITORING_USER /usr/local/bin/{prometheus,promtool}
chmod 755 /usr/local/bin/{prometheus,promtool}
cat > /etc/prometheus/prometheus.yml << EOF
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'fastapi'
static_configs:
- targets: ['localhost:8000']
metrics_path: '/metrics'
scrape_interval: 5s
EOF
chown $MONITORING_USER:$MONITORING_USER /etc/prometheus/prometheus.yml
cat > /etc/systemd/system/prometheus.service << EOF
[Unit]
Description=Prometheus
After=network.target
[Service]
Type=simple
User=$MONITORING_USER
Group=$MONITORING_USER
ExecStart=/usr/local/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus/ --web.console.templates=/etc/prometheus/consoles --web.console.libraries=/etc/prometheus/console_libraries --web.listen-address=0.0.0.0:9090
Restart=always
[Install]
WantedBy=multi-user.target
EOF
}
# Install Grafana
install_grafana() {
echo "[7/10] Installing Grafana..."
case "$PKG_MGR" in
apt)
wget -q -O - https://packages.grafana.com/gpg.key | apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" > /etc/apt/sources.list.d/grafana.list
apt update
$PKG_INSTALL grafana
;;
dnf|yum)
cat > /etc/yum.repos.d/grafana.repo << EOF
[grafana]
name=grafana
baseurl=https://packages.grafana.com/oss/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packages.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
EOF
$PKG_INSTALL grafana
;;
esac
}
# Configure firewall
configure_firewall() {
if [[ "$CONFIGURE_FIREWALL" == "false" ]]; then
log_warn "Skipping firewall configuration"
return
fi
echo "[8/10] Configuring firewall..."
case "$FIREWALL_CMD" in
ufw)
if command -v ufw &> /dev/null; then
ufw allow 8000/tcp comment "FastAPI"
ufw allow 9090/tcp comment "Prometheus"
ufw allow 3000/tcp comment "Grafana"
fi
;;
firewall-cmd)
if systemctl is-active --quiet firewalld; then
firewall-cmd --permanent --add-port=8000/tcp
firewall-cmd --permanent --add-port=9090/tcp
firewall-cmd --permanent --add-port=3000/tcp
firewall-cmd --reload
fi
;;
esac
}
# Start services
start_services() {
echo "[9/10] Starting services..."
systemctl daemon-reload
systemctl enable --now fastapi-app prometheus grafana-server
sleep 5
}
# Verify installation
verify_installation() {
echo "[10/10] Verifying installation..."
services=("fastapi-app" "prometheus" "grafana-server")
for service in "${services[@]}"; do
if systemctl is-active --quiet $service; then
log_info "$service is running"
else
log_error "$service is not running"
exit 1
fi
done
# Test endpoints
if curl -s http://localhost:8000/health &>/dev/null; then
log_info "FastAPI health check passed"
else
log_error "FastAPI health check failed"
fi
if curl -s http://localhost:9090/-/healthy &>/dev/null; then
log_info "Prometheus health check passed"
else
log_error "Prometheus health check failed"
fi
}
# Main execution
main() {
log_info "Starting FastAPI + Prometheus + Grafana installation"
check_prerequisites
detect_distro
update_system
create_monitoring_user
install_python_deps
create_fastapi_app
create_fastapi_service
install_prometheus
install_grafana
configure_firewall
start_services
verify_installation
log_info "Installation completed successfully!"
echo ""
echo "Access URLs:"
echo " FastAPI: http://localhost:8000"
echo " Prometheus: http://localhost:9090"
echo " Grafana: http://localhost:3000 (admin/admin)"
echo ""
echo "FastAPI metrics endpoint: http://localhost:8000/metrics"
}
main "$@"
Review the script before running. Execute with: bash install.sh