Bài 3: Logging và Monitoring Nginx

Bài học về logging và monitoring Nginx với access log, error log, custom log format, và log rotation. Hướng dẫn phân tích logs, troubleshooting, sử dụng logrotate, và các metrics cơ bản để theo dõi hiệu suất server. Bao gồm ví dụ thực tế và best practices.

12 min read
Bài 3: Logging và Monitoring Nginx

1. Access Log và Error Log

Nginx có hai loại log chính để theo dõi hoạt động của server: Access log (ghi lại tất cả requests) và Error log (ghi lại errors và warnings).

1.1. Access Log

Access log ghi lại mọi request đến server, bao gồm thông tin về client, request, response status, và thời gian xử lý.

Vị trí mặc định:

# Ubuntu/Debian
/var/log/nginx/access.log

# CentOS/RHEL
/var/log/nginx/access.log

# macOS (Homebrew)
/usr/local/var/log/nginx/access.log

Cấu hình cơ bản:

http {
    # Access log cho toàn bộ HTTP context
    access_log /var/log/nginx/access.log;
    
    server {
        listen 80;
        server_name example.com;
        
        # Access log riêng cho virtual host
        access_log /var/log/nginx/example.com.access.log;
        
        location / {
            root /var/www/html;
        }
        
        # Tắt access log cho location cụ thể
        location /health-check {
            access_log off;
            return 200 "OK\n";
        }
    }
}

Format mặc định (combined):

192.168.1.100 - - [03/Dec/2024:10:30:45 +0700] "GET /index.html HTTP/1.1" 200 1234 "https://google.com" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"

Giải thích các trường:

  • 192.168.1.100 - IP address của client
  • - - Remote user (thường là - nếu không có authentication)
  • - - Authenticated user
  • [03/Dec/2024:10:30:45 +0700] - Timestamp
  • "GET /index.html HTTP/1.1" - Request method, URI, và HTTP version
  • 200 - HTTP status code
  • 1234 - Response body size (bytes)
  • "https://google.com" - Referer
  • "Mozilla/5.0..." - User Agent

1.2. Error Log

Error log ghi lại các lỗi, warnings và debug information từ Nginx.

Vị trí mặc định:

/var/log/nginx/error.log

Log levels (từ ít đến nhiều chi tiết):

  1. emerg - Emergency: system unusable
  2. alert - Alert: action must be taken immediately
  3. crit - Critical conditions
  4. error - Error conditions
  5. warn - Warning conditions
  6. notice - Normal but significant
  7. info - Informational
  8. debug - Debug messages

Cấu hình:

# Global error log
error_log /var/log/nginx/error.log warn;

http {
    # HTTP-level error log
    error_log /var/log/nginx/http-error.log error;
    
    server {
        listen 80;
        server_name example.com;
        
        # Server-level error log
        error_log /var/log/nginx/example.com.error.log error;
        
        # Debug log cho troubleshooting
        error_log /var/log/nginx/debug.log debug;
    }
}

Ví dụ error log entries:

2024/12/03 10:30:45 [error] 1234#1234: *1 open() "/var/www/html/notfound.html" failed (2: No such file or directory), client: 192.168.1.100, server: example.com, request: "GET /notfound.html HTTP/1.1", host: "example.com"

2024/12/03 10:31:20 [warn] 1234#1234: *2 upstream server temporarily disabled while connecting to upstream, client: 192.168.1.101, server: api.example.com, request: "GET /api/users HTTP/1.1", upstream: "http://192.168.1.200:3000/api/users"

2024/12/03 10:32:05 [crit] 1234#1234: malloc() 8192 bytes failed (12: Cannot allocate memory)

1.3. Xem và theo dõi logs real-time

# Xem access log
sudo tail -f /var/log/nginx/access.log

# Xem error log
sudo tail -f /var/log/nginx/error.log

# Xem 100 dòng cuối
sudo tail -n 100 /var/log/nginx/access.log

# Xem cả 2 logs cùng lúc
sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log

# Filter logs
sudo tail -f /var/log/nginx/access.log | grep "404"
sudo tail -f /var/log/nginx/access.log | grep "192.168.1.100"

# Xem logs với less (có thể scroll)
sudo less +F /var/log/nginx/access.log

1.4. Phân tích logs cơ bản

Đếm số requests:

# Tổng số requests
wc -l /var/log/nginx/access.log

# Requests trong 1 giờ qua
sudo awk -v date="$(date -d '1 hour ago' '+%d/%b/%Y:%H')" '$4 > "["date' /var/log/nginx/access.log | wc -l

Top 10 IPs:

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

Top 10 URLs được truy cập:

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

Số lượng HTTP status codes:

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

Top User Agents:

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

Requests per hour:

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

2. Định dạng Log Tùy chỉnh

Nginx cho phép tạo custom log format để thu thập đúng thông tin bạn cần.

2.1. Log Format cơ bản

Định nghĩa format:

http {
    # Format mặc định (combined)
    log_format combined '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent"';
    
    # Format đơn giản hơn
    log_format simple '$remote_addr - $request - $status';
    
    # Format chi tiết
    log_format detailed '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" '
                        'rt=$request_time uct="$upstream_connect_time" '
                        'uht="$upstream_header_time" urt="$upstream_response_time"';
    
    server {
        listen 80;
        
        # Sử dụng format tùy chỉnh
        access_log /var/log/nginx/access.log detailed;
    }
}

2.2. Các biến thường dùng trong log format

Client information:

$remote_addr          # IP của client
$remote_user          # HTTP authenticated user
$http_x_forwarded_for # IP thật nếu đằng sau proxy/CDN

Request information:

$time_local           # Local time
$time_iso8601         # ISO 8601 time
$request              # Full request line
$request_method       # GET, POST, etc.
$request_uri          # Request URI with arguments
$uri                  # Current URI
$args                 # Query string arguments
$query_string         # Same as $args
$scheme               # http or https
$server_protocol      # HTTP/1.1, HTTP/2.0
$host                 # Host header
$server_name          # Server name

Response information:

$status               # HTTP status code
$body_bytes_sent      # Response body size
$bytes_sent           # Total bytes sent (headers + body)
$request_length       # Request length (including headers)

Timing information:

$request_time         # Request processing time (seconds)
$upstream_response_time    # Backend response time
$upstream_connect_time     # Time to connect to upstream
$upstream_header_time      # Time to receive upstream headers

Upstream information:

$upstream_addr             # Upstream server address
$upstream_status           # Upstream response status
$upstream_cache_status     # Cache status (HIT, MISS, etc.)

Headers:

$http_user_agent      # User-Agent header
$http_referer         # Referer header
$http_cookie          # Cookie header
$http_<header_name>   # Any HTTP header (lowercase with underscores)

2.3. Ví dụ Log Formats thực tế

Performance monitoring format:

log_format performance '$remote_addr - [$time_local] "$request" '
                       '$status $body_bytes_sent '
                       'rt=$request_time '
                       'uct=$upstream_connect_time '
                       'uht=$upstream_header_time '
                       'urt=$upstream_response_time';

server {
    listen 80;
    access_log /var/log/nginx/performance.log performance;
}

Output:

192.168.1.100 - [03/Dec/2024:10:30:45 +0700] "GET /api/users HTTP/1.1" 200 1234 rt=0.125 uct=0.005 uht=0.050 urt=0.120

JSON format (dễ parse):

log_format json_combined escape=json
    '{'
        '"time_local":"$time_local",'
        '"remote_addr":"$remote_addr",'
        '"request":"$request",'
        '"status":$status,'
        '"body_bytes_sent":$body_bytes_sent,'
        '"request_time":$request_time,'
        '"http_referer":"$http_referer",'
        '"http_user_agent":"$http_user_agent"'
    '}';

server {
    listen 80;
    access_log /var/log/nginx/access.json json_combined;
}

Output:

{"time_local":"03/Dec/2024:10:30:45 +0700","remote_addr":"192.168.1.100","request":"GET /index.html HTTP/1.1","status":200,"body_bytes_sent":1234,"request_time":0.005,"http_referer":"https://google.com","http_user_agent":"Mozilla/5.0"}

Security monitoring format:

log_format security '$remote_addr - [$time_local] '
                    '"$request" $status '
                    '"$http_user_agent" '
                    '"$http_x_forwarded_for" '
                    'host=$host '
                    'args=$args';

server {
    listen 80;
    access_log /var/log/nginx/security.log security;
}

CDN/Proxy format:

log_format cdn '$http_x_forwarded_for - $remote_addr - $remote_user [$time_local] '
               '"$request" $status $body_bytes_sent '
               '"$http_referer" "$http_user_agent" '
               'cache=$upstream_cache_status';

server {
    listen 80;
    access_log /var/log/nginx/cdn.log cdn;
}

2.4. Conditional Logging

Log chỉ khi có điều kiện:

http {
    # Định nghĩa map để check conditions
    map $status $loggable {
        ~^[23]  0;  # Don't log 2xx và 3xx
        default 1;  # Log tất cả còn lại
    }
    
    server {
        listen 80;
        
        # Chỉ log nếu $loggable = 1
        access_log /var/log/nginx/errors-only.log combined if=$loggable;
    }
}

Không log static files:

map $request_uri $log_static {
    ~*\.(jpg|jpeg|png|gif|ico|css|js)$ 0;
    default 1;
}

server {
    listen 80;
    access_log /var/log/nginx/access.log combined if=$log_static;
}

Không log health checks:

map $request_uri $log_health {
    ~^/health$ 0;
    ~^/ping$ 0;
    default 1;
}

server {
    listen 80;
    access_log /var/log/nginx/access.log combined if=$log_health;
}

Không log bots:

map $http_user_agent $log_bots {
    ~*bot 0;
    ~*crawler 0;
    ~*spider 0;
    default 1;
}

server {
    listen 80;
    access_log /var/log/nginx/access.log combined if=$log_bots;
}

2.5. Multiple Access Logs

server {
    listen 80;
    server_name example.com;
    
    # Log tất cả requests
    access_log /var/log/nginx/all.log combined;
    
    # Log chỉ errors
    access_log /var/log/nginx/errors.log combined if=$loggable;
    
    # Log performance
    access_log /var/log/nginx/performance.log performance;
    
    # Log JSON cho processing
    access_log /var/log/nginx/json.log json_combined;
}

3. Log Rotation với Logrotate

Log files có thể phình to rất nhanh. Log rotation giúp quản lý dung lượng bằng cách tự động nén và xóa logs cũ.

3.1. Logrotate cơ bản

File cấu hình mặc định:

# Ubuntu/Debian
/etc/logrotate.d/nginx

# CentOS/RHEL
/etc/logrotate.d/nginx

Nội dung mặc định:

/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
}

Giải thích directives:

  • daily - Rotate mỗi ngày
  • missingok - Không báo lỗi nếu log file không tồn tại
  • rotate 14 - Giữ 14 bản backup
  • compress - Nén logs cũ bằng gzip
  • delaycompress - Chờ đến lần rotate sau mới nén
  • notifempty - Không rotate nếu file rỗng
  • create 0640 www-data adm - Tạo file mới với permissions
  • sharedscripts - Chạy postrotate script 1 lần cho tất cả logs
  • postrotate/endscript - Script chạy sau rotation

3.2. Custom Logrotate Configuration

Rotate hourly (cho high-traffic sites):

sudo nano /etc/logrotate.d/nginx-hourly

# Nội dung:
/var/log/nginx/high-traffic.log {
    hourly
    rotate 168          # 7 days * 24 hours
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    dateext
    dateformat -%Y%m%d-%H
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

Rotate theo size:

/var/log/nginx/*.log {
    size 100M           # Rotate khi đạt 100MB
    rotate 10
    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
}

Rotate với custom naming:

/var/log/nginx/*.log {
    daily
    rotate 30
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    dateext
    dateformat -.%Y-%m-%d
    extension .log
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

# Output: access.log-2024-12-03.log.gz

Separate rotation cho từng log:

# Performance logs - giữ lâu hơn
/var/log/nginx/performance.log {
    daily
    rotate 90           # 3 months
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
}

# Error logs - giữ rất lâu
/var/log/nginx/error.log {
    weekly
    rotate 52           # 1 year
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
}

# Access logs - rotate nhanh
/var/log/nginx/access.log {
    daily
    rotate 7            # 1 week
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
}

3.3. Test và Force Rotation

# Test cấu hình (dry run)
sudo logrotate -d /etc/logrotate.d/nginx

# Force rotation (thực thi ngay)
sudo logrotate -f /etc/logrotate.d/nginx

# Check status
sudo cat /var/lib/logrotate/status

# Manual rotation (không dùng logrotate)
sudo mv /var/log/nginx/access.log /var/log/nginx/access.log.1
sudo nginx -s reopen
sudo gzip /var/log/nginx/access.log.1

3.4. Troubleshooting Logrotate

Kiểm tra logrotate có chạy không:

# Check cron job
ls -la /etc/cron.daily/logrotate

# Check logrotate status
sudo cat /var/lib/logrotate/status | grep nginx

# Run logrotate manually với verbose
sudo logrotate -v /etc/logrotate.d/nginx

Lỗi thường gặp:

# Lỗi: Permission denied
# Fix: Check ownership
ls -la /var/log/nginx/
sudo chown www-data:adm /var/log/nginx/*.log

# Lỗi: Nginx không reopen logs
# Fix: Check PID file
ls -la /var/run/nginx.pid
sudo systemctl restart nginx

# Lỗi: Logs không được nén
# Fix: Check gzip installed
which gzip
sudo apt install gzip

4. Các Metrics Cơ bản để Theo dõi

4.1. Requests per Second (RPS)

Script để tính RPS:

#!/bin/bash
# rps.sh - Calculate requests per second

LOG_FILE="/var/log/nginx/access.log"
INTERVAL=60  # seconds

while true; do
    START_COUNT=$(wc -l < "$LOG_FILE")
    sleep $INTERVAL
    END_COUNT=$(wc -l < "$LOG_FILE")
    
    REQUESTS=$((END_COUNT - START_COUNT))
    RPS=$(echo "scale=2; $REQUESTS / $INTERVAL" | bc)
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') - RPS: $RPS"
done

Chạy script:

chmod +x rps.sh
./rps.sh

4.2. Response Time Analysis

Script phân tích response time:

#!/bin/bash
# response_time.sh - Analyze response times

LOG_FILE="/var/log/nginx/access.log"

echo "Response Time Statistics:"
echo "========================"

# Extract request_time (assuming it's logged)
awk '{print $NF}' "$LOG_FILE" | \
    awk '{
        sum += $1;
        count++;
        if ($1 > max) max = $1;
        if (min == 0 || $1 < min) min = $1;
    }
    END {
        print "Average: " sum/count " seconds";
        print "Min: " min " seconds";
        print "Max: " max " seconds";
    }'

4.3. Status Code Distribution

#!/bin/bash
# status_codes.sh - Count HTTP status codes

LOG_FILE="/var/log/nginx/access.log"

echo "HTTP Status Code Distribution:"
echo "=============================="

awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -rn | \
while read count code; do
    percentage=$(echo "scale=2; ($count * 100) / $(wc -l < $LOG_FILE)" | bc)
    printf "%3s: %6d requests (%5.2f%%)\n" "$code" "$count" "$percentage"
done

4.4. Traffic by Hour

#!/bin/bash
# traffic_by_hour.sh - Analyze traffic by hour

LOG_FILE="/var/log/nginx/access.log"

echo "Traffic by Hour:"
echo "================"

awk '{print $4}' "$LOG_FILE" | cut -d: -f2 | sort | uniq -c | \
while read count hour; do
    printf "Hour %02d: %6d requests\n" "$hour" "$count"
done

4.5. Top Clients (IP Addresses)

#!/bin/bash
# top_clients.sh - Find top clients by requests

LOG_FILE="/var/log/nginx/access.log"
TOP_N=10

echo "Top $TOP_N Clients:"
echo "=================="

awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -n $TOP_N | \
while read count ip; do
    printf "%15s: %6d requests\n" "$ip" "$count"
done

4.6. Bandwidth Usage

#!/bin/bash
# bandwidth.sh - Calculate bandwidth usage

LOG_FILE="/var/log/nginx/access.log"

echo "Bandwidth Statistics:"
echo "===================="

# Assuming $body_bytes_sent is in position 10
awk '{sum += $10} END {
    gb = sum / 1024 / 1024 / 1024;
    mb = sum / 1024 / 1024;
    kb = sum / 1024;
    printf "Total: %.2f GB (%.2f MB, %.2f KB)\n", gb, mb, kb;
}' "$LOG_FILE"

4.7. Real-time Dashboard Script

#!/bin/bash
# dashboard.sh - Real-time Nginx monitoring dashboard

LOG_FILE="/var/log/nginx/access.log"

while true; do
    clear
    echo "==================================="
    echo "   NGINX MONITORING DASHBOARD"
    echo "==================================="
    echo "Time: $(date '+%Y-%m-%d %H:%M:%S')"
    echo

    # Total requests
    TOTAL=$(wc -l < "$LOG_FILE")
    echo "Total Requests: $TOTAL"
    echo

    # Last minute requests
    LAST_MINUTE=$(tail -n 1000 "$LOG_FILE" | wc -l)
    echo "Last ~1000 requests"
    echo

    # Status codes (last 1000)
    echo "Status Codes (recent):"
    tail -n 1000 "$LOG_FILE" | awk '{print $9}' | sort | uniq -c | sort -rn
    echo

    # Top 5 IPs (recent)
    echo "Top 5 IPs (recent):"
    tail -n 1000 "$LOG_FILE" | awk '{print $1}' | sort | uniq -c | sort -rn | head -5
    echo

    # Top 5 URLs (recent)
    echo "Top 5 URLs (recent):"
    tail -n 1000 "$LOG_FILE" | awk '{print $7}' | sort | uniq -c | sort -rn | head -5
    
    sleep 5
done

Chạy dashboard:

chmod +x dashboard.sh
./dashboard.sh

4.8. Gửi Alerts khi có vấn đề

#!/bin/bash
# alert.sh - Send alert when error rate is high

LOG_FILE="/var/log/nginx/access.log"
ERROR_THRESHOLD=10  # % of 5xx errors
EMAIL="admin@example.com"

# Count last 100 requests
TOTAL=$(tail -n 100 "$LOG_FILE" | wc -l)
ERRORS=$(tail -n 100 "$LOG_FILE" | awk '{print $9}' | grep "^5" | wc -l)

ERROR_RATE=$(echo "scale=2; ($ERRORS * 100) / $TOTAL" | bc)

if (( $(echo "$ERROR_RATE > $ERROR_THRESHOLD" | bc -l) )); then
    MESSAGE="ALERT: High error rate detected! $ERROR_RATE% of requests are 5xx errors"
    echo "$MESSAGE" | mail -s "Nginx Alert" "$EMAIL"
    echo "$MESSAGE"
fi

4.9. Integration với Monitoring Tools

Export metrics cho Prometheus:

# Install nginx-prometheus-exporter
wget https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v0.11.0/nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz
tar xzf nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz
sudo mv nginx-prometheus-exporter /usr/local/bin/

# Run exporter
nginx-prometheus-exporter -nginx.scrape-uri=http://localhost:8080/stub_status

Configure Nginx stub_status:

server {
    listen 8080;
    server_name localhost;
    
    location /stub_status {
        stub_status;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

5. Bài tập Thực hành

Bài tập 1: Custom Log Format

  1. Tạo custom log format có tên timing bao gồm:
    • Remote address
    • Request
    • Status
    • Request time
    • Upstream response time
  2. Apply format này cho một virtual host
  3. Generate traffic và xem logs

Bài tập 2: JSON Logging

  1. Tạo JSON log format
  2. Configure Nginx để log ra JSON
  3. Parse JSON logs bằng jq:
cat /var/log/nginx/access.json | jq '.status'
cat /var/log/nginx/access.json | jq 'select(.status >= 400)'

Bài tập 3: Log Rotation

  1. Tạo custom logrotate config rotate theo size 10MB
  2. Test với logrotate -d
  3. Force rotation và verify

Bài tập 4: Traffic Analysis

  1. Generate 1000 requests với ab:
ab -n 1000 -c 10 http://localhost/
  1. Phân tích logs để tìm:
    • Total requests
    • Average response time
    • Status code distribution
    • Top URLs

Bài tập 5: Real-time Monitoring

  1. Setup dashboard script
  2. Modify để thêm:
    • Error rate (%)
    • Bandwidth usage
    • Slowest requests

Bài tập 6: Conditional Logging

  1. Configure để không log:
    • Static files (.css, .js, .jpg, .png)
    • Health check endpoint (/health)
    • Bot traffic
  2. Verify rằng những requests này không xuất hiện trong logs

6. Troubleshooting với Logs

6.1. Debug 404 Errors

# Tìm tất cả 404s
grep " 404 " /var/log/nginx/access.log

# Top URLs gây 404
grep " 404 " /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -10

# 404s từ IP cụ thể
grep "192.168.1.100" /var/log/nginx/access.log | grep " 404 "

6.2. Debug 500 Errors

# Tìm 5xx errors
grep " 50[0-9] " /var/log/nginx/access.log

# Check error log cho details
sudo tail -100 /var/log/nginx/error.log | grep "error"

# 5xx errors theo thời gian
grep " 50[0-9] " /var/log/nginx/access.log | awk '{print $4}' | cut -d: -f1-2 | uniq -c

6.3. Debug Slow Requests

# Tìm requests > 1 second (assuming request_time is logged)
awk '$NF > 1.0' /var/log/nginx/access.log

# Top 10 slowest requests
awk '{print $NF, $7}' /var/log/nginx/access.log | sort -rn | head -10

6.4. Debug High Traffic

# Requests per minute
awk '{print $4}' /var/log/nginx/access.log | cut -d: -f1-3 | uniq -c

# Identify traffic spikes
awk '{print $4}' /var/log/nginx/access.log | cut -d: -f1-3 | uniq -c | awk '$1 > 1000'

6.5. Debug Security Issues

# Tìm SQL injection attempts
grep -i "select.*from\|union.*select" /var/log/nginx/access.log

# Tìm path traversal attempts
grep "\.\." /var/log/nginx/access.log

# Suspicious user agents
grep -i "sqlmap\|nikto\|nmap" /var/log/nginx/access.log

7. Best Practices

7.1. Log Management

  1. Separate logs cho từng virtual host:
server {
    server_name site1.com;
    access_log /var/log/nginx/site1.access.log;
    error_log /var/log/nginx/site1.error.log;
}
  1. Sử dụng log levels phù hợp:
# Production: error hoặc warn
error_log /var/log/nginx/error.log warn;

# Development: info hoặc debug
error_log /var/log/nginx/error.log debug;
  1. Không log quá nhiều:
# Disable cho static files
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    access_log off;
}

# Disable cho health checks
location /health {
    access_log off;
    return 200;
}

7.2. Performance

  1. Buffer logs:
access_log /var/log/nginx/access.log combined buffer=32k;
  1. Async logging (Nginx 1.7.11+):
access_log /var/log/nginx/access.log combined buffer=32k flush=5s;

7.3. Security

  1. Protect log files:
sudo chmod 640 /var/log/nginx/*.log
sudo chown www-data:adm /var/log/nginx/*.log
  1. Rotate regularly:
# Daily rotation cho high-traffic sites
# Weekly cho low-traffic sites
  1. Monitor và alert:
# Setup monitoring cho error rates
# Alert khi có spikes bất thường

Tổng kết

Trong bài này, bạn đã học:

  • ✅ Access log và error log
  • ✅ Custom log formats và variables
  • ✅ Log rotation với logrotate
  • ✅ Phân tích logs và metrics
  • ✅ Troubleshooting với logs
  • ✅ Best practices cho logging

Bài tiếp theo: Chúng ta sẽ tìm hiểu về Reverse Proxy - cách sử dụng Nginx làm reverse proxy cho backend applications.

Nginx logging monitoring AccessLog ErrorLog Logrotate LogAnalysis troubleshooting Metrics Performance

Đánh dấu hoàn thành (Bài 3: Logging và Monitoring Nginx)