Webserver-Logs sind unverzichtbar für Troubleshooting, Sicherheitsanalyse und Performance-Optimierung. Lernen Sie, Access- und Error-Logs richtig zu lesen und auszuwerten.

Log-Dateien finden

Apache

# Debian/Ubuntu
/var/log/apache2/access.log
/var/log/apache2/error.log

# CentOS/RHEL
/var/log/httpd/access_log
/var/log/httpd/error_log

# Oder in vHost definiert
grep -r "CustomLog\|ErrorLog" /etc/apache2/

Nginx

# Standard
/var/log/nginx/access.log
/var/log/nginx/error.log

# In Konfiguration definiert
grep -r "access_log\|error_log" /etc/nginx/

Access-Log verstehen

Apache Combined Log Format

192.168.1.100 - john [25/Jan/2026:10:15:32 +0100] "GET /page.html HTTP/1.1" 200 5432 "https://google.com" "Mozilla/5.0..."
│             │ │    │                            │                         │   │    │                    │
│             │ │    │                            │                         │   │    │                    └─ User-Agent
│             │ │    │                            │                         │   │    └─ Referer
│             │ │    │                            │                         │   └─ Bytes gesendet
│             │ │    │                            │                         └─ HTTP Status Code
│             │ │    │                            └─ Request (Methode, URI, Protokoll)
│             │ │    └─ Zeitstempel
│             │ └─ Authentifizierter Benutzer
│             └─ Identd (meist -)
└─ Client IP

Nginx Log Format

Standard-Format ähnelt Apache Combined:

# /etc/nginx/nginx.conf
log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

HTTP Status Codes

| Code | Bedeutung | Typische Ursache | |------|-----------|------------------| | 200 | OK | Erfolgreich | | 301 | Moved Permanently | Weiterleitung | | 302 | Found | Temporäre Weiterleitung | | 304 | Not Modified | Browser-Cache gültig | | 400 | Bad Request | Fehlerhafte Anfrage | | 401 | Unauthorized | Auth fehlt | | 403 | Forbidden | Keine Berechtigung | | 404 | Not Found | Seite existiert nicht | | 500 | Internal Server Error | Server-Fehler | | 502 | Bad Gateway | Backend nicht erreichbar | | 503 | Service Unavailable | Überlastet | | 504 | Gateway Timeout | Backend zu langsam |

Error-Log verstehen

Apache Error-Log

[Sun Jan 25 10:15:32.123456 2026] [php:error] [pid 1234] [client 192.168.1.100:54321] PHP Fatal error: ...
│                                  │           │          │                           │
│                                  │           │          │                           └─ Fehlermeldung
│                                  │           │          └─ Client
│                                  │           └─ Prozess-ID
│                                  └─ Modul und Level
└─ Zeitstempel

Log-Level

| Level | Bedeutung | |-------|-----------| | emerg | Notfall, System unbenutzbar | | alert | Sofortige Aktion nötig | | crit | Kritisch | | error | Fehler | | warn | Warnung | | notice | Normal aber wichtig | | info | Informationen | | debug | Debug-Informationen |

Nginx Error-Log

2026/01/25 10:15:32 [error] 1234#5678: *9999 open() "/var/www/html/missing.html" failed (2: No such file or directory), client: 192.168.1.100, server: example.com, request: "GET /missing.html HTTP/1.1", host: "example.com"

Echtzeit-Monitoring

Logs live verfolgen

# Letzten Zeilen und neue
tail -f /var/log/nginx/access.log

# Mehrere Logs gleichzeitig
tail -f /var/log/nginx/*.log

# Mit Highlighting
tail -f /var/log/nginx/access.log | grep --color=auto "404\|500"

Nur bestimmte Einträge

# Nur Fehler (4xx und 5xx)
tail -f /var/log/nginx/access.log | awk '$9 ~ /^[45]/'

# Nur eine IP
tail -f /var/log/nginx/access.log | grep "192.168.1.100"

Log-Analyse mit Command-Line Tools

Top 10 IP-Adressen

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

Top 10 angeforderte Seiten

awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

Anfragen pro Stunde

awk '{print $4}' /var/log/nginx/access.log | cut -d: -f1,2 | uniq -c

Status-Code Verteilung

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

404-Fehler finden

awk '$9 == 404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

500-Fehler finden

grep " 500 " /var/log/nginx/access.log | tail -20

Bandbreite pro IP

awk '{ip[$1]+=$10} END {for (i in ip) print ip[i], i}' /var/log/nginx/access.log | sort -rn | head -10

Bot-Traffic erkennen

grep -i "bot\|crawler\|spider" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn

GoAccess - Visuelle Log-Analyse

Installation

apt install goaccess

Terminal-UI

goaccess /var/log/nginx/access.log -c
# Format auswählen: NCSA Combined Log Format

HTML-Report generieren

goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED

Echtzeit-HTML-Report

goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED --real-time-html

Log-Rotation

logrotate Konfiguration

# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

Manuelle Rotation

logrotate -f /etc/logrotate.d/nginx

Custom Log Format

Nginx - Erweitertes Format

log_format detailed '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '$request_time $upstream_response_time $pipe';

access_log /var/log/nginx/access.log detailed;

Apache - Mit Antwortzeit

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" combined_with_time
CustomLog /var/log/apache2/access.log combined_with_time

%D = Antwortzeit in Mikrosekunden

JSON-Format für Log-Aggregation

log_format json '{"time":"$time_iso8601",'
                '"ip":"$remote_addr",'
                '"method":"$request_method",'
                '"uri":"$request_uri",'
                '"status":$status,'
                '"size":$body_bytes_sent,'
                '"referer":"$http_referer",'
                '"agent":"$http_user_agent",'
                '"request_time":$request_time}';

access_log /var/log/nginx/access.json json;

Security-Analyse

Brute-Force-Angriffe erkennen

# Login-Versuche pro IP
grep "POST /wp-login.php" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10

SQL-Injection-Versuche

grep -iE "union.*select|select.*from|insert.*into" /var/log/nginx/access.log

Verdächtige User-Agents

grep -iE "sqlmap|nikto|nmap|masscan" /var/log/nginx/access.log

403/401-Fehler analysieren

awk '$9 == 403 || $9 == 401' /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10

Debugging mit Error-Logs

PHP-Fehler finden

grep "PHP" /var/log/apache2/error.log | tail -50
grep "FastCGI" /var/log/nginx/error.log | tail -50

Timeout-Probleme

grep -i "timeout\|timed out" /var/log/nginx/error.log

Permission-Probleme

grep -i "permission denied\|forbidden" /var/log/nginx/error.log

Upstream-Fehler (Nginx)

grep "upstream" /var/log/nginx/error.log | tail -50

Zusammenfassung

| Aufgabe | Befehl | |---------|--------| | Live-Logs | tail -f access.log | | Top IPs | awk '{print $1}' access.log | sort | uniq -c | sort -rn | head | | Status-Codes | awk '{print $9}' access.log | sort | uniq -c | sort -rn | | 404-Fehler | awk '$9 == 404 {print $7}' access.log | sort | uniq -c | | Visuelle Analyse | goaccess access.log -c |

Fazit

Webserver-Logs sind eine Goldgrube für Troubleshooting und Sicherheitsanalyse. Mit einfachen Command-Line-Tools wie awk, grep und sort können Sie schnell Probleme identifizieren. Für regelmäßige Analyse empfiehlt sich GoAccess oder eine Log-Aggregation mit ELK-Stack. Vergessen Sie nicht die Log-Rotation, um Speicherplatz zu sparen.