problem area

Hosting Operations

Web hosting, SSL, DNS, Nginx, deployment, backups, and VPS management.

133 checked fixes

One-liners in this area

Hosting Operations safe

List Newest Source Files Before Backup

Before trusting a backup, know which files changed most recently.

find source -type f -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort
Hosting Operations safe

Create a SHA256 Checksum Manifest

A file list says what exists; checksums say whether bytes match.

sha256sum source/app/config.yml source/content/index.md source/content/about.md source/assets/logo.svg
Hosting Operations safe

Compare Source and Backup File Lists

A backup can be missing files and still look plausible at a glance.

comm -3 <(find source -type f | sed 's#^source/##' | sort) <(find backup -type f | sed 's#^backup/##' | sort)
Hosting Operations safe

Preview Backup Drift with rsync

Rsync can tell you what would change before it changes anything.

rsync -ain --delete source/ backup/
Hosting Operations safe

Find Empty Files in a Backup

Zero-byte files can be normal, or they can be failed writes.

find backup -type f -size 0 -print
Hosting Operations safe

List Largest Files in a Backup

Large backup files are where storage surprises usually start.

find backup -type f -printf '%s %p\n' | sort -nr | head
Hosting Operations safe

Find Files Newer Than a Backup Snapshot

Files newer than the last snapshot are the ones most likely missing from it.

find source -type f -newer backup/.snapshot -print | sort
Hosting Operations safe

List Restore Points Before a Drill

A restore drill starts by proving which backups actually exist.

cd restore-dr && find backups -maxdepth 2 -type f -name MANIFEST.txt -printf '%TY-%Tm-%Td %TH:%TM %h\n' | sort -r
Hosting Operations safe

Read the Backup Manifest

The manifest should say what backup you are about to trust.

cd restore-dr && cat backups/2026-06-25/MANIFEST.txt
Hosting Operations safe

List Archive Contents Before Extracting

You can inspect a tar backup before it writes a single file.

cd restore-dr && tar -tf backups/2026-06-25/site.tar | sed 's#^./##' | sort
Hosting Operations safe

Find Missing Files in an Old Backup

The fastest failed restore drill is the one that finds missing critical files early.

cd restore-dr && tar -tf backups/2026-06-24/site.tar | sed 's#^./##' | sort | comm -23 required-files.txt -
Hosting Operations caution

Extract a Backup Into a Restore Sandbox

A restore drill should write to a sandbox, not production.

cd restore-dr && rm -rf restore-sandbox/full && mkdir -p restore-sandbox/full && tar -xf backups/2026-06-25/site.tar -C restore-sandbox/full
Hosting Operations caution

Verify Restored File Checksums

A restore is not validated until the bytes match.

cd restore-dr && rm -rf restore-sandbox/full && mkdir -p restore-sandbox/full && tar -xf backups/2026-06-25/site.tar -C restore-sandbox/full && (cd restore-sandbox/full && sha256sum -c CHECKSUMS.sha256)
Hosting Operations caution

Diff Restored Config Against Expected

A restored config can exist and still be the wrong config.

cd restore-dr && rm -rf restore-sandbox/full && mkdir -p restore-sandbox/full && tar -xf backups/2026-06-25/site.tar -C restore-sandbox/full && diff -u expected/app/config.yml restore-sandbox/full/app/config.yml
Hosting Operations caution

Check Required Files After Restore

A successful extraction still needs a required-file check.

cd restore-dr && rm -rf restore-sandbox/full && mkdir -p restore-sandbox/full && tar -xf backups/2026-06-25/site.tar -C restore-sandbox/full && find restore-sandbox/full -type f | sed 's#^restore-sandbox/full/##' | sort | comm -23 required-files.txt -
Hosting Operations safe

Review Critical File Modes in the Archive

Permissions are part of the restore, not decoration.

cd restore-dr && tar -tvf backups/2026-06-25/site.tar | awk '/secrets.env|deploy.sh/ {print $1, $6}'
Hosting Operations safe

Read the Restore Drill Validation Report

A restore drill that leaves no evidence is hard to trust later.

cd restore-dr && grep -E 'status=|rpo_minutes=|rto_seconds=|checksum=|file_count=' reports/restore-dr-2026-06-25.txt
Hosting Operations safe

Find the Newest Build Logs First

The failing file is usually one of the newest artifacts.

find artifacts logs -type f \( -name '*.log' -o -name '*.txt' \) -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort -r | head
Hosting Operations safe

Scan Every CI Log for Error Lines

One grep pass can turn a log pile into a failure list.

grep -RInE 'error|failed|failure|exception|traceback' artifacts logs | head -50
Hosting Operations safe

Summarize Test Counts from Reports

Before debugging a test failure, measure the blast radius.

grep -RhoE 'tests="[0-9]+"|failures="[0-9]+"|errors="[0-9]+"|skipped="[0-9]+"' artifacts/test/*.xml | sort | uniq -c
Hosting Operations safe

Find Coverage Regression Lines

Coverage failures usually say the threshold out loud.

grep -RInE 'coverage|threshold|minimum|below' artifacts logs
Hosting Operations safe

Find the Largest CI Artifacts

A bloated artifact can explain a slow or failed pipeline.

find artifacts -type f -printf '%s %p\n' | sort -nr | head -10
Hosting Operations safe

Detect Secret Leak Markers in Artifacts

Artifacts are public more often than you think.

grep -RInE 'AWS_ACCESS_KEY|SECRET|TOKEN|PRIVATE KEY|PASSWORD' artifacts logs | head -50
Hosting Operations safe

Find Tests That Passed After Rerun

A green retry can still hide a flaky test.

grep -RInE 'rerun|retry|flaky|passed on retry|failed attempt' artifacts logs
Hosting Operations safe

Show Active PostgreSQL Connections

The database was not down. It was full.

psql -X -A -F '|' -c "select pid,usename,datname,state,client_addr from pg_stat_activity order by state, pid;"
Hosting Operations safe

Find Long-Running PostgreSQL Queries

One query can make the whole app look broken.

psql -X -c "select pid, now() - query_start as age, state, left(query, 80) as query from pg_stat_activity where query_start is not null order by age desc limit 10;"
Hosting Operations safe

Check PostgreSQL Lock Waits

The outage was a queue, not a crash.

psql -X -c "select pid, wait_event_type, wait_event, state, left(query, 80) as query from pg_stat_activity where wait_event_type is not null order by pid;"
Hosting Operations safe

Show PostgreSQL Database Sizes

Disk pressure starts with knowing what grew.

psql -X -c "select datname, pg_size_pretty(pg_database_size(datname)) as size from pg_database order by pg_database_size(datname) desc;"
Hosting Operations safe

Find Long-Running MySQL Queries

One old query explained the whole slowdown.

mysql -e "select id,user,host,db,command,time,state,left(info,80) as info from information_schema.processlist where command <> 'Sleep' order by time desc limit 10;"
Hosting Operations safe

Show MySQL Database Sizes

The storage alert needed a database name.

mysql -e "select table_schema, round(sum(data_length + index_length)/1024/1024, 1) as mb from information_schema.tables group by table_schema order by mb desc;"
Hosting Operations safe

Tail the Failing CI Lines

Skip the full CI log and jump straight to lines that usually explain the failure.

grep -RInE 'error|failed|exception|traceback|fatal' logs/ | tail -50
Hosting Operations safe

List Newest Build Artifacts

Confirm what your pipeline actually produced before you deploy it.

find artifacts/ -type f -printf '%TY-%Tm-%Td %TH:%TM %10s %p\n' | sort | tail -20
Hosting Operations safe

Show Release Directory Ages

See your newest release directories without opening a dashboard.

find releases/ -mindepth 1 -maxdepth 1 -type d -printf '%T@ %TY-%Tm-%Td %TH:%TM %p\n' | sort -nr | head -10 | cut -d' ' -f2-
Hosting Operations safe

Compare Artifact Checksums

Verify two artifact copies match before blaming deployment code.

sha256sum artifacts/app.tar.gz releases/current/app.tar.gz
Hosting Operations safe

Check Image Tags in Manifests

Find the image tags your deployment files reference without printing env values.

grep -RhoE 'image:[[:space:]]*[^[:space:]]+' deploy/ | sort -u
Hosting Operations safe

Keep du on One Filesystem

A cleanup scan should not wander into mounted backups or network storage.

du -xh --max-depth=1 /lab/disk-inode-cleanup/var 2>/dev/null | sort -h
Hosting Operations safe

Preview Old Temp Files Before Deleting

The safe version of cleanup is a candidate list first.

find /lab/disk-inode-cleanup/var/tmp/uploads -xdev -type f -mtime +7 -printf '%TY-%Tm-%Td %10s %p\n' | sort
Hosting Operations safe

Find Directories Burning Inodes

Inode cleanup starts by finding the directory with too many files.

find /lab/disk-inode-cleanup/var/cache/app -xdev -type f -printf '%h\n' | sort | uniq -c | sort -nr | head
Hosting Operations safe

List Empty Directories as Cleanup Candidates

Empty directories are low-risk candidates, but they still deserve a preview.

find /lab/disk-inode-cleanup/var/cache/app -xdev -depth -type d -empty -print
Hosting Operations safe

Exclude the Current Release from Cleanup

Release cleanup should prove what current points to before listing old directories.

current=$(readlink -f /lab/disk-inode-cleanup/home/deploy/current); find /lab/disk-inode-cleanup/home/deploy/releases -mindepth 1 -maxdepth 1 -type d ! -samefile "$current" -printf '%TY-%Tm-%Td %p\n' | sort
Hosting Operations safe

Rank Old Cleanup Candidates by Size

The oldest file is not always the file that buys back meaningful space.

find /lab/disk-inode-cleanup/var -xdev -type f -mtime +7 -printf '%s %TY-%Tm-%Td %p\n' | sort -nr | head
Hosting Operations safe

Review Log Files Before Cleanup

Before truncating logs, prove which log files are large and how old they are.

find /lab/disk-inode-cleanup/var/log -xdev -type f -printf '%10s %TY-%Tm-%Td %p\n' | sort -nr
Hosting Operations safe

Summarize Cache File Ages

Cache cleanup is safer when you know whether files are stale or still active.

find /lab/disk-inode-cleanup/var/cache/app -xdev -type f -printf '%TY-%Tm-%Td\n' | sort | uniq -c
Hosting Operations safe

Show Containers in a Clean Triage Table

Turn noisy docker ps output into the few fields operators scan first.

docker ps -a --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}\t{{.Ports}}'
Hosting Operations safe

Check Container Health Status

Docker may say a container is running while its health check says otherwise.

docker inspect --format '{{.Name}} health={{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}} status={{.State.Status}}' web
Hosting Operations safe

Snapshot Container CPU and Memory

Get Docker resource usage once, without leaving a live dashboard running.

docker stats --no-stream --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}'
Hosting Operations safe

Summarize Docker Disk Usage

See how Docker storage is split across images, containers, volumes, and cache.

docker system df -v
Hosting Operations safe

See Container Network Attachments

A container can be healthy and still attached to the wrong network.

docker inspect --format '{{.Name}} {{range $name, $net := .NetworkSettings.Networks}}{{$name}} {{$net.IPAddress}} {{end}}' api
Hosting Operations safe

Snapshot Git Status Before Recovery

Before rollback commands, capture the branch and dirty files.

cd /lab/git-recovery-rollback && git status --short --branch
Hosting Operations safe

Map Recent Release Commits

A rollback is easier when the last few release tags are visible.

cd /lab/git-recovery-rollback && git log --oneline --decorate --graph --all -8
Hosting Operations safe

Show Files Changed Since Last Good Release

Compare the suspect release against the last known-good tag.

cd /lab/git-recovery-rollback && git diff --name-status release-2026-06-25-1000..HEAD
Hosting Operations safe

Find a Discarded Commit in Reflog

A reset does not mean the commit vanished.

cd /lab/git-recovery-rollback && git reflog --date=iso --format='%h %gd %gs' -6
Hosting Operations caution

Branch a Recovered Commit

Put a name on the reflog commit before it slips away.

cd /lab/git-recovery-rollback && git branch recovered-incident-note HEAD@{1}
Hosting Operations caution

Restore One File From Last Good Release

Recover a config file without rolling back the whole branch.

cd /lab/git-recovery-rollback && git restore --source=release-2026-06-25-1000 -- app/config.yml
Hosting Operations safe

Check the Active Release Symlink

Git may say one thing while the release pointer serves another.

cd /lab/git-recovery-rollback && readlink releases/current && cat releases/current/VERSION
Hosting Operations caution

Rollback a Release Symlink in a Sandbox

Practice the pointer switch where the blast radius is zero.

cd /lab/git-recovery-rollback && ln -sfn 2026-06-25-1000 releases/current
Hosting Operations safe

Preview the Patch a Rollback Would Apply

Show the exact file changes before moving the branch back.

cd /lab/git-recovery-rollback && git diff --stat HEAD..release-2026-06-25-1000
Hosting Operations caution

Revert the Suspect Release Commit

Undo a bad release with a new commit instead of rewriting history.

cd /lab/git-recovery-rollback && git restore -- app/config.yml && git revert --no-edit release-2026-06-25-1030
Hosting Operations safe

Test Nginx Before Reload

The config looked fine. Nginx disagreed before reload broke anything.

nginx -t
Hosting Operations safe

Show Enabled Nginx Sites

The config existed, but it was not enabled.

ls -l /etc/nginx/sites-enabled/
Hosting Operations safe

Inspect Response Headers

The page loaded, but the headers told the operational story.

curl -sI https://example.com
Hosting Operations safe

Check a Domain A Record

The site was fine. The domain was pointed somewhere else.

dig +short example.com A
Hosting Operations safe

List Certbot Certificates

The certificate existed. The question was which domains it covered.

certbot certificates
Hosting Operations safe

Check the Current Release Symlink

The deploy finished. The symlink told me what was actually live.

readlink -f /srv/www/example.com/current
Hosting Operations safe

Find Top 404 URLs

The missing file was not random. The access log had a pattern.

awk '$9==404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
Hosting Operations safe

See Top Referrers

LinkedIn traffic was not a guess. The referrer field showed it.

awk -F'"' '{print $4}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
Hosting Operations safe

Summarize Journal Severity During an Incident

Start with severity counts before opening every log line.

journalctl -p warning..alert --since "2 hours ago" --no-pager -o short-iso | awk '{count[$4]++} END {for (level in count) print count[level], level}' | sort -nr
Hosting Operations safe

Group Journal Errors by Unit

A noisy incident usually has a noisy source.

journalctl -p err..alert --since "2 hours ago" --no-pager -o short-iso | awk '{split($3,a,"["); unit=a[1]; count[unit]++} END {for (u in count) print count[u], u}' | sort -nr
Hosting Operations safe

Print a Critical Journal Timeline

Timeline beats guesswork when several failures happen close together.

journalctl -p err..alert --since "2 hours ago" --no-pager -o short-iso | awk '{print $1, $3, $4, substr($0,index($0,$5))}'
Hosting Operations safe

Count App Errors by Minute

A minute-by-minute count shows whether an incident is a spike or a drip.

awk 'tolower($0) ~ /(error|fatal|timeout|exception)/ {minute=substr($1,1,16); count[minute]++} END {for (m in count) print count[m], m}' fixtures/incidents/app.log | sort -nr
Hosting Operations safe

Count Request IDs in Error Lines

Repeated request IDs can connect separate error lines to one failing path.

grep -Ei 'error|timeout|fatal|exception' fixtures/incidents/app.log | awk '{for (i=1;i<=NF;i++) if ($i ~ /^request_id=/) print $i}' | sort | uniq -c | sort -nr
Hosting Operations safe

Build a Deploy and Restart Timeline

Deploys and restarts are incident landmarks.

grep -Eh 'deploy|release|restart|started|stopped|rolled back' fixtures/incidents/*.log | sort
Hosting Operations safe

Find Release Files Writable Outside the Owner

A release file that someone besides the owner can modify deserves a second look.

find fixtures/perm-audit/releases/2026-06-25 -type f -perm /0022 -printf '%M %u:%g %p\n' | sort
Hosting Operations safe

Find Runtime Directories Writable Outside the Owner

Runtime directories often need writes, but the write boundary should be visible.

find fixtures/perm-audit/releases/2026-06-25/storage fixtures/perm-audit/releases/2026-06-25/uploads -type d -perm /0022 -printf '%M %u:%g %p\n' | sort
Hosting Operations safe

Group Writable Files by Owning Group

Group-writable files are not automatically wrong, but the owning group decides the risk.

find fixtures/perm-audit -type f -perm -0020 -printf '%g %M %p\n' | sort
Hosting Operations safe

Audit a Symlink Permission Chain

A symlink can make the path you audited different from the file the app opens.

find fixtures/perm-audit -type l -printf '%p -> %l\n' -exec namei -l {} \;
Hosting Operations safe

Find the Processes Burning CPU

A server feels slow, but you need proof before restarting anything.

ps -eo pid,ppid,stat,pcpu,pmem,comm,args --sort=-pcpu | head -n 10
Hosting Operations safe

Find the Processes Eating Memory

Memory pressure can look like a slow app, a stuck deploy, or random crashes.

ps -eo pid,ppid,stat,pcpu,pmem,rss,comm,args --sort=-pmem | head -n 10
Hosting Operations safe

Find System Cron Files Fast

A job can be nowhere in your crontab and still run every night.

find /etc/cron.d /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly -maxdepth 1 -type f -print 2>/dev/null | sort
Hosting Operations safe

Find Cron Jobs With No Log Trail

A silent cron job is a future incident with no witness.

crontab -l | awk 'NF && $1 !~ /^#/ && $0 !~ /(>>|2>|logger|mail)/ {print}'
Hosting Operations safe

Spot Stale systemd Timers

The suspicious timer is the one with no next run.

systemctl list-timers --all --no-pager --plain | awk 'NR==1 || $1=="n/a" || /backup\.timer|logrotate\.timer/'
Hosting Operations safe

Check the Last Timer Payload Logs

When a timer fires, the useful logs are usually on the service.

journalctl -u backup.service -n 20 --no-pager
Hosting Operations safe

Dry-Run Logrotate Before Touching Logs

Logrotate can explain its plan without rotating anything.

logrotate -d /etc/logrotate.conf 2>&1 | sed -n '/rotating pattern/p;/considering log/p;/error:/p'
Hosting Operations safe

Find Logs Missing Logrotate Coverage

The biggest log risk is often the file no policy mentions.

find /var/log -type f -name '*.log' -printf '%p\n' | while read -r log; do grep -Rqs -- "$log" /etc/logrotate.conf /etc/logrotate.d || grep -Rqs -- "$(dirname "$log")/[*].log" /etc/logrotate.conf /etc/logrotate.d || printf '%s\n' "$log"; done
Hosting Operations safe

Show One SQLite Table Schema

A failed query is often just a wrong assumption about column names.

sqlite3 app.db ".schema users"
Hosting Operations safe

Check SQLite Database Integrity

When a SQLite-backed app behaves strangely, first rule out file corruption.

sqlite3 app.db "PRAGMA integrity_check;"
Hosting Operations safe

List SQLite User Tables Only

System metadata tables can distract from the app tables you care about.

sqlite3 app.db "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"
Hosting Operations safe

Count Rows in Key SQLite Tables

A quick row count can reveal empty imports, runaway events, or missing data.

sqlite3 app.db "SELECT 'users', count(*) FROM users UNION ALL SELECT 'orders', count(*) FROM orders UNION ALL SELECT 'events', count(*) FROM events;"
Hosting Operations safe

Show Indexes on a SQLite Table

Slow lookups often start with missing or misunderstood indexes.

sqlite3 app.db "PRAGMA index_list('orders');"
Hosting Operations safe

Show Recent SQLite Events

For small apps, the quickest timeline may be inside the SQLite file.

sqlite3 app.db "SELECT created_at, event_type FROM events ORDER BY created_at DESC LIMIT 5;"
Hosting Operations safe

Count SQLite Events by Type

A noisy event type stands out faster when you group it.

sqlite3 app.db "SELECT event_type, count(*) FROM events GROUP BY event_type ORDER BY count(*) DESC;"
Hosting Operations safe

Find Duplicate Emails in SQLite

Duplicate account data is easier to spot with one grouped query.

sqlite3 app.db "SELECT email, count(*) FROM users GROUP BY email HAVING count(*) > 1;"
Hosting Operations caution

Back Up a SQLite Database File

Copying a live SQLite file blindly can produce a bad backup.

sqlite3 app.db ".backup backup/app.db"
Hosting Operations safe

Find Duplicate Page Titles

Duplicate titles make a static site harder to scan in search results and browser tabs.

grep -Rho --include='*.html' '[^<]*' public | sed 's###;s###' | sort | uniq -c | sort -nr
Hosting Operations safe

Find Pages Missing Canonical Links

Canonical tags are easy to drop when templates branch.

find public -name '*.html' -print | while read -r f; do grep -qi 'rel="canonical"' "$f" || echo "$f"; done
Hosting Operations safe

Find Pages Marked noindex

A leftover noindex can hide a page after launch.

grep -Rni --include='*.html' 'noindex' public
Hosting Operations safe

Find Pages Missing Meta Descriptions

Missing descriptions are usually a content template problem, not a mystery.

find public -name '*.html' -print | while read -r f; do grep -qi 'name="description"' "$f" || echo "$f"; done
Hosting Operations safe

Find HTML Pages Missing from the Sitemap

A page can exist in the build but never make it into the sitemap.

find public -name '*.html' -print | sed 's#^public#https://example.com#' | while read -r url; do grep -q "$url" public/sitemap.xml || echo "$url"; done
Hosting Operations safe

Find Pages Missing og:title

Social previews often fail because one template missed Open Graph tags.

find public -name '*.html' -print | while read -r f; do grep -qi 'property="og:title"' "$f" || echo "$f"; done
Hosting Operations safe

Find Feed Links Missing from the Sitemap

Your feed can advertise URLs that the sitemap never lists.

grep -o 'https://example.com/[^<]*' public/feed.xml | sed 's###;s###' | while read -r url; do grep -q "$url" public/sitemap.xml || echo "$url"; done
Hosting Operations safe

Build a Restart Loop Timeline

Restart loops make more sense when you line up starts, failures, and counters.

journalctl -u app-worker -b --no-pager -o short-iso | grep -E 'Started|Failed|Scheduled restart|Main process exited'
Hosting Operations safe

Print Runtime Paths and User From systemd

Confirm the user, working directory, env file, and ExecStart systemd is actually using.

systemctl show app-worker --property=FragmentPath,DropInPaths,EnvironmentFiles,ExecStart,User,WorkingDirectory --no-pager
Hosting Operations safe

Find the First Failure Line for One Unit

The first failure line is often more useful than the last restart message.

journalctl -u app-worker -b --no-pager -o short-iso | grep -m1 -E 'ERROR|Failed|status='
Hosting Operations safe

List Nginx Listen Directives

The site was configured, but the port was not.

grep -RInE '^[[:space:]]*listen[[:space:]]' fixtures/nginx/conf.d fixtures/nginx/sites-enabled
Hosting Operations safe

Find the Nginx Default Server

The wrong site answered because it was the fallback.

grep -RIn 'default_server' fixtures/nginx/conf.d fixtures/nginx/sites-enabled
Hosting Operations safe

Show Nginx Include Lines

The config was valid; it just was not included.

grep -RInE '^[[:space:]]*include[[:space:]]' fixtures/nginx/nginx.conf fixtures/nginx/conf.d fixtures/nginx/sites-enabled
Hosting Operations safe

Map Nginx Roots and Aliases

The URL was right. The filesystem path was not.

grep -RInE '^[[:space:]]*(root|alias)[[:space:]]' fixtures/nginx/conf.d fixtures/nginx/sites-enabled
Hosting Operations safe

Map Nginx Proxy Targets

Nginx was healthy. It was proxying to the wrong place.

grep -RInE '^[[:space:]]*proxy_pass[[:space:]]' fixtures/nginx/conf.d fixtures/nginx/sites-enabled
Hosting Operations safe

Show Enabled Apache Sites

The Apache config existed. The enabled symlink did not.

find fixtures/apache/sites-enabled -maxdepth 1 -type l -printf '%f -> %l\n' | sort
Hosting Operations safe

Map Apache Virtual Hosts

Apache chose a virtual host. You need to know which one.

grep -RInE '
Hosting Operations safe

Find Apache Document Roots

Apache was serving files from a different directory than expected.

grep -RInE '^[[:space:]]*DocumentRoot[[:space:]]' fixtures/apache/sites-enabled
Hosting Operations safe

Map Apache Proxy Rules

Apache was up. The reverse proxy target was wrong.

grep -RInE '^[[:space:]]*(ProxyPass|ProxyPassReverse)[[:space:]]' fixtures/apache/sites-enabled
Hosting Operations safe

Find Web Server Redirect Rules

The redirect loop was hiding in plain text.

grep -RInE 'return[[:space:]]+30[18]|rewrite[[:space:]]|Redirect[[:space:]]|RewriteRule|RewriteCond' fixtures/nginx fixtures/apache
Hosting Operations safe

Summarize HTTP Status Codes

Before chasing individual lines, get the shape of the whole log.

awk '{count[$9]++} END {for (code in count) print count[code], code}' ./fixtures/nginx/access.log | sort -nr
Hosting Operations safe

Group Server Errors by URL Path

A 500 spike is easier to triage when the broken path is obvious.

awk '$9 ~ /^5/ {count[$7]++} END {for (path in count) print count[path], path}' ./fixtures/nginx/access.log | sort -nr | head
Hosting Operations safe

Find Unusually Large Web Responses

A few huge responses can explain bandwidth, latency, and suspicious download patterns.

awk '$10 ~ /^[0-9]+$/ && $10 > 1000000 {print $10, $1, $7, $9}' ./fixtures/nginx/access.log | sort -nr | head