os_log, NSLog ve os_trace'in yerini alan Apple'ın iOS ve macOS için birleşik günlük API'sidir. Eski mekanizmaların aksine, os_log çekirdek seviyesinde çalışır: mesajlar bir halka tamponda arabelleğe alınır ve yalnızca bir etkinlik eşiğine ulaşıldığında diske yazılır. Apple WWDC 2016'ya göre os_log, NSLog'a kıyasla disk yükünü 10 kat azaltır ve kategoriler ve türler aracılığıyla ayrıntı düzeyi üzerinde kontrol sağlar. iOS geliştiricisi için birincil tanı aracıdır: Console.app aracılığıyla mesajları gerçek zamanlı olarak sürece, kategoriye ve kritiklik düzeyine göre filtreleyebilirsiniz.
Önemli Noktalar
os_log, Apple tarafından iOS 10 ve macOS Sierra'da tanıtılan birleşik bir günlük API'sidir. Dağınık günlük mekanizmaları olan NSLog, os_trace ve syslog'u, XNU çekirdek seviyesinde arabelleğe alma ile tek bir sistemde birleştirdi.
Her mesajı eşzamanlı olarak diske yazan ve iş parçacığını bloke eden NSLog'un aksine, os_log bellekte eşzamansız bir halka tamponu kullanır. Mesajlar yalnızca etkinlik belirlenen bir eşiği aştığında veya log collect komutuyla diske boşaltılır. Bu, günlüğün uygulama performansı üzerindeki etkisini kökten azaltır.
os_log altı kritiklik seviyesini, subsystem ve category'ye göre ayrımı ve yerleşik bir gizlilik mekanizmasını destekler: private olarak işaretlenen veriler üretim günlüklerinde otomatik olarak maskelenir ve yalnızca Xcode üzerinden bağlandığında geliştirici tarafından kullanılabilir.
iOS 10'dan önce, geliştiriciler hata ayıklama için NSLog ve sistem mesajları için syslog kullanıyordu. NSLog stderr ve konsola yazıyordu, ancak son derece verimsizdi: her mesaj eşzamanlı olarak diske yazılıyor ve sık günlük kaydında kullanıcı arayüzünde gecikmelere neden oluyordu. os_log, arabelleğe almayı XNU çekirdeğinin BSD bölümüne taşıyarak ve disk yazmalarını eşzamansız hale getirerek bu sorunu çözdü.
os_log tüm Apple uygulamalarında kullanılır ve Apple tarafından iOS, macOS, tvOS ve watchOS için tek günlük API'si olarak önerilir. Sistem ve üçüncü taraf uygulamalar, bu aracılığıyla birleşik bir veritabanına mesaj yazar — bellekte depolanır ve periyodik olarak diske boşaltılır. Bu günlükler, Mac'te Console.app veya terminaldeki log komutu aracılığıyla analiz edilebilir.
os_log mimarisi üç katmandan oluşur: kullanıcı alanında istemci tarafı API (libsystem_trace.dylib), XNU çekirdeğinde bir halka tamponu ve tamponu eşzamansız olarak diske boşaltan logd arka plan programı.
Bir uygulama os_log'u çağırdığında, mesaj birkaç megabayt boyutundaki bir çekirdek halka tamponuna kopyalanır. Tampon FIFO prensibine göre çalışır: doluysa, eski mesajlar yenileri tarafından üzerine yazılır. logd arka plan programı periyodik olarak tamponu kontrol eder ve mesajları dosya sisteminin korunan bir alanındaki .tracev3 dosyalarına kaydeder.
Apple Engineering'e göre, os_log çağrısından mesajın Console.app'te görünmesine kadar geçen tipik gecikme bir cihazda 1–5 saniye ve toplu modda diske boşaltırken 60 saniyeye kadardır. Bu bilinçli bir değiş tokuştur: günlük kaydı nedeniyle uygulama performansı etkilenmez, ancak geliştirici mesajları hafif bir gecikmeyle görür.
// OSLog aracılığıyla os_log bildirimi
import OSLog
let logger = Logger(
subsystem: "com.example.app",
category: "network"
)
os_log'un halka tamponu sabit bir boyuta sahiptir ve kullanıcı alanından değiştirilemez. Tampon boyutu Apple Watch'ta 256 KB'den Mac'te 4 MB'a kadar değişir. Bir uygulama, tampon kapasitesinden daha fazla mesaj ürettiğinde, eski mesajlar kaybolur — bu, yüksek hacimli günlük kaydı için beklenen bir davranıştır.
Tüm mesajların uzun süreli toplanması için log collect komutu kullanılır. Cihazda bir toplama arka plan programı başlatır ve geliştiricinin bilgisayarına bir .logarchive dışa aktarır. Bu modda, tampon üzerine yazılmaz — mesajlar doğrudan arşive yazılır.
os_log, her biri farklı bir mesaj türünden sorumlu ve sistem tarafından farklı şekilde işlenen beş kritiklik seviyesini destekler. Default, her zaman tampona giren mesajlar için temel seviyedir. Info ve Debug, toplama profili olmayan üretim yapılarında devre dışı bırakılır. Error ve Fault her zaman etkindir ve veritabanında özel bir işaretle işaretlenir.
| Seviye | Anlamı | Varsayılan olarak tampon girişi |
|---|---|---|
| Default | Tanı için önemli normal mesajlar | Evet |
| Info | Ayrıntılı analiz için bilgilendirme mesajları | Hayır (yalnızca profille) |
| Debug | Geliştirme için hata ayıklama mesajları | Hayır (yalnızca profille) |
| Error | Dikkat gerektiren hatalar | Evet |
| Fault | Çökmelere yol açan kritik arızalar | Evet |
Doğru kritiklik seviyesini seçmek performans için önemlidir: Info ve Debug normal modda diske yazılmaz, bu nedenle uygulamayı yavaşlatma riski olmadan bolca kullanılabilirler. Error ve Fault her zaman kaydedilir, ancak miktarları minimum düzeyde olmalıdır — bu tür her mesaj, ek meta veriler nedeniyle yazma süresini artırır.
Subsystem, reverse-DNS biçiminde (com.example.app) bir uygulama veya modül tanımlayıcısıdır. Category, bir subsystem içinde günlükleri işlevsel alanlara göre gruplandıran bir dize etiketidir: network, ui, database, auth. Bu hiyerarşi, her mesajı okumadan günlükleri filtrelemeye ve her modül için ayrı ayrı istatistik toplamaya olanak tanır.
Apple, modül başına bir OSLog tanımlanmasını ve bu modülün tüm dosyalarında kullanılmasını önerir. Uygulamanın farklı katmanları — networking, UI, persistence — için ayrı kategoriler oluşturulmalıdır. Ardından Console.app'te uygulamayı yeniden derlemeden yalnızca network için günlükleri etkinleştirebilir ve diğerleri için devre dışı bırakabilirsiniz.
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 yerleşik bir gizlilik kontrol mekanizması sağlar: biçim dizesindeki her değer public, private veya auto (varsayılan davranış) olarak işaretlenebilir. Varsayılan olarak, os_log tüm dinamik dizeleri ve nesneleri potansiyel olarak hassas kabul eder ve bunları üretim günlüklerinde <private> maskesiyle değiştirir.
Bu, GDPR ve HIPAA uyumluluğu için kritiktir: bir uygulama os_log aracılığıyla otomatik modda bir kullanıcının e-postasını veya kart numarasını günlüğe kaydederse, gerçek veriler asla diske ulaşmaz. Geliştirici, tam mesajı yalnızca Xcode üzerinden bağlandığında veya aynı Mac'e bağlı bir cihazdan toplama profili kullandığında görür.
let email = "user@example.com"
logger.log("User login: \(email, privacy: .public)")
// Üretim günlüklerinde: "User login: "
// Xcode hata ayıklamasında: "User login: user@example.com"
logger.log("Payment token: \(token)")
Sayılar (Int, Double, Float) varsayılan olarak herkese açık kabul edilir — işaretleme olmadan güvenle günlüğe kaydedilebilirler. Dizeler (String, NSString, StaticString) ve nesneler (NSObject, CFType) varsayılan olarak özeldir — üretimde maskelenirler. Statik dizeler (biçim dizesi içinde tırnak içindeki dize değişmezleri) her zaman görünür — bunlar veri değil, mesajın kendisinin bir parçasıdır.
Bu davranış, tüm verilerin düz metin olarak günlüğe kaydedildiği NSLog'dan farklıdır. os_log'a geçiş, günlükler aracılığıyla hassas kullanıcı verilerinin sızma riskini önemli ölçüde azaltır.
os_log, yüksek frekanslı günlük kaydında NSLog'dan %90–95 daha hızlıdır. Bir döngüde 10.000 çağrı ile yapılan bir testte, NSLog yaklaşık 2,8 saniyelik bir gecikme yaratırken, os_log aynı çağrıları 0,3 saniyede gerçekleştirir. Fark, os_log'daki eşzamansız arabelleğe almaya karşı NSLog'daki eşzamanlı disk yazmalarıyla açıklanır.
Apple Performance Lab'e (2016) göre, saniyede 20 günlük çağrısı yapan bir iOS uygulaması, ana iş parçacığının bloke olması nedeniyle saniyede 5–8 animasyon karesi kaybeder. os_log ile kare kaybı olmaz çünkü arabelleğe alma ayrı bir çekirdek iş parçacığında gerçekleşir.
| Parametre | NSLog | os_log |
|---|---|---|
| Yazma mekanizması | Eşzamanlı disk yazma | Çekirdekte eşzamansız arabelleğe alma |
| 10.000 çağrı süresi | ~2,8 sn | ~0,3 sn |
| FPS üzerindeki etkisi | 5–8 kare kaybı | 0 kare |
| Kritiklik seviyeleri | Hiçbiri | 5 seviye |
| Gizlilik | Tüm veriler görünür | Otomatik maskeleme |
| Filtreleme | Desteklenmiyor | subsystem / category / level'e göre |
os_log iki API'ye sahiptir: klasik C tarzı os_log_create ve iOS 14'te tanıtılan modern Swift sarmalayıcı Logger. Swift Logger, biçimlendirme için ResultBuilder sistemini kullanır — argümanlar, açık gizlilik işaretlemesiyle dize değişmezleri aracılığıyla enterpolasyona tabi tutulur.
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, bir cihazdan toplanan günlükleri dışa aktarmak için bir komut satırı yardımcı programıdır. USB aracılığıyla cihaz bir Mac'e bağlandıktan sonra Terminal'den çalıştırılır.
// .logarchive'de günlük toplama
// Terminal'de: log collect --device --output ./app_logs.logarchive
// subsystem günlüklerini görüntüleme: log show --subsystem com.example.app
// Dinamik değerlerle günlük kaydı
logger.log("User \(userId) opened screen \(screenName)")
Logger kullanırken, argümanların os_log'un C sürümündeki gibi biçim dizeleri aracılığıyla değil, Dize Enterpolasyonu (String Interpolation) aracılığıyla enterpolasyona tabi tutulduğunu hatırlamak önemlidir. Bu daha güvenlidir, ancak varsayılan davranış geliştirici için uygun değilse her argüman için açık gizlilik işaretlemesi gerektirir.
Sıkça Sorulan Sorular
os_log, mesajları çekirdekte eşzamansız olarak arabelleğe alır ve ana iş parçacığını bloke etmez, oysa NSLog eşzamanlı olarak diske yazar. os_log 10 kat daha hızlıdır, 5 kritiklik seviyesi sunar ve özel verileri otomatik olarak maskeler — NSLog bu özelliklerin hiçbirine sahip değildir.
Geçici hata ayıklama mesajları için .debug kullanın — üretim yapılarında devre dışı bırakılır ve kullanıcı performansını etkilemezler. Her zaman korunması gereken önemli mesajlar için .default veya .info kullanın.
Xcode'da Configure Profile aracılığıyla: Devices → cihazı seçin → Open Console → Actions → Configure Profile. İstenen subsystem için toplama seviyesini Include olarak ayarlayın. Bu, cihazın ilk yeniden başlatılmasına kadar aktif kalan bir profil oluşturur.
Evet, os_log ek kurulum gerektirmeden tüm SwiftUI uygulamalarında çalışır. Modelinizde veya bir View uzantısında statik bir Logger oluşturun ve ekran yaşam döngüsünü izlemek için bunu onChange, task ve jest işleyicilerinde kullanın.
Varsayılan olarak, os_log dizeleri ve nesneleri private olarak maskeler. Değeri görmek için enterpolasyonda açıkça privacy: .public belirtin. Bu işaretleme olmadan, üretim yapılarında değerler maske ile değiştirilecektir, ancak Xcode hata ayıklamasında normal şekilde görüntülenirler.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun