02:00. The page fires. Disk usage 95%. Your model proxy returns 500s. No deploy. No traffic spike. The logs just grew.
Free-tier servers have small disks. A chatty agent log can fill one in hours. Today you will fill the disk on purpose, watch the failure, and build a recovery path.
MonkeyCode offers a free server and free model access. This drill uses that server and a minimal Python proxy. No external tools.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
What you are testing
- How the OS behaves when the disk fills
- How your proxy fails when it cannot write logs
- How logrotate prevents the next outage
Stage 1: Provision the server and a log-generating proxy
SSH into your free server.
ssh root@your-free-server
df -h
Note the available space. Create a working directory.
mkdir -p ~/drill && cd ~/drill
Create a minimal proxy that logs every request:
#!/usr/bin/env python3
import json
import time
from http.server import BaseHTTPRequestHandler, HTTPServer
LOG = "/var/log/proxy.log"
class H(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("Content-Length", 0))
self.rfile.read(length)
with open(LOG, "a") as f:
f.write(f"{time.time()} {self.client_address[0]}\n")
body = b'{"ok":true}'
self.send_response(200)
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, *a):
pass
HTTPServer(("0.0.0.0", 8080), H).serve_forever()
Run it as a background process:
python3 proxy.py &
Verify it works:
curl -s -X POST http://127.0.0.1:8080/ -d '{}'
# {"ok":true}
tail -1 /var/log/proxy.log
# 1720000000.123 127.0.0.1
Stage 2: Fill the disk on purpose
Check current usage:
df -h /
Example output on a 10G server:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 10G 2.1G 7.9G 21% /
Use fallocate to consume 90% of the free space. Adjust the size based on your server.
fallocate -l 1G /tmp/fill
df -h /
Repeat until you reach 90%:
for i in 1 2 3 4 5 6 7; do fallocate -l 1G /tmp/fill.$i; done
df -h /
Now send requests to the proxy:
for i in $(seq 1 20); do
curl -s -o /dev/null -w "%{http_code}\n" -X POST http://127.0.0.1:8080/ -d '{}'
done | sort | uniq -c
Expected output:
12 200
8 500
Some requests succeed, then they fail. The proxy cannot append to the log.
Stage 3: Diagnose the failure
Check the disk:
df -h /
Check the log size:
ls -lh /var/log/proxy.log
Check kernel messages:
dmesg | tail -20
You will see no space left on device errors. The proxy process may still run, but every write fails.
Stage 4: Recover and implement logrotate
Remove the filler files:
rm -f /tmp/fill.*
df -h /
Now configure logrotate for the proxy log. Create /etc/logrotate.d/proxy:
/var/log/proxy.log {
daily
rotate 3
compress
missingok
notifempty
copytruncate
}
Test logrotate manually:
logrotate -vf /etc/logrotate.d/proxy
ls -lh /var/log/proxy.log*
Output shows the rotated and compressed files:
-rw-r--r-- 1 root root 0 Aug 25 02:10 /var/log/proxy.log
-rw-r--r-- 1 root root 123 Aug 25 02:09 /var/log/proxy.log.1.gz
The log is rotated and compressed. The proxy keeps writing to a fresh file.
Stage 5: Re-run the drill and verify
Fill the disk again, but this time watch logrotate protect you.
for i in 1 2 3 4 5 6 7; do fallocate -l 1G /tmp/fill.$i; done
df -h /
Send requests again:
for i in $(seq 1 20); do
curl -s -o /dev/null -w "%{http_code}\n" -X POST http://127.0.0.1:8080/ -d '{}'
done | sort | uniq -c
Expected output:
20 200
All requests succeed. The log file stays bounded because logrotate truncates it. The disk fills, but the log does not.
Limitations
- Free server disk size varies. Check your actual quota.
- Do not fill the disk to 100%. You can lock yourself out of SSH.
- Logrotate is not a monitoring solution. You still need alerts on disk usage.
-
copytruncatecan lose a few log lines between copy and truncate. Acceptable for this use case.
Cleanup and rollback
Remove the filler files:
rm -f /tmp/fill.*
Stop the proxy:
pkill -f proxy.py
Remove the test log and logrotate config:
rm -f /var/log/proxy.log*
rm /etc/logrotate.d/proxy
Your server is back to the original state.
Who should skip this
- If your proxy writes logs to stdout and you use a log collector, this drill is less relevant.
- If your log volume is a few KB per day, disk exhaustion is unlikely.
- If you run a managed service, the provider handles disk pressure.
Run this drill on your free server. The df curve after a log flood is the signal you want to see before production, not after.
Top comments (0)