Giảm chi phí CloudWatch Logs mà vẫn đủ dữ liệu để debug
CloudWatch Logs tính phí ở ingestion, storage và query. Bài viết đi qua cách tìm log group tốn kém nhất, giảm log tại nguồn, đặt retention và khi nào nên dùng Infrequent Access.
CloudWatch Logs thường không phải dòng chi phí lớn nhất khi hệ thống còn nhỏ. Khi số service, số pod và số Lambda function tăng lên, nó trở thành một khoản đáng kể, và việc cắt giảm thường gặp phản đối hợp lý từ đội vận hành: log là thứ họ cần khi có sự cố. Bài viết này giải thích CloudWatch Logs tính phí ở đâu, những thay đổi nào giảm chi phí mà không làm mất dữ liệu cần thiết để debug, và cách xác định nên bắt đầu từ log group nào.
CloudWatch Logs tính phí ở ba chỗ
Chi phí CloudWatch Logs gồm ba phần chính, và tỷ trọng giữa chúng quyết định nên tối ưu ở đâu:
- Ingestion: phí cho mỗi GB log được đẩy vào CloudWatch. Tại us-east-1, mức giá cho log class Standard là $0.50/GB. Với hầu hết hệ thống, đây là phần lớn nhất.
- Storage: phí lưu trữ log đã nén, khoảng $0.03/GB-tháng. Phần này nhỏ theo từng tháng, nhưng tích lũy dần vì retention mặc định của log group là không bao giờ hết hạn.
- Query: CloudWatch Logs Insights tính phí theo lượng dữ liệu được quét, $0.005/GB. Một dashboard hoặc alert chạy query trên khoảng thời gian dài với tần suất cao có thể tạo ra khoản phí bất ngờ.
Free tier hàng tháng gồm 5 GB dữ liệu, tính chung cho ingestion, storage và dữ liệu quét bởi Logs Insights. Với hệ thống production, mức này gần như không đáng kể.
Một cluster EKS có 40 service, trung bình mỗi service ghi 3 GB log mỗi ngày ở mức DEBUG:
Ingestion: 40 × 3 GB × 30 ngày = 3.600 GB × $0.50 ≈ $1.800 / tháng
Storage: tích lũy thêm mỗi tháng vì không đặt retentionNếu chuyển phần lớn service về mức INFO và log lượng nhỏ hơn khoảng 70%, ingestion còn khoảng $540 mỗi tháng. Con số thực tế phụ thuộc vào mức độ log của từng service, nên cần đo trước khi ước tính.
Bước 1: Tìm log group chiếm nhiều chi phí nhất
Trong hầu hết hệ thống, một số ít log group chiếm phần lớn lượng ingestion. Có hai cách để tìm chúng:
- Cost and Usage Report: lọc theo service CloudWatch và các usage type liên quan tới ingestion log (thường chứa
DataProcessing-Bytes), sau đó nhóm theo resource. Cách này cho biết chính xác số tiền theo từng log group. - Metric của CloudWatch Logs: mỗi log group có metric
IncomingBytestrong namespaceAWS/Logs. Sắp xếp các log group theo tổngIncomingBytestrong 30 ngày cho một danh sách đủ tốt để bắt đầu.
Khi đã có danh sách, hãy mở vài log group đứng đầu và đọc thử log thực tế. Chúng tôi thường gặp các trường hợp sau: health check được log ở mỗi request, log DEBUG được bật từ một lần điều tra sự cố cũ và chưa tắt, toàn bộ request và response body được ghi lại, hoặc stack trace lặp lại hàng nghìn lần cho cùng một lỗi.
Bước 2: Giảm lượng log tại nguồn
Đây là thay đổi có tác động lớn nhất, vì ingestion được tính theo mỗi GB đi vào CloudWatch. Mọi GB không được ghi ra là một GB không phải trả phí ingestion, storage hay query.
- Đặt log level phù hợp theo môi trường. Production nên chạy ở mức INFO hoặc WARN theo mặc định, và có cơ chế bật DEBUG tạm thời cho một service cụ thể qua config thay vì phải deploy lại.
- Bỏ log cho health check và các endpoint nội bộ. Request từ load balancer hoặc Kubernetes probe thường chiếm một phần lớn số dòng log mà không có giá trị khi debug.
- Sampling cho log có lưu lượng cao. Với những request thành công và lặp lại, ghi lại một phần nhỏ (ví dụ 1–5%) thường đủ để thấy xu hướng. Request lỗi vẫn nên được ghi đầy đủ.
- Không ghi toàn bộ payload. Ghi request ID, các trường quan trọng và kích thước payload thay vì toàn bộ body. Việc này còn giảm rủi ro ghi dữ liệu nhạy cảm vào log.
Với EKS, cần kiểm tra thêm cấu hình của agent thu thập log như Fluent Bit. Agent mặc định thường gửi toàn bộ stdout của mọi container, bao gồm cả các system pod. Bộ lọc ở tầng agent cho phép loại bỏ namespace hoặc pattern không cần thiết trước khi dữ liệu tới CloudWatch. Container Insights cũng tạo ra lượng log hiệu năng riêng, và nên được đánh giá xem đội có thực sự dùng nó hay không.
Bước 3: Đặt retention cho từng log group
Retention mặc định của log group là không bao giờ hết hạn, nên log từ nhiều năm trước vẫn đang được tính phí storage. Đặt retention là thay đổi ít rủi ro nhất trong bài này, và nên được quản lý trong IaC để log group mới không bị bỏ sót.
resource "aws_cloudwatch_log_group" "api" {
name = "/ecs/api"
retention_in_days = 30
}Thời gian retention nên dựa trên mục đích của log. Log ứng dụng dùng để debug thường chỉ cần 14 đến 30 ngày. Log phục vụ audit hoặc yêu cầu tuân thủ có thể cần lưu một năm hoặc lâu hơn, nhưng trong trường hợp đó, lưu chúng ở S3 thường rẻ hơn nhiều so với giữ trong CloudWatch.
Bước 4: Cân nhắc log class Infrequent Access
CloudWatch Logs có log class Infrequent Access với giá ingestion bằng một nửa Standard, $0.25/GB tại us-east-1. Đổi lại, log group dùng class này không hỗ trợ một số tính năng quan trọng:
- Truy vấn bằng CloudWatch Logs Insights
- Export log sang S3
- Mã hóa bằng KMS và chia sẻ cross-account
- Data protection để che dữ liệu nhạy cảm
- Subscription filter và metric filter
- Live Tail
- Xem log trực tiếp bằng GetLogEvents hoặc FilterLogEvents
- Embedded metric format và anomaly detection
Điểm cần lưu ý là log class không thể thay đổi sau khi log group được tạo. Để chuyển một log group sang Infrequent Access, bạn phải tạo log group mới và cấu hình lại nơi ghi log.
Infrequent Access phù hợp với log ít khi được đọc và không có alert hay metric phụ thuộc vào chúng, ví dụ log audit, log của các job batch hoặc log chỉ được tra cứu khi điều tra sự cố. Với log group mà đội đang dùng metric filter để tạo alarm, chuyển sang Infrequent Access sẽ làm mất các alarm đó.
Bước 5: Kiểm tra subscription filter và đường đi của log
Nhiều hệ thống đẩy log từ CloudWatch sang một công cụ khác như OpenSearch, Datadog hoặc một SIEM thông qua subscription filter. Trong trường hợp đó, bạn đang trả phí ingestion ở CloudWatch, cộng với chi phí Lambda hoặc Kinesis Data Firehose để chuyển log, cộng với phí ingestion ở công cụ đích.
Nếu CloudWatch chỉ đóng vai trò trung chuyển, việc gửi log trực tiếp từ agent tới đích, hoặc ghi vào S3 qua Firehose, có thể loại bỏ hoàn toàn phần ingestion ở CloudWatch. Ngược lại, nếu đội chủ yếu tra cứu log trong CloudWatch, có thể không cần duy trì một bản sao đầy đủ ở công cụ thứ hai.
Với log cần lưu lâu dài nhưng hiếm khi truy vấn, lưu trên S3 và truy vấn bằng Athena khi cần thường là cách rẻ nhất. Chi phí lưu trữ trên S3 thấp hơn đáng kể, và có thể kết hợp lifecycle để chuyển dữ liệu cũ sang các storage class rẻ hơn.
Lambda và vended logs
Một số service của AWS ghi log theo dạng vended logs, với giá ingestion giảm dần theo bậc khi lượng log tăng. Tại us-east-1, bậc đầu tiên tới 10 TB có giá $0.50/GB, sau đó giảm xuống $0.25, $0.10 và $0.05/GB ở các bậc cao hơn. Log của Lambda hiện cũng được tính theo cách này, và Lambda có thêm tùy chọn gửi log trực tiếp tới S3 hoặc Firehose. Với các hệ thống dùng Lambda ở quy mô lớn, nên xem lại cách tính hiện tại trên trang giá của CloudWatch thay vì dựa vào ước tính cũ.
Tóm lại
Phần lớn chi phí CloudWatch Logs đến từ ingestion, nên thay đổi hiệu quả nhất là giảm lượng log tại nguồn: log level phù hợp, bỏ log health check, sampling cho request thành công và không ghi toàn bộ payload. Sau đó, đặt retention cho mọi log group, cân nhắc Infrequent Access cho log ít được đọc, và kiểm tra xem log có đang bị trả phí hai lần qua subscription filter hay không. Những thay đổi này giữ lại đủ dữ liệu để debug, vì log lỗi và log quan trọng vẫn được ghi đầy đủ, trong khi phần bị loại bỏ chủ yếu là log lặp lại mà đội gần như không bao giờ đọc.