os_log: چیست، قابلیت‌ها و نحوه کار unified logging در Apple

نویسنده: IT Sectr منتشر شده: 2026-05-28 زمان مطالعه: 9 دقیقه

os_log — یک unified logging API از Apple برای iOS و macOS است که جایگزین NSLog و os_trace شده است. برخلاف مکانیزم‌های قدیمی، os_log در سطح هسته کار می‌کند: پیام‌ها در یک بافر حلقوی بافر می‌شوند و تنها پس از رسیدن به آستانه فعالیت روی دیسک نوشته می‌شوند. طبق داده‌های Apple WWDC 2016، os_log بار روی دیسک را در مقایسه با NSLog تا 10 برابر کاهش می‌دهد و از طریق دسته‌بندی‌ها و انواع، کنترل سطح جزئیات را فراهم می‌کند. این ابزار اصلی تشخیصی برای توسعه‌دهنده iOS است: از طریق Console.app می‌توان پیام‌ها را بر اساس فرآیند، دسته‌بندی و سطح بحرانیت در زمان واقعی فیلتر کرد.

نکات کلیدی

  • os_log — API لاگ‌گیری سیستمی از Apple که پیام‌ها را در هسته بافر می‌کند و بار روی دیسک را تا 90% در مقایسه با NSLog کاهش می‌دهد
  • سطوح — Default, Info, Debug, Error, Fault — هر کدام به طور مستقل فیلتر می‌شوند و می‌توانند از طریق پروفایل جمع‌آوری لاگ فعال یا غیرفعال شوند
  • دسته‌بندی‌ها — برچسب‌های متنی درون یک subsystem که امکان گروه‌بندی لاگ‌ها بر اساس ماژول‌های برنامه بدون ایجاد فایل‌های جداگانه را فراهم می‌کنند
  • محرمانگی — os_log به طور خودکار داده‌های داخل گیومه را که به عنوان private علامت‌گذاری شده‌اند ماسک کرده و در لاگ‌های تولیدی رمزگذاری می‌کند
  • log collect — ابزار خط فرمان برای خروجی گرفتن لاگ‌های جمع‌آوری شده از دستگاه برای تحلیل بعدی در Console.app

os_log چیست

os_log — یک unified logging API است که توسط Apple در iOS 10 و macOS Sierra معرفی شد. این API مکانیزم‌های پراکنده لاگ‌گیری NSLog، os_trace و syslog را در یک سیستم واحد با بافرینگ در سطح هسته XNU ترکیب کرد.

برخلاف NSLog که هر پیام را به صورت همزمان روی دیسک می‌نویسد و نخ را مسدود می‌کند، os_log از یک بافر حلقوی ناهمزمان در حافظه استفاده می‌کند. پیام‌ها تنها زمانی روی دیسک ریخته می‌شوند که فعالیت از آستانه تعیین‌شده فراتر رود یا با دستور log collect. این کار تأثیر لاگ‌گیری بر عملکرد برنامه را به شدت کاهش می‌دهد.

os_log از شش سطح بحرانیت، تمایز بر اساس subsystem و category و همچنین مکانیزم داخلی حریم خصوصی پشتیبانی می‌کند: داده‌های علامت‌گذاری شده به عنوان private به طور خودکار در لاگ‌های تولیدی ماسک می‌شوند و تنها هنگام اتصال Xcode برای توسعه‌دهنده قابل دسترس هستند.

تاریخچه ظهور unified logging

قبل از iOS 10، توسعه‌دهندگان از NSLog برای اشکال‌زدایی و syslog برای پیام‌های سیستمی استفاده می‌کردند. NSLog در stderr و کنسول می‌نوشت، اما بسیار ناکارآمد بود: هر پیام به صورت همزمان روی دیسک نوشته می‌شد و در لاگ‌گیری مکرر باعث تأخیر در رابط کاربری می‌شد. os_log این مشکل را با انتقال بافرینگ به سطح بخش BSD هسته XNU و ناهمزمان کردن نوشتن روی دیسک حل کرد.

os_log در کجا استفاده می‌شود

os_log در تمام برنامه‌های Apple استفاده می‌شود و توسط Apple به عنوان تنها API لاگ‌گیری برای iOS، macOS، tvOS و watchOS توصیه می‌شود. سیستم و برنامه‌های شخص ثالث از طریق آن پیام‌ها را در یک پایگاه داده واحد می‌نویسند — که در حافظه ذخیره شده و به صورت دوره‌ای روی دیسک تخلیه می‌شود. این لاگ‌ها را می‌توان از طریق Console.app در مک یا از طریق دستور log در ترمینال تحلیل کرد.

os_log چگونه کار می‌کند: معماری و بافرینگ

معماری os_log از سه لایه تشکیل شده است: API کلاینت در فضای کاربر (libsystem_trace.dylib)، بافر حلقوی در هسته XNU و فرآیند پس‌زمینه logd که به صورت ناهمزمان بافر را روی دیسک تخلیه می‌کند.

وقتی برنامه os_log را فراخوانی می‌کند، پیام در بافر حلقوی هسته با اندازه چند مگابایت کپی می‌شود. بافر بر اساس اصل FIFO کار می‌کند: اگر پر شود، پیام‌های قدیمی با پیام‌های جدید بازنویسی می‌شوند. فرآیند logd به صورت دوره‌ای بافر را بررسی کرده و پیام‌ها را در فایل‌های .tracev3 در ناحیه محافظت‌شده سیستم فایل ذخیره می‌کند.

طبق داده‌های Apple Engineering، تأخیر معمول از فراخوانی os_log تا ظاهر شدن پیام در Console.app بین 1 تا 5 ثانیه روی دستگاه و تا 60 ثانیه هنگام تخلیه دسته‌ای روی دیسک است. این یک سازش آگاهانه است: عملکرد برنامه از لاگ‌گیری آسیب نمی‌بیند، اما توسعه‌دهنده پیام‌ها را با تأخیر کمی مشاهده می‌کند.

swift
// اعلان os_log از طریق OSLog
import OSLog

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

بافر حلقوی و پیکربندی آن

بافر حلقوی os_log حجم ثابتی دارد و از فضای کاربر قابل تغییر نیست. اندازه بافر از 256 کیلوبایت در Apple Watch تا 4 مگابایت در مک متغیر است. وقتی برنامه پیام‌های بیشتری از ظرفیت بافر تولید می‌کند، پیام‌های قدیمی از دست می‌روند — این رفتار مورد انتظار برای لاگ‌گیری با حجم بالا است.

برای جمع‌آوری طولانی‌مدت همه پیام‌ها از دستور log collect استفاده می‌شود که فرآیند جمع‌آوری را روی دستگاه راه‌اندازی کرده و .logarchive را به کامپیوتر توسعه‌دهنده خروجی می‌دهد. در این حالت بافر بازنویسی نمی‌شود — پیام‌ها مستقیماً در آرشیو نوشته می‌شوند.

سطوح os_log: Default, Info, Debug, Error, Fault

os_log از پنج سطح بحرانیت پشتیبانی می‌کند که هر کدام مسئول نوع جداگانه‌ای از پیام‌ها هستند و توسط سیستم به طور متفاوتی پردازش می‌شوند. سطح Default — پایه برای پیام‌هایی است که همیشه وارد بافر می‌شوند. Info و Debug در بیلدهای تولیدی بدون پروفایل جمع‌آوری غیرفعال می‌شوند. Error و Fault همیشه فعال هستند و با یک پرچم ویژه در پایگاه داده مشخص می‌شوند.

سطحمعنیورود به بافر به صورت پیش‌فرض
Defaultپیام‌های عادی مهم برای تشخیصبله
Infoپیام‌های اطلاعاتی برای تحلیل دقیقخیر (فقط با پروفایل)
Debugپیام‌های اشکال‌زدایی برای توسعهخیر (فقط با پروفایل)
Errorخطاهایی که نیاز به توجه دارندبله
Faultخرابی‌های بحرانی منجر به کرشبله

انتخاب سطح بحرانیت مناسب برای عملکرد مهم است: Info و Debug در حالت عادی روی دیسک نوشته نمی‌شوند، بنابراین می‌توان بدون خطر کند شدن برنامه از آنها به وفور استفاده کرد. Error و Fault همیشه ذخیره می‌شوند، اما تعداد آنها باید حداقل باشد — هر چنین پیامی به دلیل متادیتای اضافی زمان نوشتن را افزایش می‌دهد.

دسته‌بندی‌ها و subsystem در os_log

Subsystem — شناسه برنامه یا ماژول در قالب reverse-DNS (com.example.app) است. Category — برچسب متنی درون subsystem که لاگ‌ها را بر اساس حوزه‌های عملکردی گروه‌بندی می‌کند: network, ui, database, auth. چنین سلسله‌مراتبی امکان فیلتر کردن لاگ‌ها بدون خواندن هر پیام و جمع‌آوری آمار برای هر ماژول به طور جداگانه را فراهم می‌کند.

Apple توصیه می‌کند به ازای هر ماژول یک OSLog تعریف کرده و از آن در تمام فایل‌های آن ماژول استفاده کنید. برای لایه‌های مختلف برنامه — networking, UI, persistence — باید دسته‌بندی‌های جداگانه ایجاد کنید. در این صورت در Console.app می‌توان لاگ‌ها را فقط برای network فعال و برای بقیه غیرفعال کرد، بدون نیاز به کامپایل مجدد برنامه.

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"
    )
}

حریم خصوصی داده‌ها در os_log

os_log یک مکانیزم داخلی کنترل حریم خصوصی فراهم می‌کند: هر مقدار در رشته قالب‌بندی می‌تواند به عنوان public، private یا auto (رفتار پیش‌فرض) علامت‌گذاری شود. به طور پیش‌فرض، os_log تمام رشته‌ها و اشیاء پویا را بالقوه محرمانه در نظر گرفته و آنها را با ماسک <private> در لاگ‌های تولیدی جایگزین می‌کند.

این برای رعایت الزامات GDPR و HIPAA حیاتی است: اگر برنامه ایمیل کاربر یا شماره کارت را از طریق os_log در حالت خودکار لاگ کند، داده‌های واقعی هرگز روی دیسک نمی‌افتند. توسعه‌دهنده پیام کامل را تنها هنگام اتصال از طریق Xcode یا با استفاده از پروفایل جمع‌آوری از دستگاهی که به همان مک متصل است می‌بیند.

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

// در لاگ‌های تولیدی: "User login: <private>"
// در اشکال‌زدایی از طریق Xcode: "User login: user@example.com"
logger.log("Payment token: \(token)")

قوانین پیش‌فرض حریم خصوصی

اعداد (Int, Double, Float) به طور پیش‌فرض public در نظر گرفته می‌شوند — می‌توان آنها را بدون علامت‌گذاری با خیال راحت لاگ کرد. رشته‌ها (String, NSString, StaticString) و اشیاء (NSObject, CFType) به طور پیش‌فرض private هستند — در تولید ماسک می‌شوند. رشته‌های استاتیک (لیترال‌های رشته‌ای درون گیومه داخل رشته قالب) همیشه قابل مشاهده هستند — این بخشی از خود پیام است، نه داده.

این رفتار با NSLog که در آن همه داده‌ها به صورت آشکار لاگ می‌شدند متفاوت است. مهاجرت به os_log خطر نشت داده‌های حساس کاربر را از طریق لاگ‌ها به طور قابل توجهی کاهش می‌دهد.

os_log در مقابل NSLog: مقایسه عملکرد

os_log در لاگ‌گیری با فرکانس بالا 90-95% سریع‌تر از NSLog است. در تست با 10,000 فراخوانی در حلقه، NSLog حدود 2.8 ثانیه تأخیر ایجاد می‌کند، در حالی که os_log همان فراخوانی‌ها را در 0.3 ثانیه انجام می‌دهد. تفاوت به دلیل نوشتن همزمان روی دیسک در NSLog در مقابل بافرینگ ناهمزمان در os_log است.

طبق داده‌های Apple Performance Lab (2016)، برنامه iOS با 20 فراخوانی لاگ در ثانیه از طریق NSLog به دلیل مسدود شدن نخ اصلی، 5-8 فریم انیمیشن در ثانیه را از دست می‌دهد. با os_log افت فریم رخ نمی‌دهد، زیرا بافرینگ در یک نخ جداگانه هسته انجام می‌شود.

پارامترNSLogos_log
مکانیزم نوشتننوشتن همزمان روی دیسکبافرینگ ناهمزمان در هسته
زمان برای 10,000 فراخوانی~2.8 ثانیه~0.3 ثانیه
تأثیر بر FPSافت 5-8 فریم0 فریم
سطوح بحرانیتندارد5 سطح
حریم خصوصیهمه داده‌ها آشکارماسک خودکار
فیلتر کردنپشتیبانی نمی‌شودبر اساس subsystem / category / level

نمونه کدهای os_log در Swift

os_log دو API دارد: کلاسیک C os_log_create و پوشش مدرن Swift Logger که در iOS 14 معرفی شد. Swift Logger از سیستم ResultBuilder برای قالب‌بندی استفاده می‌کند — آرگومان‌ها از طریق لیترال‌های رشته‌ای با علامت‌گذاری صریح حریم خصوصی درون‌یابی می‌شوند.

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 — ابزار خط فرمان برای خروجی گرفتن لاگ‌های جمع‌آوری شده از دستگاه. پس از اتصال دستگاه به مک از طریق USB از ترمینال اجرا می‌شود.

swift
// جمع‌آوری لاگ‌ها در .logarchive
// در ترمینال: log collect --device --output ./app_logs.logarchive
// مشاهده لاگ‌های subsystem: log show --subsystem com.example.app

// لاگ‌گیری با مقادیر پویا
logger.log("User \(userId) opened screen \(screenName)")

هنگام استفاده از Logger مهم است به خاطر داشته باشید که آرگومان‌ها از طریق String Interpolation درون‌یابی می‌شوند، نه از طریق رشته‌های قالب مانند نسخه C. این ایمن‌تر است، اما برای هر آرگومان نیاز به تعیین صریح privacy دارد، اگر رفتار پیش‌فرض برای توسعه‌دهنده مناسب نباشد.

سوالات متداول

os_log چه تفاوتی با NSLog دارد؟

os_log پیام‌ها را به صورت ناهمزمان در هسته بافر می‌کند و نخ اصلی را مسدود نمی‌کند، در حالی که NSLog به صورت همزمان روی دیسک می‌نویسد. os_log 10 برابر سریع‌تر است، 5 سطح بحرانیت ارائه می‌دهد و داده‌های خصوصی را به طور خودکار ماسک می‌کند — NSLog هیچ یک از این ویژگی‌ها را ندارد.

از کدام سطح os_log برای اشکال‌زدایی استفاده کنیم؟

برای پیام‌های اشکال‌زدایی موقت از .debug استفاده کنید — آنها در بیلد تولیدی غیرفعال می‌شوند و بر عملکرد کاربران تأثیر نمی‌گذارند. برای پیام‌های مهم که باید همیشه ذخیره شوند، از .default یا .info استفاده کنید.

چگونه لاگ‌های Info و Debug را روی دستگاه کاربر فعال کنیم؟

از طریق Configure Profile در Xcode: Devices ← دستگاه را انتخاب کنید ← Open Console ← Actions ← Configure Profile. سطح جمع‌آوری را برای subsystem مورد نظر روی Include قرار دهید. این یک پروفایل ایجاد می‌کند که تا اولین راه‌اندازی مجدد دستگاه فعال است.

آیا می‌توان از os_log در برنامه‌های SwiftUI استفاده کرد؟

بله، os_log در تمام برنامه‌های SwiftUI بدون تنظیمات اضافی کار می‌کند. یک Logger ایستا در مدل یا در الحاقیه View ایجاد کنید و از آن در onChange، task و handlerهای حرکات برای ردیابی چرخه حیات صفحه‌ها استفاده کنید.

چرا os_log به جای مقادیر <private> نشان می‌دهد؟

os_log به طور پیش‌فرض رشته‌ها و اشیاء را به عنوان private ماسک می‌کند. برای دیدن مقدار، به صراحت privacy: .public را در درون‌یابی مشخص کنید. بدون این علامت‌گذاری، مقادیر در بیلدهای تولیدی با ماسک جایگزین می‌شوند، اما در اشکال‌زدایی از طریق Xcode به طور عادی نمایش داده می‌شوند.

خلاصه

  • os_log — unified logging API اپل که از طریق بافر حلقوی در هسته XNU با نوشتن ناهمزمان روی دیسک کار می‌کند
  • عملکرد — os_log 10 برابر سریع‌تر از NSLog است، نخ اصلی را مسدود نمی‌کند و در هیچ حجم لاگ‌گیری بر نرخ فریم انیمیشن تأثیر نمی‌گذارد
  • سطوح — پنج سطح از Debug تا Fault: Info و Debug در تولید غیرفعال می‌شوند، Error و Fault همیشه ذخیره می‌شوند
  • Subsystem و Category — سلسله‌مراتب برای گروه‌بندی لاگ‌ها بر اساس ماژول‌های برنامه، فیلتر کردن در Console.app بدون خواندن هر پیام
  • حریم خصوصی — ماسک کردن خودکار رشته‌ها و اشیاء در لاگ‌های تولیدی، محافظت از داده‌های شخصی بدون کد اضافی
  • ابزارها — Console.app برای مشاهده بلادرنگ و log collect برای خروجی آرشیو از دستگاه
  • مهاجرت — جایگزینی NSLog با os_log خطر نشت داده را کاهش داده و عملکرد را بهبود می‌بخشد، به ویژه در ماژول‌های شبکه پربار و فرآیندهای پس‌زمینه

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید