Kendi sunucunda hata takibi: Sentry ile GlitchTip arasında nasıl seçim yapılır
Kendi sunucunuzda Sentry yirmiyi aşkın servis ve 16 GB RAM ister, GlitchTip aynı işi 512 MB ile yapar. İki seçeneğin lisans, kaynak ve özellik farklarını karşılaştırıyor; Sentry uyumlu bir sunucuya geçerken tarayıcı SDK'sının DSN doğrulaması yüzünden ön yüz hatalarının aylarca sessizce kaybolmasına yol açan tuzağı ve nasıl önleneceğini anlatıyoruz.
Log değil, hataların kendisi
Metrik bir sistemin ne kadar yüklendiğini, log ne yaptığını, iz de bir isteğin hangi servislerden geçtiğini anlatır. Hata takibi bunların hiçbirinin cevaplamadığı bir soruyu cevaplar: bu sürümde hangi istisna, kaç ayrı kullanıcıda, hangi yığın izini üreterek patlıyor ve bu ilk kez mi oluyor? Log satırı aynı veriyi taşır, ama gruplanmamış, sürüme bağlanmamış, tekrarı sayılmamış hâlde taşır. Günde yüz binlerce satır akan bir sistemde "aynı NullPointerException 40 bin kez düştü ama hepsi tek bir kullanıcıdan geliyor" tespitini elle çıkarmak mümkün değil. Hata takip araçlarının asıl işi bu parmak izi çıkarma, gruplama ve ilk/son görülme takibidir. Kırık ekranların geri kalanı bu çekirdeğin etrafına dizilmiş süstür.
Kendi sunucusunda çalışmak isteyen bir ekibin önünde pratikte üç yol var: barındırılan Sentry, kendi sunucunuzda Sentry, GlitchTip. Bu üçünü ayıran şey özellik listesi değil, işletme maliyeti ve lisans.
Kaynak farkı bir ayrıntı değil, kararın kendisi
Kendi sunucunuzda Sentry, tek bir uygulama değil, bir veri platformudur. Resmî kurulum belgesi asgari olarak 4 çekirdek, 16 GB RAM ve 20 GB disk ister; gerçek trafik altında işletenlerin verdiği rakamlar bunun üzerindedir. Compose dosyası yirmiyi aşan servis ayağa kaldırır: PostgreSQL, Redis, memcached, Kafka ve Zookeeper, ClickHouse, sorgu katmanı olarak Snuba, alım kapısı olarak Relay, native sembolizasyon için Symbolicator, bunların üstüne birkaç ayrı worker ve zamanlayıcı. Bu mimarinin bir sebebi var; olay hacmi yüz milyonlara çıktığında bu ayrışma işe yarıyor. Ama günde birkaç bin olay gören bir ekipte, izlemek için kurduğunuz sistem izlediğiniz sistemden pahalıya gelir. Kafka'nın disk doldurması, ClickHouse'un birleştirme sırasında bellek yemesi, sürüm yükseltmelerinde migration'ların yarım kalması sizin sorununuz olur.
GlitchTip aynı işi tek bir Django uygulamasıyla yapar. Belgelendirilmiş önerisi 512 MB RAM; hepsi-bir-arada kurulumda asgari 256 MB, dikkatli yapılandırmayla 128 MB artı takas. Zorunlu bağımlılığı PostgreSQL 14 ve üzeridir, Redis ya da Valkey büyük kurulumlarda performans için önerilir ama şart değildir. Ölçekleme ihtiyacı doğduğunda web ve worker süreçlerini ayırırsınız, hepsi bu. Disk tarafında ayağı yere basan bir rakam veriyorlar: ayda 1 milyon olay için 30 GB civarı.
İki kat değil, otuz kat fark var. Bu farkın karşılığında ne verdiğinizi bilmek gerekiyor.
Lisans
Sentry 2023 sonunda Functional Source License'a (FSL) geçti. FSL, Business Source License soyundan gelir: kaynak kod açıktır, okuyabilir, değiştirebilir, kendi işinizde çalıştırabilirsiniz, ama rakip bir ürün üretemezsiniz. İki yıl sonra her sürüm Apache 2.0'a (Sentry'nin seçtiği gelecek lisans) döner. FSL, OSI onaylı bir açık kaynak lisansı değildir.
Pratikte bunun anlamı şu: kendi uygulamalarınızın hatalarını izlemek için Sentry'yi kendi sunucunuzda çalıştırmak lisans açısından sorun değildir. Sorun, müşterilerinize hata takibi hizmeti sunmak isterseniz başlar. Bir ajans, bir barındırma sağlayıcısı ya da çok kiracılı bir platform işletiyorsanız FSL'in "competing use" tanımına dikkatle bakmanız gerekir. Kurumsal satın alma süreçlerinde hukuk ekibinin "OSI onaylı mı?" sorusuna hayır cevabı vermek de ayrı bir maliyettir.
GlitchTip MIT lisanslıdır. Bu soruların hiçbiri yoktur.
GlitchTip'in bilinçli olarak durduğu yer
GlitchTip'i "hafif Sentry" diye anlatmak yanıltıcı. Sentry'nin küçültülmüş hâli değil, en çok kullanılan protokol yüzeyinin yeniden yazılmış hâli. Kapsamadığı şeyler var ve bunlar dokümanda küçük yazıyla saklanmıyor:
- Oturum tekrarı (session replay) yok. Bu bir arayüz eksiği değil, protokol boşluğu; SDK olayları gönderir, sunucu sessizce düşürür.
- Profil çıkarma (profiling) yok.
- Dağıtık iz derinliği yok. Span desteği geliştirme aşamasında ve Sentry'deki span şelalesi, sorgu analizi, N+1 tespiti gibi katmanların karşılığı bulunmuyor.
- Native sembolizasyon yok. iOS/Android/C++ tarafında dSYM, PDB ya da breakpad sembolleri yükleyip çökmeleri okunur hâle getiriyorsanız GlitchTip bu ihtiyacı karşılamaz. Sentry'nin bunun için ayrı bir servisi olması boşuna değil.
- Gruplama algoritmaları daha basit. Sentry'nin yıllardır rafine ettiği fingerprint mantığının inceliklerini beklemeyin.
Web ve API uygulamalarında bu listenin çoğu zaten kullanılmıyor. Mobil uygulama yayınlıyorsanız dördüncü madde tek başına kararı verir.
SDK uyumu ne kadar gerçek
GlitchTip kendi istemci kütüphanesini yazmaz; Sentry'nin resmî SDK'larıyla çalışır. Bunun ne kadar iyi çalıştığı şaşırtıcı: uygulama kodunuzda tek satır değişmez, yalnız DSN değişir. Backend tarafında hata düşer, yığın izi gelir, sürüm etiketleri, kullanıcı bağlamı, breadcrumb'lar, beforeSend kancaları, örnekleme oranı, hepsi çalışır.
Buradaki tehlike de tam olarak bu: uyum o kadar iyi ki, çalışmayan tek yeri fark etmezsiniz.
Sessizce ölen ön yüz
Sentry uyumlu bir sunucuya geçen ekiplerin başına gelen ve teşhis edilmesi en zor problem şudur: arka uç hataları düşmeye devam eder, tarayıcı hataları aylarca hiç ulaşmaz.
Sebebi tek bir düzenli ifade. Sentry'nin JavaScript SDK'sı DSN'i şöyle bir kalıpla doğrular:
/^(?:(\w+):)\/\/(?:(\w+)(?::(\w+)?)?@)((?:\[[:.%\w]+\]|[\w.-]+))(?::(\d+))?\/(.+)/
Dikkat edilecek yer, public key'i yakalayan ikinci grup: (\w+). JavaScript'te \w yalnızca [a-zA-Z0-9_] demektir. Tire bu kümede yoktur. Host kısmı [\w.-]+ olduğu için tireli alan adları sorunsuz geçer; anahtar kısmı geçmez.
Sentry uyumlu sunucular proje anahtarını sık sık UUID olarak üretir ve UUID'nin standart yazımı tirelidir:
https://[email protected]/3
Bu DSN'i Sentry.init()'e verdiğinizde SDK istisna fırlatmaz. Kalıp eşleşmez, dsnFromString() konsola tek bir satır basar (Invalid Sentry Dsn: ...) ve undefined döner. İstemci hiç kurulmaz. Sentry.captureException() çağrılarınız çalışmaya devam eder, hata vermez, hiçbir yere bir şey göndermez.
Bunun aylarca fark edilmemesinin sebepleri sırasıyla:
- Uyarı yalnızca tarayıcı konsoluna düşer. Sunucu logunda, uygulama logunda, CI çıktısında hiçbir iz yoktur.
- Backend SDK'ları (Python, PHP, Go, Java) aynı doğrulamayı yapmaz ya da farklı bir kalıp kullanır. Backend hataları düşmeye devam ettiği için pano dolu görünür.
- Ön yüz hataları zaten seyrektir. "Bu hafta hiç JS hatası yok" cümlesi kimseyi rahatsız etmez.
- Geliştirici konsolunda tek satırlık bir uyarı, üçüncü parti scriptlerin ürettiği gürültünün içinde kaybolur.
Düzeltmesi basit. Anahtardaki tireleri temizleyip DSN'i öyle verin:
https://[email protected]/3
Tiresiz 32 haneli onaltılık dizi geçerli bir UUID yazımıdır; hem Python'un uuid.UUID çözümleyicisi hem PostgreSQL'in uuid tipi bu biçimi aynı değer olarak kabul eder, yani sunucu tarafında arama bozulmaz. Yalnız anahtar kısmındaki tireleri silin. Adresteki tirelere dokunmayın, orada tire silmek DSN'i başka bir sunucuya yollar.
Bunu tek bir yerde, DSN'i üreten ortak koda koyun. Her uygulamada elle temizlenmiş DSN yazmak, bir sonraki projede aynı hatayı yeniden üretmenin en garantili yoludur.
Geçişten sonra yapılacak tek şey
Sunucu değiştirdiğinizde "backend hataları geliyor, demek ki çalışıyor" cümlesi bir kanıt değildir. Ölçün:
Uygulamanın canlı bir sayfasını açın, tarayıcı konsoluna şunu yazın:
Sentry.captureException(new Error("dsn dogrulama testi"));
Sonra yeni panoda o olayı arayın. Görünmüyorsa aynı konsolda Sentry.getClient() çağırın; undefined dönüyorsa istemci hiç kurulmamış demektir, sorun DSN'dedir. Bu iki komut, aylarca sürebilecek bir kör noktayı kırk saniyede kapatır. Aynı testi yalnız geçiş sonrasında değil, SDK sürümü yükselttiğinizde de tekrarlayın.
Kim hangisini seçmeli
Ön yüzü olan bir web uygulaması ya da API çalıştırıyorsanız, olay hacminiz günde birkaç yüz binin altındaysa ve oturum tekrarına ihtiyacınız yoksa GlitchTip'i seçin. Tereddüt etmeyin. Kendi sunucunuzda Sentry'nin size vereceği ek değer, ona ödeyeceğiniz işletme vergisinin çok altında kalır; 16 GB'lık bir makineyi ve düzenli bakım zamanını hata takibine ayırmak, o kaynağı asıl işinize ayırmamak demektir.
Mobil uygulama yayınlıyorsanız, native çökmeleri sembolize etmeniz gerekiyorsa ya da performans sorunlarını span düzeyinde kovalıyorsanız, barındırılan Sentry'yi seçin. Kendi sunucunuzda Sentry'yi değil. Bu özellikleri isteyen bir ekip, o özellikleri ayakta tutan yirmi konteyneri de işletmek zorunda kalır ve o iş göründüğünden büyüktür.
Kendi sunucunuzda Sentry yalnızca iki koşul birlikte sağlanıyorsa mantıklıdır: verinin dışarı çıkmasının hukuken imkânsız olması ve bu platformu işletecek ayrılmış bir ekibin bulunması. İkisinden biri eksikse yanlış tarafa düşersiniz.
Hangisini seçerseniz seçin, kurduktan sonra tarayıcı konsolundan bir test olayı gönderip panoda görün. Kurulumun bittiği an, ilk olayın düştüğü andır.