DeployEasy
Menu
ProductionTrung bình

Monitoring production: Log, healthcheck, CPU, RAM và cảnh báo

Hướng dẫn monitoring VPS và ứng dụng production bằng journalctl, Nginx log, PM2, Docker healthcheck, tài nguyên và cảnh báo.

· 7 phút đọc · 1.465 từ
Mục lục bài viết

Deploy thành công chỉ cho biết app hoạt động tại một thời điểm. Production cần phát hiện khi:

  • Website down.
  • API trả lỗi.
  • RAM cạn.
  • Disk đầy.
  • Container restart.
  • Database mất kết nối.
  • Chứng chỉ sắp hết hạn.
  • Backup không chạy.

Monitoring là quá trình thu thập tín hiệu, đánh giá trạng thái và gửi cảnh báo.

Bốn nhóm tín hiệu cơ bản

Availability

Dịch vụ có truy cập được không?

HTTP 200?
DNS hoạt động?
Port 443 mở?

Errors

HTTP 5xx
Exception
Database timeout
Container crash

Latency

p50
p95
p99

Average có thể che request rất chậm.

Saturation

CPU
RAM
Swap
Disk
Inode
Connection
Queue

Healthcheck là gì?

Healthcheck xác định service có hoạt động không.

GET /health
{
  "status": "ok"
}

HTTP:

200 OK

Liveness và readiness

Liveness

Process còn sống và không bị kẹt nghiêm trọng?

Readiness

Service đã sẵn sàng nhận request?

App có thể sống nhưng chưa ready vì database chưa kết nối hoặc migration chưa xong.

Khi cần, tách:

/health/live
/health/ready

Healthcheck không nên

  • Chạy query nặng.
  • Ghi dữ liệu.
  • Gọi quá nhiều service.
  • Lộ secret.
  • Luôn trả 200 dù dependency chết.

Kiểm tra bằng curl

curl \
  --fail \
  --silent \
  --show-error \
  https://api.deployeasy.vn/health

Xem timing:

curl \
  -o /dev/null \
  -s \
  -w 'status=%{http_code} time=%{time_total}\n' \
  https://api.deployeasy.vn/health

Systemd service

systemctl status nginx
systemctl status ssh
systemctl status postgresql
systemctl --failed

systemctl dùng để kiểm tra và điều khiển systemd service.

Journalctl

Log service:

sudo journalctl -u nginx

Realtime:

sudo journalctl -u nginx -f

Trong 30 phút:

sudo journalctl -u nginx --since "30 minutes ago"

Chỉ lỗi:

sudo journalctl -p err --since today

Boot hiện tại:

sudo journalctl -b

Boot trước:

sudo journalctl -b -1

Dung lượng:

journalctl --disk-usage

Không xóa log ngay khi sự cố xảy ra.

Nginx log

/var/log/nginx/access.log
/var/log/nginx/error.log

Theo dõi:

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

Lọc 5xx theo log format mặc định:

awk '$9 ~ /^5/' /var/log/nginx/access.log | tail

Field có thể khác nếu log format đã đổi.

Log riêng:

access_log /var/log/nginx/deployeasy.access.log;
error_log /var/log/nginx/deployeasy.error.log;

PM2 monitoring

pm2 list
pm2 monit
pm2 logs
pm2 logs deployeasy-api --lines 200

Theo dõi:

  • Status.
  • Restart count.
  • CPU.
  • Memory.
  • Uptime.

Restart count tăng liên tục cần điều tra.

Docker monitoring

docker compose ps
docker compose logs -f
docker stats

Health:

docker inspect \
  --format='{{json .State.Health}}' \
  CONTAINER_NAME | jq

Restart:

docker inspect \
  --format='{{.RestartCount}}' \
  CONTAINER_NAME

Container running chưa chắc app healthy.

Docker healthcheck

services:
  api:
    healthcheck:
      test:
        [
          "CMD",
          "node",
          "-e",
          "fetch('http://127.0.0.1:3000/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))",
        ]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 20s

Command healthcheck phải tồn tại trong image.

CPU và load

uptime
top
htop
nproc

Load average không bằng trực tiếp phần trăm CPU. Cần xem số CPU, I/O wait và process.

RAM và swap

free -h
vmstat 1

Tìm OOM:

sudo journalctl -k | grep -i -E 'out of memory|killed process'

Hoặc:

dmesg --ctime | grep -i -E 'out of memory|killed process'

Exit code 137 thường liên quan SIGKILL; OOM là nguyên nhân phổ biến nhưng không phải duy nhất.

Disk

df -h
du -sh /var/log/*
du -sh /var/lib/docker/*

Tìm thư mục lớn:

sudo du -xhd1 / | sort -h

Tránh quét sâu vào giờ cao điểm nếu I/O hạn chế.

Inode

df -i

Có thể còn GB trống nhưng không tạo file được vì hết inode.

Docker disk

docker system df

Dọn có chọn lọc:

docker image prune
docker builder prune

Không prune toàn bộ production thiếu kiểm soát.

Network và port

sudo ss -tulpn
sudo ss -s
dig deployeasy.vn
curl -Iv https://deployeasy.vn

PostgreSQL

sudo -u postgres psql -c "SELECT now();"

Docker:

docker compose exec database \
  pg_isready \
  -U deployeasy \
  -d deployeasy

Theo dõi:

  • Connection.
  • Query chậm.
  • Lock.
  • Disk.
  • Backup.
  • Autovacuum.

Structured log

Thay vì:

Something failed

Dùng:

{
  "level": "error",
  "message": "Database connection failed",
  "service": "deployeasy-api",
  "requestId": "abc123",
  "timestamp": "2026-07-10T03:00:00Z"
}

Không log:

  • Password.
  • Token.
  • Cookie.
  • Private key.
  • Secret env.
  • Dữ liệu cá nhân không cần thiết.

Request ID

X-Request-ID: abc123

Dùng cùng request ID ở Nginx và API để theo dõi request qua hệ thống.

Log level

debug
info
warn
error
fatal

Không bật debug liên tục trên production vì log nhiều và có thể lộ dữ liệu.

Log rotation

Nginx:

ls /etc/logrotate.d/

PM2:

pm2 install pm2-logrotate

Docker:

logging:
  driver: json-file
  options:
    max-size: "10m"
    max-file: "3"

Journal:

journalctl --disk-usage

Uptime monitoring bên ngoài

Monitoring ngay trên VPS không phát hiện được khi toàn VPS mất mạng.

Dùng một dịch vụ hoặc máy khác kiểm tra:

https://deployeasy.vn/health

Cảnh báo qua email, chat hoặc hệ thống incident.

Dùng retry trước cảnh báo để giảm false alarm.

Alert phải actionable

Tốt:

API production trả 5xx 12% trong 5 phút,
dashboard..., runbook...

Kém:

Something wrong

Mỗi alert cần:

  • Service.
  • Environment.
  • Metric.
  • Threshold.
  • Thời gian.
  • Link log.
  • Hành động ban đầu.

Threshold tham khảo

Disk > 80%: warning
Disk > 90%: critical
Healthcheck fail nhiều lần: critical
Certificate < 14 ngày: warning
Backup quá hạn: critical
Restart count tăng: warning

Điều chỉnh theo hệ thống thực tế.

Monitoring chứng chỉ

echo | openssl s_client \
  -servername deployeasy.vn \
  -connect deployeasy.vn:443 2>/dev/null |
openssl x509 -noout -enddate

Certbot timer vẫn có thể lỗi, nên cần kiểm tra độc lập.

Monitoring backup

Kiểm tra:

  • File mới nhất.
  • Kích thước.
  • Upload offsite.
  • Exit code.
  • Restore test.

Ví dụ tìm backup trong 25 giờ:

find /var/backups/deployeasy \
  -type f \
  -name '*.dump' \
  -mmin -1500 \
  -print

Runbook website down

1. Xác nhận từ mạng ngoài
2. Kiểm tra DNS
3. Kiểm tra HTTPS
4. Kiểm tra Nginx
5. Kiểm tra app/container
6. Kiểm tra database
7. Kiểm tra RAM/disk
8. Xem log đúng thời điểm
9. Rollback nếu do deploy
10. Ghi timeline

Lệnh nhanh:

curl -Iv https://deployeasy.vn
sudo systemctl status nginx
pm2 list
docker compose ps
free -h
df -h
sudo journalctl -p err --since "30 minutes ago"

Chỉ chạy lệnh phù hợp với stack.

Sau sự cố

Postmortem:

Sự cố gì?
Bắt đầu lúc nào?
Phát hiện ra sao?
Ảnh hưởng ai?
Nguyên nhân gốc?
Điều gì kéo dài sự cố?
Khắc phục tạm thời?
Hành động phòng ngừa?
Ai phụ trách?

Không dùng postmortem để đổ lỗi cá nhân.

Stack theo giai đoạn

Ban đầu

Healthcheck
Journal/PM2/Docker logs
Uptime monitor ngoài VPS
Disk/RAM alert
Backup alert

Trung bình

Metrics
Dashboard
Centralized logs
Error tracking
Alert routing

Lớn

Tracing
SLO/SLI
On-call
Incident management
Capacity planning

Không cần cài stack phức tạp chỉ cho một blog tĩnh.

Checklist

[ ] Health endpoint
[ ] External uptime monitor
[ ] Nginx error log
[ ] Structured app log
[ ] Secret được che
[ ] Restart alert
[ ] CPU/RAM/swap
[ ] Disk và inode
[ ] Database readiness
[ ] Certificate expiry
[ ] Backup freshness
[ ] Log rotation
[ ] Alert có runbook
[ ] Rollback procedure
[ ] Postmortem

Câu hỏi thường gặp

Log có phải monitoring không?

Log là một tín hiệu. Monitoring còn có metric, healthcheck và alert.

Container running có nghĩa app tốt không?

Không. App có thể chạy nhưng endpoint lỗi hoặc database down.

Website ít người dùng có cần monitoring không?

Có, nhưng bắt đầu đơn giản với uptime, disk, backup và certificate.

Có nên tự restart khi healthcheck fail?

Có thể, nhưng restart liên tục có thể che lỗi. Cần giới hạn và cảnh báo.

Kết luận

Monitoring tốt giúp phát hiện sớm, chẩn đoán nhanh và phục hồi có kiểm soát. Bắt đầu từ healthcheck, log, tài nguyên và backup.

Nguồn tham khảo

Đọc tiếp