Remote Logging là cơ chế gửi log từ thiết bị di động đến máy chủ từ xa để phân tích và giám sát tập trung. Không giống như ghi log cục bộ lưu trữ dữ liệu trên thiết bị, thu thập từ xa cho phép xem lỗi và bất thường từ tất cả thiết bị người dùng trong thời gian thực. Theo Sentry Resource Library, các ứng dụng có remote logging tìm thấy 92% lỗi sản xuất trong giờ đầu tiên sau khi phát hành so với 15% khi chỉ sử dụng báo cáo sự cố. Đây là công cụ bắt buộc cho bất kỳ nhóm phát triển di động nào: Firebase Crashlytics, Sentry và Datadog cung cấp SDK sẵn sàng cho iOS và Android.
Những điểm chính
Remote Logging là quá trình thu thập log từ các thiết bị từ xa và truyền chúng đến máy chủ trung tâm để phân tích. Trong bối cảnh phát triển di động, remote logging không chỉ bao gồm báo cáo sự cố mà còn cả sự kiện tùy chỉnh, breadcrumbs, chỉ số hiệu suất và kịch bản người dùng.
Sự khác biệt chính giữa remote logging và crash reporting là tính chủ động. Crash reporting chỉ thu thập dữ liệu về các sự cố ứng dụng đã xảy ra. Remote logging thu thập chuỗi sự kiện trước sự cố: người dùng đã mở màn hình nào, đã thực hiện yêu cầu nào, đã nhập dữ liệu nào. Điều này cho phép tái tạo kịch bản lỗi mà không cần giao tiếp với người dùng.
Apple cung cấp cơ chế tích hợp để thu thập log từ xa qua .logarchive, nhưng đối với ứng dụng sản xuất, hầu như luôn sử dụng dịch vụ của bên thứ ba. Android SDK bao gồm Logcat, có thể truy cập từ xa qua ADB, nhưng không dành cho thiết bị người dùng cuối không có chế độ gỡ lỗi.
Kiến trúc remote logging bao gồm ba thành phần: SDK khách trên thiết bị thu thập và lưu đệm log, giao thức truyền tải để gửi dữ liệu và máy chủ để lưu trữ và hiển thị.
| Thành phần | Vai trò | Ví dụ |
|---|---|---|
| SDK khách | Thu thập, lưu đệm, batching | Firebase SDK, Sentry Cocoa, Timber |
| Truyền tải | Truyền dữ liệu qua HTTPS | REST, gRPC, WebSocket |
| Máy chủ | Lưu trữ, lập chỉ mục, cảnh báo | Sentry, Crashlytics, Datadog |
SDK khách lưu đệm log trong RAM và định kỳ gửi chúng đến máy chủ theo lô. Nếu thiết bị ngoại tuyến, log được lưu vào tệp cục bộ và gửi khi có kết nối mạng tiếp theo. Kích thước bộ đệm và khoảng thời gian gửi có thể cấu hình: giá trị điển hình là 50 sự kiện hoặc 30 giây.
HTTPS REST là giao thức phổ biến nhất cho remote logging. SDK tuần tự hóa log thành JSON và gửi qua các yêu cầu POST đến điểm cuối của máy chủ. gRPC là một giải pháp thay thế với tuần tự hóa nhị phân (Protocol Buffers), nhỏ gọn hơn JSON 30–40% và nhanh hơn trên thiết bị di động có kết nối không ổn định. WebSocket được sử dụng để ghi log thời gian thực khi gỡ lỗi nhưng hiếm khi dùng trong sản xuất do tiêu thụ điện năng.
Firebase Crashlytics là dịch vụ miễn phí của Google để thu thập báo cáo sự cố và log tùy chỉnh. Nó được tích hợp trong Firebase SDK và không yêu cầu máy chủ riêng. Crashlytics tự động thu thập stack trace, trạng thái thiết bị, phiên bản hệ điều hành và màn hình đang mở tại thời điểm sự cố.
Log tùy chỉnh trong Crashlytics được thêm qua phương thức log() — chúng không được gửi đến máy chủ ngay lập tức mà được lưu trong bộ đệm vòng và đính kèm vào báo cáo sự cố tiếp theo. Đây là điểm khác biệt chính so với Sentry, nơi mỗi log là một sự kiện riêng biệt. Khối lượng tối đa của log tùy chỉnh trong Crashlytics là 64 KB cho mỗi sự cố.
// Firebase Crashlytics — log tùy chỉnh trên Android
import com.google.firebase.crashlytics.FirebaseCrashlytics
class CheckoutViewModel {
fun processPayment(amount: Double) {
FirebaseCrashlytics.getInstance()
.log("Payment started: amount=$amount")
try {
process(amount)
} catch (e: Exception) {
FirebaseCrashlytics.getInstance()
.recordException(e)
}
}
}
Firebase Crashlytics hỗ trợ setUserIdentifier để liên kết sự cố với người dùng cụ thể. Điều này giúp xác định lỗi là phổ biến hay chỉ ảnh hưởng đến một người dùng. setCustomKey thêm các khóa tùy ý vào mỗi báo cáo — phiên bản thử nghiệm A/B, khu vực, gói cước.
Sentry là nền tảng giám sát lỗi lưu trữ không chỉ báo cáo sự cố mà còn tất cả sự kiện tùy chỉnh (breadcrumbs) dưới dạng bản ghi độc lập. Không giống như Crashlytics, Sentry cho phép xem chuỗi sự kiện trước lỗi theo thứ tự thời gian — breadcrumbs hiển thị trong giao diện mà không cần tái tạo từ log sự cố.
SDK Sentry tự động thu thập breadcrumbs cho các sự kiện hệ thống: thay đổi vòng đời UIViewController (viewDidLoad, viewWillAppear), chạm, nhấn nút, yêu cầu HTTP qua URLSession. Tất cả các sự kiện này xuất hiện trong dòng thời gian lỗi cùng với breadcrumbs tùy chỉnh. Đối với Android, vòng đời Activity và Fragment, sự kiện onClick và yêu cầu mạng qua OkHttp được thu thập tương tự.
SDK Sentry cho iOS và Android tự động thu thập breadcrumbs của sự kiện UI: chạm, điều hướng, vòng đời. Nhà phát triển có thể thêm breadcrumbs tùy chỉnh qua addBreadcrumb() với loại, danh mục và cấp độ. Sentry hỗ trợ distributed tracing: trình ghi log liên kết breadcrumbs phía máy khách với yêu cầu backend qua ID truy vết.
import Sentry
func trackCartEvent(action: String, itemId: String) {
let crumb = Breadcrumb()
crumb.level = .info
crumb.category = "cart"
crumb.message = "Cart \(action): \(itemId)"
crumb.data = ["action": action, "item_id": itemId]
SentrySDK.addBreadcrumb(crumb)
}
Logcat là hệ thống ghi log tiêu chuẩn của Android, có thể truy cập qua Android Debug Bridge (ADB). Logcat thu thập tất cả thông báo hệ thống và ứng dụng, được tổ chức theo cấp độ (V, D, I, W, E, F) và thẻ. Truy cập từ xa vào Logcat hoạt động qua ADB qua USB hoặc Wi-Fi, nhưng chỉ dành cho thiết bị ở chế độ gỡ lỗi — ứng dụng sản xuất trên thiết bị không có kết nối USB không thể truy cập được.
Để ghi log từ xa trong sản xuất trên Android, các giải pháp thay thế được sử dụng: Logcat tự nó không thể gửi log đến máy chủ. Vai trò của nó là chẩn đoán cục bộ. Tuy nhiên, có các wrapper (Timber, LogcatLive) chuyển tiếp thông báo đến Firebase hoặc Sentry trong khi vẫn giữ API quen thuộc Log.d / Log.e. Timber cho phép chuyển đổi trình xử lý mà không thay đổi mã ứng dụng — cây gỡ lỗi ghi vào Logcat, cây phát hành gửi đến máy chủ với batching và nén.
Batching là nhóm nhiều log thành một yêu cầu HTTP duy nhất để tiết kiệm lưu lượng và pin. Thay vì 50 yêu cầu POST riêng lẻ, SDK gửi một mảng JSON duy nhất. Các chiến lược điển hình: gửi theo lịch trình (mỗi 30 giây), theo số lượng (mỗi 50 sự kiện) hoặc theo sự kiện (chỉ khi có lỗi nghiêm trọng).
Đối với ứng dụng có hàng triệu người dùng, khối lượng log có thể đạt đến terabyte mỗi ngày. Batching giảm số lượng yêu cầu từ 10–50 lần và giảm tải máy chủ. Sentry sử dụng nén gzip ở cấp độ truyền tải, giúp giảm thêm khối lượng dữ liệu từ 60–70%.
// Triển khai batching đơn giản trên Android
class LogBatcher {
private val buffer = mutableListOf<LogEvent>()
private val maxSize = 50
private val intervalMs = 30_000L
fun append(event: LogEvent) {
buffer.add(event)
if (buffer.size >= maxSize) flush()
}
suspend fun flush() {
val batch = buffer.toList()
buffer.clear()
sendToServer(batch)
}
}
gzip là phương pháp nén tiêu chuẩn cho truyền tải HTTP của log. SDK Sentry và Crashlytics tự động nén nội dung yêu cầu trước khi gửi. Khử trùng lặp — loại bỏ thông báo trùng lặp ở phía máy khách: nếu cùng một sự kiện xảy ra 100 lần mỗi giây, SDK gửi nó một lần với trường count = 100.
Lỗi phổ biến nhất là ghi log dữ liệu nhạy cảm. Các SDK remote logging truyền dữ liệu đến máy chủ và nếu nhà phát triển vô tình ghi log mật khẩu, token hoặc email người dùng, dữ liệu này sẽ nằm trong cơ sở hạ tầng đám mây. Luôn sử dụng bộ lọc PII (Thông tin Nhận dạng Cá nhân) ở cấp SDK: Sentry có hook beforeSend tích hợp để làm sạch dữ liệu trước khi gửi.
Vấn đề phổ biến thứ hai là ghi log quá mức. Nếu mọi chuyển động ngón tay đều được gửi đến máy chủ, khối lượng dữ liệu tăng theo cấp số nhân và chi phí máy chủ cũng tăng. Hãy đặt ngân sách ghi log: không quá 1–5 sự kiện cho mỗi người dùng mỗi phút trong sản xuất. Chỉ gửi log gỡ lỗi với cờ được bật cho các thiết bị cụ thể.
Lỗi thứ ba là bỏ qua kịch bản ngoại tuyến. Nếu SDK mất log khi không có mạng và không khôi phục chúng khi kết nối lại, remote logging sẽ vô ích đối với người dùng có kết nối không ổn định. Tất cả SDK (Firebase, Sentry) tự động lưu log vào tệp cục bộ và gửi khi có mạng, nhưng cần kiểm tra cài đặt này.
Câu hỏi thường gặp
Crash reporting chỉ thu thập thông tin về sự cố ứng dụng. Remote Logging thu thập tất cả sự kiện: log tùy chỉnh, breadcrumbs, chỉ số hiệu suất, sự kiện UI. Crash reporting là tập con của remote logging, không phải là giải pháp thay thế.
Crashlytics miễn phí và đủ cho báo cáo sự cố cơ bản. Sentry tốt hơn nếu bạn cần breadcrumbs, distributed tracing, bảng điều khiển tùy chỉnh và cảnh báo linh hoạt. Đối với dự án doanh nghiệp có yêu cầu tuân thủ, Sentry có sẵn phiên bản tự lưu trữ.
Sử dụng cấp độ ghi log: chỉ gửi log debug/info từ thiết bị nhà phát triển qua cờ isDebuggable. Lọc các cấp độ khác (warn, error) qua hook beforeSend, loại bỏ trường chứa PII. Xác định kích thước log tối đa cho mỗi phiên.
Logcat không hỗ trợ gửi từ xa đến máy chủ. Để remote logging trên Android, sử dụng Timber để chuyển tiếp đến Firebase hoặc Sentry và giữ Logcat để gỡ lỗi qua USB. Timber thay thế API Log của Android và thêm các cây có thể trồng.
Tối đa 50 sự kiện mỗi phút cho mỗi thiết bị không ảnh hưởng đáng kể đến mức tiêu thụ pin nếu sử dụng batching (gửi theo lô thay vì từng cái một). Ở mức 200+ sự kiện mỗi phút, Wi-Fi/modem sẽ hoạt động liên tục — pin xả nhanh hơn 15–25%.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm