A Flask application that generates rich telemetry (metrics, logs, traces) for observability testing.
- Prometheus Metrics: Exposed at
/metrics - Structured JSON Logs: Output to stdout
- OpenTelemetry Traces: Manual instrumentation for key flows
- Multi-tenant: All telemetry tagged with
tenant_id(merch/coupons) - Failure Simulation: Every 3rd cart click fails
# Install dependencies
pip install -r requirements.txt
# Run the app
python app.pyVisit http://localhost:5001 for the UI.
- A DigitalOcean account
- SSH key configured
-
Create a Droplet
- Go to DigitalOcean Console → Create → Droplets
- Choose: Ubuntu 22.04 LTS
- Plan: Basic ($6/month - 1GB RAM, 1 vCPU)
- Add your SSH key
- Create Droplet
-
SSH into your droplet
ssh root@YOUR_DROPLET_IP
-
Install Docker & Docker Compose
# Update packages apt update && apt upgrade -y # Install Docker curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh # Install Docker Compose apt install docker-compose -y # Verify installation docker --version docker-compose --version
-
Deploy the Application
# Create app directory mkdir -p /opt/bisney cd /opt/bisney # Clone or copy your files (choose one method): # Method A: If using Git git clone YOUR_REPO_URL . # Method B: Manual upload (from your local machine) # scp -r /Users/jayanthnaidu/dev/bisney/* root@YOUR_DROPLET_IP:/opt/bisney/
-
Start the Application
cd /opt/bisney docker-compose up -d -
Verify it's running
docker-compose ps docker-compose logs -f
-
Configure Firewall
# Allow SSH, HTTP, and app port ufw allow 22/tcp ufw allow 5001/tcp ufw --force enable
-
Access Your App
- UI:
http://YOUR_DROPLET_IP:5001 - Metrics:
http://YOUR_DROPLET_IP:5001/metrics
- UI:
# SSH into droplet
ssh root@YOUR_DROPLET_IP
# Install Python
apt update && apt upgrade -y
apt install python3 python3-pip python3-venv -y
# Create app directory
mkdir -p /opt/bisney
cd /opt/bisney
# Copy files (from local machine)
# scp -r /Users/jayanthnaidu/dev/bisney/* root@YOUR_DROPLET_IP:/opt/bisney/
# Install dependencies
pip3 install -r requirements.txt
# Run with systemd (persistent)
cat > /etc/systemd/system/bisney.service << 'EOF'
[Unit]
Description=Bisney Simulator
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/bisney
ExecStart=/usr/bin/python3 /opt/bisney/app.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# Enable and start service
systemctl daemon-reload
systemctl enable bisney
systemctl start bisney
systemctl status bisney
# Configure firewall
ufw allow 22/tcp
ufw allow 5001/tcp
ufw --force enable# Check logs (Docker)
docker-compose logs -f
# Check logs (systemd)
journalctl -u bisney -f
# Restart app (Docker)
docker-compose restart
# Restart app (systemd)
systemctl restart bisney
# Stop app (Docker)
docker-compose down
# Update app (Docker)
docker-compose down
docker-compose pull
docker-compose up -d
# Check container health
docker ps
curl http://localhost:5001/metrics-
Use a Reverse Proxy (Nginx)
apt install nginx -y cat > /etc/nginx/sites-available/bisney << 'EOF' server { listen 80; server_name YOUR_DOMAIN_OR_IP; location / { proxy_pass http://localhost:5001; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } EOF ln -s /etc/nginx/sites-available/bisney /etc/nginx/sites-enabled/ nginx -t systemctl restart nginx # Update firewall ufw allow 80/tcp
-
Add SSL with Let's Encrypt (if you have a domain)
apt install certbot python3-certbot-nginx -y certbot --nginx -d yourdomain.com
-
Monitor Resource Usage
htop docker stats
# Check if port is listening
netstat -tlnp | grep 5001
# Check Docker logs
docker logs bisney-simulator
# Check system logs
journalctl -xe
# Test app locally on droplet
curl http://localhost:5001
curl http://localhost:5001/metrics
# Rebuild Docker image
docker-compose down
docker-compose build --no-cache
docker-compose up -dUser Browser → Droplet (Port 5001) → Flask App
↓
Prometheus Metrics (/metrics)
JSON Logs (stdout)
OpenTelemetry Traces (console)
- UI:
http://YOUR_IP:5001/ - Metrics:
http://YOUR_IP:5001/metrics - Health: Check metrics endpoint for 200 response
bisney_requests_total{tenant_id, status}- Total requests counterbisney_inventory_lag{tenant_id}- Inventory sync lag gaugebisney_cache_hits{tenant_id, result}- Cache hit/miss counter