Khi một ứng dụng gặp sự cố, câu hỏi đầu tiên của đội vận hành thường là:
Trong nhiều hệ thống cũ, mỗi ứng dụng tự ghi log vào một thư mục riêng:
/var/log/app.log
C:\Logs\application.log
Ban đầu điều này có vẻ hợp lý.
Nhưng khi hệ thống có hàng chục Microservices và hàng trăm Container, việc đăng nhập vào từng máy để tìm log gần như không còn khả thi.
Đó là lý do Yếu tố thứ 11 của 12-Factor App đưa ra một nguyên tắc rất quan trọng:
Hay nói cách khác:
Log không chỉ là một file
Nhiều người vẫn xem Log đơn giản là:
application.log
Theo 12-Factor App, đây chỉ là định dạng lưu trữ cuối cùng.
Bản chất của Log là:
Nói cách khác, Log giống như một dòng sự kiện đang chảy liên tục (Event Stream) chứ không phải một tệp văn bản tĩnh.
Ứng dụng chỉ cần ghi ra stdout
Theo 12-Factor App, ứng dụng không nên quan tâm log sẽ được lưu ở đâu.
Mỗi Process chỉ cần ghi Log ra:
Ví dụ:
Application
│
stdout / stderr
│
▼
Operating System
Từ thời điểm đó, việc thu thập và xử lý Log sẽ do hệ điều hành hoặc nền tảng triển khai đảm nhiệm.
Điều này giúp ứng dụng không phụ thuộc vào cách lưu trữ Log của từng môi trường.
UNIX đã làm việc này rất tốt
Các hệ điều hành UNIX/Linux từ lâu đã cung cấp cơ chế xử lý các luồng dữ liệu chuẩn.
Log ghi ra stdout hoặc stderr có thể được:
Ứng dụng không cần biết những việc này diễn ra như thế nào. Nó chỉ cần tiếp tục ghi Log ra luồng chuẩn.
Syslog là gì?
Syslog là một chuẩn ghi Log rất phổ biến trên các hệ thống UNIX/Linux.
Không chỉ máy chủ ứng dụng, nhiều thiết bị cũng có thể gửi Log về Syslog như:
Nhờ đó, doanh nghiệp có thể tập trung Log từ nhiều hệ thống khác nhau về một nơi để phục vụ giám sát, phân tích và điều tra sự cố.
Vì sao không nên để ứng dụng tự ghi Log vào file?
Nếu ứng dụng tự quyết định:
Write Log
│
▼
application.log
thì sẽ phát sinh nhiều vấn đề:
Đặc biệt trong Kubernetes, Container có thể bị thay thế bất cứ lúc nào. Nếu Log chỉ tồn tại trong hệ thống tệp của Container, chúng có thể biến mất khi Container bị xóa.
Log Management là việc của nền tảng
Trong kiến trúc Cloud Native, ứng dụng chỉ tạo Log.
Việc còn lại do nền tảng đảm nhận.
Ví dụ:
Application
│
stdout
│
▼
Container Runtime
│
▼
Log Collector
│
▼
Central Log System
Nhờ cách tiếp cận này, cùng một ứng dụng có thể được triển khai trên nhiều môi trường mà không cần thay đổi cách ghi Log.
DevSecOps và Event Streams
Khi Log được xem là Event Stream, doanh nghiệp có thể:
Điều quan trọng là ứng dụng không cần biết Log sẽ được lưu ở đâu hoặc phân tích như thế nào. Trách nhiệm của ứng dụng là ghi các sự kiện ra stdout hoặc stderr, còn việc thu thập, lưu trữ và xử lý sẽ do hạ tầng đảm nhiệm.
Đây là một nguyên tắc cốt lõi của 12-Factor App và cũng là nền tảng của các hệ thống Cloud Native hiện đại: tách biệt hoàn toàn ứng dụng khỏi cơ chế quản lý Log, giúp việc triển khai, mở rộng và vận hành trở nên linh hoạt hơn mà không phải thay đổi mã nguồn.
"Log đâu?"
Trong nhiều hệ thống cũ, mỗi ứng dụng tự ghi log vào một thư mục riêng:
/var/log/app.log
C:\Logs\application.log
Ban đầu điều này có vẻ hợp lý.
Nhưng khi hệ thống có hàng chục Microservices và hàng trăm Container, việc đăng nhập vào từng máy để tìm log gần như không còn khả thi.
Đó là lý do Yếu tố thứ 11 của 12-Factor App đưa ra một nguyên tắc rất quan trọng:
Treat Logs as Event Streams.
Hay nói cách khác:
Ứng dụng chỉ tạo ra Log. Việc lưu trữ, thu thập và phân tích Log là trách nhiệm của nền tảng vận hành.
Log không chỉ là một file
Nhiều người vẫn xem Log đơn giản là:
application.log
Theo 12-Factor App, đây chỉ là định dạng lưu trữ cuối cùng.
Bản chất của Log là:
- Chuỗi sự kiện (Events).
- Có dấu thời gian (Timestamp).
- Được tạo ra liên tục.
- Không có điểm bắt đầu hay kết thúc.
Nói cách khác, Log giống như một dòng sự kiện đang chảy liên tục (Event Stream) chứ không phải một tệp văn bản tĩnh.
Ứng dụng chỉ cần ghi ra stdout
Theo 12-Factor App, ứng dụng không nên quan tâm log sẽ được lưu ở đâu.
Mỗi Process chỉ cần ghi Log ra:
- stdout (Standard Output)
- stderr (Standard Error)
Ví dụ:
Application
│
stdout / stderr
│
▼
Operating System
Từ thời điểm đó, việc thu thập và xử lý Log sẽ do hệ điều hành hoặc nền tảng triển khai đảm nhiệm.
Điều này giúp ứng dụng không phụ thuộc vào cách lưu trữ Log của từng môi trường.
UNIX đã làm việc này rất tốt
Các hệ điều hành UNIX/Linux từ lâu đã cung cấp cơ chế xử lý các luồng dữ liệu chuẩn.
Log ghi ra stdout hoặc stderr có thể được:
- Hiển thị trực tiếp trên Terminal khi phát triển.
- Chuyển hướng (Redirect) vào một tệp nếu cần.
- Theo dõi theo thời gian thực bằng các công cụ của hệ điều hành.
- Gửi tới hệ thống phân tích Log.
- Chuyển đến một Syslog Server tập trung.
Ứng dụng không cần biết những việc này diễn ra như thế nào. Nó chỉ cần tiếp tục ghi Log ra luồng chuẩn.
Syslog là gì?
Syslog là một chuẩn ghi Log rất phổ biến trên các hệ thống UNIX/Linux.
Không chỉ máy chủ ứng dụng, nhiều thiết bị cũng có thể gửi Log về Syslog như:
- Router.
- Switch.
- Firewall.
- Máy in.
- Máy chủ Linux.
- Nhiều ứng dụng khác.
Nhờ đó, doanh nghiệp có thể tập trung Log từ nhiều hệ thống khác nhau về một nơi để phục vụ giám sát, phân tích và điều tra sự cố.
Vì sao không nên để ứng dụng tự ghi Log vào file?
Nếu ứng dụng tự quyết định:
Write Log
│
▼
application.log
thì sẽ phát sinh nhiều vấn đề:
- Khó thay đổi cơ chế lưu trữ.
- Khó thu thập Log từ nhiều máy chủ.
- Khó triển khai trong môi trường Container.
- Khó tích hợp với các nền tảng giám sát.
Đặc biệt trong Kubernetes, Container có thể bị thay thế bất cứ lúc nào. Nếu Log chỉ tồn tại trong hệ thống tệp của Container, chúng có thể biến mất khi Container bị xóa.
Log Management là việc của nền tảng
Trong kiến trúc Cloud Native, ứng dụng chỉ tạo Log.
Việc còn lại do nền tảng đảm nhận.
Ví dụ:
Application
│
stdout
│
▼
Container Runtime
│
▼
Log Collector
│
▼
Central Log System
Nhờ cách tiếp cận này, cùng một ứng dụng có thể được triển khai trên nhiều môi trường mà không cần thay đổi cách ghi Log.
DevSecOps và Event Streams
Khi Log được xem là Event Stream, doanh nghiệp có thể:
- Theo dõi ứng dụng theo thời gian thực.
- Thu thập Log từ nhiều máy chủ hoặc Container.
- Phân tích sự cố nhanh hơn.
- Hỗ trợ kiểm toán (Audit).
- Kết hợp Log với các hệ thống giám sát và cảnh báo.
Điều quan trọng là ứng dụng không cần biết Log sẽ được lưu ở đâu hoặc phân tích như thế nào. Trách nhiệm của ứng dụng là ghi các sự kiện ra stdout hoặc stderr, còn việc thu thập, lưu trữ và xử lý sẽ do hạ tầng đảm nhiệm.
Đây là một nguyên tắc cốt lõi của 12-Factor App và cũng là nền tảng của các hệ thống Cloud Native hiện đại: tách biệt hoàn toàn ứng dụng khỏi cơ chế quản lý Log, giúp việc triển khai, mở rộng và vận hành trở nên linh hoạt hơn mà không phải thay đổi mã nguồn.