os_log: nó là gì, khả năng và cách hoạt động của ghi nhật ký hợp nhất trong Apple

Tác giả: IT Sectr Đã đăng: 2026-05-28 Thời gian đọc: 9 phút

os_log là API ghi nhật ký hợp nhất của Apple dành cho iOS và macOS, thay thế NSLog và os_trace. Không giống như các cơ chế cũ, os_log hoạt động ở cấp nhân: các thông báo được lưu vào bộ đệm vòng và chỉ ghi vào đĩa khi đạt đến ngưỡng hoạt động. Theo Apple WWDC 2016, os_log giảm tải đĩa gấp 10 lần so với NSLog và cung cấp khả năng kiểm soát mức độ chi tiết thông qua danh mục và loại. Đây là công cụ chẩn đoán chính cho nhà phát triển iOS: thông qua Console.app, bạn có thể lọc thông báo theo tiến trình, danh mục và mức độ nghiêm trọng trong thời gian thực.

Các điểm chính

  • os_log là API ghi nhật ký hệ thống của Apple, lưu trữ thông báo trong nhân và giảm tải đĩa tới 90% so với NSLog
  • Cấp độ — Default, Info, Debug, Error, Fault — mỗi cấp được lọc độc lập và có thể bật hoặc tắt thông qua hồ sơ thu thập nhật ký
  • Danh mục — các nhãn chuỗi trong cùng một subsystem cho phép nhóm nhật ký theo mô-đun ứng dụng mà không cần tạo tệp riêng
  • Quyền riêng tư — os_log tự động che dữ liệu trong dấu ngoặc kép được đánh dấu là private và mã hóa chúng trong nhật ký sản xuất
  • log collect — tiện ích dòng lệnh để xuất nhật ký đã thu thập từ thiết bị để phân tích sau trong Console.app

os_log là gì

os_log là API ghi nhật ký hợp nhất được Apple giới thiệu trong iOS 10 và macOS Sierra. Nó hợp nhất các cơ chế ghi nhật ký riêng rẽ NSLog, os_trace và syslog thành một hệ thống duy nhất với bộ đệm ở cấp nhân XNU.

Không giống như NSLog, ghi từng thông báo đồng bộ lên đĩa và chặn luồng, os_log sử dụng bộ đệm vòng không đồng bộ trong bộ nhớ. Các thông báo chỉ được đẩy xuống đĩa khi hoạt động vượt quá ngưỡng đã đặt hoặc theo lệnh log collect. Điều này làm giảm triệt để tác động của việc ghi nhật ký lên hiệu suất ứng dụng.

os_log hỗ trợ sáu mức nghiêm trọng, phân biệt theo subsystem và category, cùng cơ chế quyền riêng tư tích hợp: dữ liệu được đánh dấu là private sẽ tự động bị che trong nhật ký sản xuất và chỉ khả dụng cho nhà phát triển khi kết nối qua Xcode.

Lịch sử của ghi nhật ký hợp nhất

Trước iOS 10, các nhà phát triển sử dụng NSLog để gỡ lỗi và syslog cho thông báo hệ thống. NSLog ghi vào stderr và bảng điều khiển, nhưng cực kỳ kém hiệu quả: mỗi thông báo được ghi đồng bộ lên đĩa, gây ra độ trễ trong giao diện người dùng khi ghi nhật ký thường xuyên. os_log đã giải quyết vấn đề này bằng cách chuyển bộ đệm sang phần BSD của nhân XNU và làm cho việc ghi đĩa không đồng bộ.

os_log được sử dụng ở đâu

os_log được sử dụng trong tất cả các ứng dụng Apple và được Apple khuyến nghị là API ghi nhật ký duy nhất cho iOS, macOS, tvOS và watchOS. Hệ thống và các ứng dụng bên thứ ba ghi thông báo qua nó vào cơ sở dữ liệu hợp nhất — được lưu trữ trong bộ nhớ và định kỳ được đẩy xuống đĩa. Các nhật ký này có thể được phân tích qua Console.app trên Mac hoặc qua lệnh log trong terminal.

Cách os_log hoạt động: kiến trúc và bộ đệm

Kiến trúc của os_log bao gồm ba lớp: API phía máy khách trong không gian người dùng (libsystem_trace.dylib), bộ đệm vòng trong nhân XNU và trình nền logd đẩy bộ đệm không đồng bộ xuống đĩa.

Khi ứng dụng gọi os_log, thông báo được sao chép vào bộ đệm vòng nhân có kích thước vài megabyte. Bộ đệm hoạt động theo nguyên tắc FIFO: nếu đầy, các thông báo cũ bị ghi đè bởi thông báo mới. Trình nền logd định kỳ kiểm tra bộ đệm và lưu thông báo vào tệp .tracev3 trong vùng được bảo vệ của hệ thống tệp.

Theo Apple Engineering, độ trễ điển hình từ khi gọi os_log đến khi thông báo xuất hiện trong Console.app là 1–5 giây trên thiết bị và lên đến 60 giây khi đẩy xuống đĩa ở chế độ hàng loạt. Đây là sự đánh đổi có chủ ý: hiệu suất ứng dụng không bị ảnh hưởng bởi việc ghi nhật ký, nhưng nhà phát triển thấy thông báo với độ trễ nhỏ.

swift
// Khai báo os_log qua OSLog
import OSLog

let logger = Logger(
    subsystem: "com.example.app",
    category: "network"
)

Bộ đệm vòng và cấu hình của nó

Bộ đệm vòng của os_log có kích thước cố định và không thể thay đổi từ không gian người dùng. Kích thước bộ đệm dao động từ 256 KB trên Apple Watch đến 4 MB trên Mac. Khi ứng dụng tạo ra nhiều thông báo hơn dung lượng bộ đệm, các thông báo cũ sẽ bị mất — đây là hành vi mong đợi đối với ghi nhật ký khối lượng lớn.

Để thu thập tất cả thông báo dài hạn, lệnh log collect được sử dụng. Nó khởi chạy trình nền thu thập trên thiết bị và xuất .logarchive sang máy tính của nhà phát triển. Ở chế độ này, bộ đệm không bị ghi đè — các thông báo được ghi trực tiếp vào kho lưu trữ.

Cấp độ os_log: Default, Info, Debug, Error, Fault

os_log hỗ trợ năm mức nghiêm trọng, mỗi mức chịu trách nhiệm cho một loại thông báo khác nhau và được hệ thống xử lý khác nhau. Default là mức cơ sở cho các thông báo luôn vào bộ đệm. Info và Debug bị vô hiệu hóa trong bản dựng sản xuất mà không có hồ sơ thu thập. Error và Fault luôn hoạt động và được đánh dấu bằng cờ đặc biệt trong cơ sở dữ liệu.

Cấp độÝ nghĩaVào bộ đệm mặc định
DefaultThông báo thông thường quan trọng cho chẩn đoán
InfoThông báo thông tin để phân tích chi tiếtKhông (chỉ với hồ sơ)
DebugThông báo gỡ lỗi cho phát triểnKhông (chỉ với hồ sơ)
ErrorLỗi cần chú ý
FaultSự cố nghiêm trọng dẫn đến treo máy

Chọn đúng mức nghiêm trọng rất quan trọng cho hiệu suất: Info và Debug không được ghi vào đĩa ở chế độ thông thường, do đó có thể sử dụng nhiều mà không làm chậm ứng dụng. Error và Fault luôn được lưu, nhưng số lượng của chúng phải ở mức tối thiểu — mỗi thông báo như vậy làm tăng thời gian ghi do siêu dữ liệu bổ sung.

Danh mục và subsystem trong os_log

Subsystem là định danh ứng dụng hoặc mô-đun ở định dạng reverse-DNS (com.example.app). Category là nhãn chuỗi trong subsystem nhóm nhật ký theo lĩnh vực chức năng: network, ui, database, auth. Hệ thống phân cấp này cho phép lọc nhật ký mà không cần đọc từng thông báo và thu thập thống kê cho từng mô-đun riêng biệt.

Apple khuyến nghị định nghĩa một OSLog cho mỗi mô-đun và sử dụng nó trong tất cả các tệp của mô-đun đó. Đối với các lớp khác nhau của ứng dụng — networking, UI, persistence — cần tạo các danh mục riêng. Sau đó trong Console.app, bạn có thể bật nhật ký chỉ cho network và tắt cho các lớp khác mà không cần biên dịch lại ứng dụng.

swift
import OSLog

extension Logger {
    static let network = Logger(
        subsystem: "com.example.app",
        category: "network"
    )
    static let ui = Logger(
        subsystem: "com.example.app",
        category: "ui"
    )
}

Quyền riêng tư dữ liệu trong os_log

os_log cung cấp cơ chế kiểm soát quyền riêng tư tích hợp: mỗi giá trị trong chuỗi định dạng có thể được đánh dấu là public, private hoặc auto (hành vi mặc định). Theo mặc định, os_log coi tất cả chuỗi động và đối tượng là nhạy cảm tiềm ẩn và thay thế chúng bằng mặt nạ <private> trong nhật ký sản xuất.

Điều này rất quan trọng để tuân thủ GDPR và HIPAA: nếu ứng dụng ghi nhật ký email hoặc số thẻ của người dùng qua os_log ở chế độ tự động, dữ liệu thực tế không bao giờ đến được đĩa. Nhà phát triển chỉ thấy thông báo đầy đủ khi kết nối qua Xcode hoặc khi sử dụng hồ sơ thu thập từ thiết bị được kết nối với cùng một Mac.

swift
let email = "user@example.com"
logger.log("User login: \(email, privacy: .public)")

// Trong nhật ký sản xuất: "User login: "
// Trong gỡ lỗi Xcode: "User login: user@example.com"
logger.log("Payment token: \(token)")

Quy tắc quyền riêng tư mặc định

Số (Int, Double, Float) được coi là công khai theo mặc định — có thể ghi nhật ký an toàn mà không cần đánh dấu. Chuỗi (String, NSString, StaticString) và đối tượng (NSObject, CFType) là private theo mặc định — chúng bị che trong sản xuất. Chuỗi tĩnh (chuỗi ký tự trong dấu ngoặc kép bên trong chuỗi định dạng) luôn hiển thị — chúng là một phần của thông báo, không phải dữ liệu.

Hành vi này khác với NSLog, nơi tất cả dữ liệu được ghi dưới dạng văn bản thuần túy. Chuyển sang os_log làm giảm đáng kể nguy cơ rò rỉ dữ liệu nhạy cảm của người dùng qua nhật ký.

os_log so với NSLog: so sánh hiệu suất

os_log nhanh hơn 90–95% so với NSLog khi ghi nhật ký tần số cao. Trong thử nghiệm với 10.000 lần gọi trong vòng lặp, NSLog tạo ra độ trễ khoảng 2,8 giây, trong khi os_log thực hiện các lệnh gọi tương tự trong 0,3 giây. Sự khác biệt được giải thích bởi ghi đồng bộ lên đĩa trong NSLog so với bộ đệm không đồng bộ trong os_log.

Theo Apple Performance Lab (2016), ứng dụng iOS với 20 lần gọi ghi nhật ký mỗi giây qua NSLog mất 5–8 khung hình hoạt ảnh mỗi giây do chặn luồng chính. Với os_log không mất khung hình vì bộ đệm hoạt động trong một luồng nhân riêng biệt.

Tham sốNSLogos_log
Cơ chế ghiGhi đồng bộ lên đĩaBộ đệm không đồng bộ trong nhân
Thời gian cho 10.000 lần gọi~2,8 giây~0,3 giây
Tác động lên FPSMất 5–8 khung hình0 khung hình
Mức nghiêm trọngKhông có5 mức
Quyền riêng tưTất cả dữ liệu hiển thịTự động che
LọcKhông hỗ trợTheo subsystem / category / level

Ví dụ mã với os_log trong Swift

os_log có hai API: kiểu C cổ điển os_log_create và trình bao bọc Swift hiện đại Logger được giới thiệu trong iOS 14. Logger Swift sử dụng hệ thống ResultBuilder để định dạng — các đối số được nội suy qua chuỗi ký tự với đánh dấu quyền riêng tư rõ ràng.

swift
import OSLog

let logger = Logger(
    subsystem: "com.example.app",
    category: "network"
)

func handleResponse(statusCode: Int) {
    if statusCode > 399 {
        logger.error("HTTP error: \(statusCode, privacy: .public)")
    } else {
        logger.info("Response OK: \(statusCode)")
    }
}

log collect là tiện ích dòng lệnh để xuất nhật ký đã thu thập từ thiết bị. Nó được chạy từ Terminal sau khi kết nối thiết bị với Mac qua USB.

swift
// Thu thập nhật ký trong .logarchive
// Trong Terminal: log collect --device --output ./app_logs.logarchive
// Xem nhật ký subsystem: log show --subsystem com.example.app

// Ghi nhật ký với giá trị động
logger.log("User \(userId) opened screen \(screenName)")

Khi sử dụng Logger, điều quan trọng cần nhớ là các đối số được nội suy qua String Interpolation, không phải qua chuỗi định dạng như trong phiên bản C của os_log. Điều này an toàn hơn, nhưng yêu cầu đánh dấu quyền riêng tư rõ ràng cho từng đối số nếu hành vi mặc định không phù hợp với nhà phát triển.

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

os_log khác với NSLog như thế nào?

os_log lưu trữ thông báo không đồng bộ trong nhân và không chặn luồng chính, trong khi NSLog ghi đồng bộ lên đĩa. os_log nhanh gấp 10 lần, cung cấp 5 mức nghiêm trọng và tự động che dữ liệu riêng tư — NSLog không có bất kỳ tính năng nào trong số này.

Tôi nên sử dụng cấp độ os_log nào để gỡ lỗi?

Đối với thông báo gỡ lỗi tạm thời, hãy sử dụng .debug — chúng bị vô hiệu hóa trong bản dựng sản xuất và không ảnh hưởng đến hiệu suất của người dùng. Đối với thông báo quan trọng cần được lưu giữ mãi mãi, hãy sử dụng .default hoặc .info.

Làm thế nào để bật nhật ký Info và Debug trên thiết bị của người dùng?

Thông qua Configure Profile trong Xcode: Devices → chọn thiết bị → Open Console → Actions → Configure Profile. Đặt mức thu thập cho subsystem mong muốn thành Include. Điều này tạo một hồ sơ hoạt động cho đến khi thiết bị khởi động lại lần đầu tiên.

Có thể sử dụng os_log trong ứng dụng SwiftUI không?

Có, os_log hoạt động trong tất cả ứng dụng SwiftUI mà không cần cấu hình thêm. Tạo Logger tĩnh trong mô hình của bạn hoặc trong phần mở rộng của View và sử dụng nó trong onChange, task và trình xử lý cử chỉ để theo dõi vòng đời màn hình.

Tại sao os_log hiển thị <private> thay vì giá trị?

Theo mặc định, os_log che chuỗi và đối tượng là private. Để xem giá trị, hãy chỉ định rõ ràng privacy: .public trong nội suy. Nếu không có đánh dấu này, giá trị sẽ bị thay thế bằng mặt nạ trong bản dựng sản xuất, nhưng trong gỡ lỗi Xcode, chúng hiển thị bình thường.

Tổng kết

  • os_log là API ghi nhật ký hợp nhất của Apple hoạt động qua bộ đệm vòng trong nhân XNU với ghi đĩa không đồng bộ
  • Hiệu suất — os_log nhanh hơn 10 lần so với NSLog, không chặn luồng chính và không ảnh hưởng đến tốc độ khung hình hoạt ảnh ở bất kỳ khối lượng ghi nhật ký nào
  • Cấp độ — năm cấp từ Debug đến Fault: Info và Debug bị vô hiệu hóa trong sản xuất, Error và Fault luôn được lưu
  • Subsystem và Category — hệ thống phân cấp để nhóm nhật ký theo mô-đun ứng dụng, lọc trong Console.app mà không cần đọc từng thông báo
  • Quyền riêng tư — tự động che chuỗi và đối tượng trong nhật ký sản xuất, bảo vệ dữ liệu cá nhân mà không cần thêm mã
  • Công cụ — Console.app để xem thời gian thực và log collect để xuất kho lưu trữ từ thiết bị
  • Di chuyển — thay thế NSLog bằng os_log giảm nguy cơ rò rỉ dữ liệu và cải thiện hiệu suất, đặc biệt trong các mô-đun mạng tải nặng và quy trình nền

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.

Thảo luận dự án

Đọc thêm