Structured Logging, her mesajın yapılandırılmamış metin yerine anahtar-değer çiftleriyle makine tarafından okunabilir bir biçimde temsil edildiği bir log kaydı yaklaşımıdır. Düz dizelerin aksine, yapılandırılmış loglar meta veri içerir: zaman damgası, seviye, modül, istek kimliği — ve analiz sistemleri tarafından indekslenebilir. O'Reilly Effective Logging’e göre, yapılandırılmış biçimlere geçiş, alanlara göre filtreleme imkanı sayesinde olay arama süresini saatlerden dakikalara düşürür. Bu, modern mobil ve sunucu geliştirmede fiili standarttır: JSON ve logfmt, logların gözlerle değil, programlarla işlenmesine olanak tanır.
Kilit Noktalar
Structured Logging, her mesajın adlandırılmış alanlar ve tür belirtilmiş değerler içerdiği bir log kaydetme yöntemidir. User 42 logged in from device ABC gibi bir dize yerine, yapılandırılmış bir log bir dizi alan olarak görünür: user_id=42, event=login, device_id=ABC, timestamp=2026-07-04T10:30:00Z.
Yapılandırılmış logların metin loglarına göre ana avantajı, programatik işleme yeteneğidir. Metin loglarını ayrıştırmak, düzenli ifadeler ve dize biçimi hakkında varsayımlar gerektirir. Yapılandırılmış loglar kayıpsız ayrıştırılır: her alanın bilinen bir türü ve adı vardır, bu da ek işlem gerektirmeden kullanıcı 42 için son bir saatteki tüm kimlik doğrulama hatalarını bul gibi sorgular oluşturulmasına olanak tanır.
Honeycomb.io’ya (2023) göre, üretimde structured logging kullanan ekipler, metin loglarına ve grep’e güvenen ekiplere kıyasla olayları ortalama 4 kat daha hızlı tespit eder.
Structured Logging birden çok serileştirme biçimini destekler. Biçim seçimi altyapıya bağlıdır: JSON, Elasticsearch ve bulut sistemleriyle entegrasyon için uygundur, logfmt tail ve grep ile konsol görüntüleme için, Protocol Buffers bant genişliği sınırlamaları olan yüksek performanslı sistemler için.
| Biçim | Örnek | Ne Zaman Kullanılır |
|---|---|---|
| JSON | {"event":"login","user_id":42} | ELK Stack, bulut toplayıcılar, mikroservisler |
| Logfmt | event=login user_id=42 duration_ms=150 | Konsol, tail, heroku logs |
| MessagePack | JSON’ın ikili eşdeğeri | Yüksek yüklü sistemler, IoT |
JSON yapılandırılmış loglar için en yaygın biçimdir. Tüm toplama sistemleri tarafından yerel olarak desteklenir: Logstash, Fluentd, Amazon CloudWatch, Google Cloud Logging. JSON logları insanlar tarafından kolayca okunabilir ve ek kütüphane olmadan herhangi bir programlama diliyle ayrıştırılabilir. Ana dezavantajı ayrıntılılıktır: her anahtar-değer çifti tırnak işaretleri ve iki nokta gerektirir, bu da logfmt’a kıyasla depolanan veri hacmini %30–50 artırır.
Logfmt Heroku’da konsol görünürlüğü için geliştirilmiştir. JSON’dan daha kompakttır, insan okunabilirliğini korur ve cut ve awk ile kolayca işlenebilir. Örnek: ts=2026-07-04T10:30:00Z level=error module=api status=500. Logfmt çoğu karakterin kaçılmasını gerektirmez ve konteynırlarda stdout loglama için uygundur.
Mobil uygulamalarda Structured Logging üç temel sorunu çözer: bir cihazda yeniden üretmeye gerek kalmadan çökme nedenlerini bulma, kullanıcı oturumlarını izleme ve uygulama sürümlerine göre performans analizi.
Mobil cihazlardaki metin logları neredeyse işe yaramaz — bir geliştirici kullanıcının cihazındaki logları grep ile arayamaz. Yapılandırılmış loglar bulut sistemlerine (Firebase, Sentry, Datadog) gönderilir ve orada indekslenir. iOS 17.4, uygulama sürümü 3.2, ödeme modülündeki tüm çökmeleri göster gibi bir sorgu oluşturabilir ve saniyeler içinde doğru bir seçim elde edebilirsiniz.
Sentry’e (2024) göre, yapılandırılmış breadcrumbs kullanan uygulamalar, yalnızca hata metnini loglayan uygulamalara kıyasla her çökme raporunda %60 daha fazla bağlama sahiptir. Bu, hata düzeltme hızını doğrudan etkiler.
ELK Stack — Elasticsearch, Logstash, Kibana — yapılandırılmış loglarla çalışmak için standart altyapı olmaya devam etmektedir. Logstash logları JSON biçiminde alır, dönüştürür ve indeksleme için Elasticsearch’e gönderir, Kibana sorgular ve panolar için görsel bir arayüz sağlar.
Mobil uygulamalar için bulut çözümleri popülerdir: Firebase Crashlytics özel loglarla, Sentry breadcrumbs ile, Datadog APM izleme ile. Bunlar yapılandırılmış logları doğrudan mobil SDK’dan kabul eder ve kendi arka uçlarını dağıtmayı gerektirmez. Firebase çökme raporları için ücretsiz bir paket sunar, Sentry dağıtık izleme ekler ve Datadog, istemci ve sunucuda aynı anda istek performansını izlemek için APM ile entegre olur.
Grafana Loki — loglar için optimize edilmiş bir Elasticsearch alternatifi. Loki varsayılan olarak mesaj içeriğini indekslemez, filtreleme için etiketler (labels) kullanır. Bu, depolamada önemli ölçüde daha ucuz ve sabit bir alan kümesinde sorgulamalar için daha hızlıdır.
// Swift Logger ile JSON’da yapılandırılmış loglama
struct StructuredLog {
let event: String
let attributes: [String: Any]
let level: String
func serialize() -> String {
var base = "event=\(event) level=\(level)"
for (key, value) in attributes {
base += " \(key)=\(value)"
}
return base
}
}
Yapılandırılmış loglamanın ilk kuralı: her mesaj bir istek veya oturum tanımlayıcısı içermelidir. Bağlam olmadan, tek bir log işe yaramaz — hangi kullanıcıya veya isteğe ait olduğunu belirlemek imkansızdır. Oturum başlangıcında bir correlation ID ekleyin ve uygulamanın tüm katmanları boyunca iletin.
İkinci kural: alan türlemesi. Sayısal alanlar (duration_ms, status_code, retry_count) dizeler olarak değil, sayılar olarak iletilmelidir. Elasticsearch ve benzer sistemler sayıları ve dizeleri farklı şekilde indeksler: sayılar toplanabilir (ortalama, medyan, yüzdelik), dizeler tam metin aramasını destekler. Yanlış türleme, analitik panoların oluşturulmasını engeller.
Üçüncü kural: iç içe nesnelerden kaçının. 2 seviyeden fazla iç içelik derinliğine sahip JSON logları filtrelemek ve görselleştirmek zordur. {"user": {"name": "Alice", "role": "admin"}} yerine düz anahtarlar kullanın: user_name=Alice user_role=admin.
// Timber + logfmt ile Android’de yapılandırılmış loglama
class StructuredTree : Timber.Tree() {
override fun log(priority: Int, tag: String?,
message: String?, t: Throwable?) {
val level = priorityToLevel(priority)
val logfmt = "level=$level tag=$tag message=$message"
sendToRemote(logfmt)
}
}
Her yapılandırılmış mesaj için minimum alan seti: ISO 8601 biçiminde timestamp, level (debug/info/warn/error/fatal), logger (modül veya sınıf adı), message (olayın insan tarafından okunabilir açıklaması). Ek olarak: correlation_id, user_id (varsa), version (uygulama sürümü), platform (iOS/Android), environment (dev/staging/prod).
correlation_id olmadan, yapılandırılmış loglar tek bir kullanıcı senaryosunda birleştirilemeyen dağınık kayıtlar topluluğuna dönüşür. Her uygulama başlatıldığında bir UUID oluşturun ve tüm oturum loglarına ekleyin. Pratikte, correlation ID tüm katmanlar boyunca iletilmelidir: UI olaylarından ağ isteklerine ve arka plan görevlerine kadar — aksi takdirde bazı loglar bağlamsız kalır ve analize katılmaz. Uçtan uca izleme ile tek bir UUID, kullanıcı yolculuğunun tam resmini toplamaya olanak tanır.
iOS’ta, yapılandırılmış loglama, alanları logfmt biçimine serileştiren os_log üzerine bir sarmalayıcı ile uygulanabilir. Android’de, sunucuya göndermeden önce mesajları JSON veya logfmt’a dönüştüren özel bir Tree ile Timber aracılığıyla.
import OSLog
struct StructuredLogger {
let subsystem: String
let category: String
func log(level: OSLogType,
event: String,
context: [String: Any]) {
let oslogger = Logger(
subsystem: subsystem,
category: category
)
let fields = context.map {
"\($0.key)=\($0.value)"
}.joined(separator: " ")
oslogger.log(level: level,
"\(event) \(fields)")
}
}
Yapılandırılmış ve metin logları arasındaki seçim proje aşamasına bağlıdır. Erken geliştirme aşamalarında, metin logları daha basit ve hızlıdır — geliştirici ek sarmalayıcılar olmadan doğrudan mesaj yazar. Ancak proje tek bir ekibin veya sunucunun ötesine geçtiğinde, yapılandırılmış loglar zorunlu hale gelir.
| Kriter | Metin Logları | Yapılandırılmış Loglar |
|---|---|---|
| Okunabilirlik | Konsolda yüksek | Orta (pretty-print gerekli) |
| Arama | Alt dizeye göre grep | Alanlara ve değerlere göre sorgu |
| Toplama | Desteklenmez | Ortalama, medyan, yüzdelikler |
| Entegrasyon | Ayrıştırma gerekli | ELK/Loki/Datadog’da yerel |
| Depolama hacmi | Daha küçük (meta veri yok) | Daha büyük (alanlar + değerler) |
Sıkça Sorulan Sorular
Sunucuya göndermek için JSON kullanın — Firebase Crashlytics, Sentry ve Datadog tarafından yerel olarak desteklenir. Xcode veya Android Studio loglarında yerel görüntüleme için logfmt kullanın — daha kompakttır ve biçimlendirme olmadan okunabilir.
Evet, istemcideki yapılandırılmış loglar her çökme raporuna bağlam eklemeye olanak tanır: işletim sistemi sürümü, ağ durumu, son kullanıcı eylemleri. Yapılandırılmış breadcrumbs olmadan, bir çökme raporu kullanıcı senaryosu olmadan yalnızca çağrı yığını içerir.
Logfmt daha kompakttır (%30–50 daha az hacim) ve terminalde okunması daha kolaydır. JSON iç içe nesneleri ve dizileri destekler ancak tırnak kaçışı gerektirir. Seçim altyapıya bağlıdır: ELK için — JSON, konsol görüntüleme için — logfmt.
Uygulama başlatıldığında UUID’nin tek bir örneğini oluşturun, bir singleton veya DI kabında saklayın ve yapıcı aracılığıyla tüm loglayıcılara iletin. Alternatif — Kotlin coroutine’lerinde iş parçacığı yerel deposu veya Continuation Local Storage kullanın.
Karıştırılabilir ancak önerilmez — karıştırma otomatik indeksleme yeteneğini kaybettirir. Bazı loglar metin tabanlıysa, düzenli ifadelerle ayrıştırılmaları gerekir, bu da arama performansını ve güvenilirliğini azaltır. Tüm logları yapılandırılmış biçime taşımak daha iyidir.
Ö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