Jetimza Brand Logo
v1.0  ·  Gözlemlenebilirlik & Denetim

Jetimza MVP Gözlemlenebilirlik & Denetim Tasarımı

jet-api için log, metrik, iz, denetim ve alarm mimarisi. imza.io SignGate ve Infrastructure'da hâlihazırda çalışan desen referans alınmıştır.

DurumÇalışma Dokümanı
Versiyonv1.0
LogSerilog → OTLP → Loki
MetrikOpenTelemetry → Prometheus
İzOTel → Tempo
Tasarımın Temel Sözü

Bir kullanıcı "imzam olmadı" dediğinde, destek ekibi tek bir işlem kimliğinden yola çıkarak o isteğin log'una, dağıtık izine ve altyapı yanıtına dakikalar içinde ulaşabilmelidir.

Üç Düzlem İlkesi

Gözlemlenebilirlik tasarımlarının en sık yapılan hatası, birbirinden çok farklı üç ihtiyacı tek mekanizmayla çözmeye çalışmaktır. Sonuç genellikle şudur: her veritabanı değişikliğini yazan bir denetim kancası — yazma yolunu yavaşlatır, okunamayacak kadar gürültülü bir tablo üretir ve asıl sorulan sorulara yine cevap veremez. Jetimza'da üç düzlem ayrı tutulur.

Düzlem 1

Telemetri

Ne
Yapısal log, metrik, dağıtık iz, profil
Nerede
Loki · Prometheus · Tempo · Pyroscope
Hacim
Yüksek — örneklenebilir
Saklama
Günler / haftalar
Doğruluk
Kaynak değildir. Kaybı tolere edilir
Soru
"Sistem sağlıklı mı, nerede yavaşladı, ne hata verdi?"
Düzlem 2

İş & Denetim

Ne
Token hareketleri, işlem geçişleri, yönetsel eylemler
Nerede
PostgreSQL — append-only tablolar
Hacim
Düşük — işlem başına birkaç satır
Saklama
Yıllar
Doğruluk
Doğruluk kaynağı. Kaybı kabul edilemez
Soru
"Bu kullanıcının bakiyesi neden bu, bu işlem kimin ve ne oldu?"
Düzlem 3

Toplama

Ne
Günlük özetler, huni oranları
Nerede
PostgreSQL — daily_*_stats
Hacim
Çok düşük — gün başına birkaç satır
Saklama
Kalıcı
Doğruluk
Dondurulmuş gerçek — geçmişe dönük değişmez
Soru
"Ürün çalışıyor mu, dönüşüm nasıl gidiyor?"
Düzlemleri birbirine bağlayan tek şey

correlation_id ve trace_id. Bu iki değer iş satırlarında kolon olarak tutulur (bkz. veritabanı dokümanı). Destek ekranındaki bir işlemden log'a ve ize geçiş bu köprüyle olur. Köprü olmazsa telemetri ve iş verisi iki ayrı ada olarak kalır ve hiçbiri tek başına soruyu cevaplayamaz.

Ne YAPMAYACAĞIZ

  • Kayıt katmanının kaydetme adımına takılan, her satır değişikliğini bir denetim tablosuna yazan genel kanca
  • Uygulama log'larını veritabanına yazmak
  • Metrik etiketlerine kullanıcı kimliği, telefon, kimlik numarası veya işlem kimliği koymak
  • Panoların ham işlem tablolarını canlı taraması
  • Her isteği tek tek loglayıp "gözlemlenebilirlik var" demek

Referans: Mevcut Altyapıda Ne Var

Aşağıdakiler imza.io'da bugün çalışan bileşenlerdir; jet-api sıfırdan bir şey icat etmeyecek, aynı deseni ve aynı toplama altyapısını kullanacaktır.

KatmanBileşenJetimza'da karşılığı
LogSerilog + ortam bazlı yapılandırmaAynı desen: serilog.{Environment}.json
Log bağlamıRequestContextEnricherRequestPath, RequestMethod, ClientIP, UserAgent, CorrelationId — aynı alan seti + UserId
İlişkilendirmeCorrelationIdMiddlewareX-Correlation-ID başlığı; yoksa etkin izin kimliği; o da yoksa yeni üretilir. Yanıt başlığına geri yazılır
MetrikOpenTelemetry + alan bazlı Meter'larSignGate 8 ayrı Meter kullanıyor; jet-api 6 Meter kullanacak
Adlandırmaimzaio_signgate_signature_duration_secondsimzaio_jet_<alan>_<ölçüm>_<birim> — aynı kural
HistogramHistogramBuckets (alan bazlı)SignGate Easy için 0,5–300 sn kova seti kullanıyor çünkü insan PIN giriyor. Jetimza imza kovaları aynı gerekçeyle geniş
İzOTel tracing + OTLP exporter filtresiAspNetCore, HttpClient enstrümantasyonu; dışa aktarım isteklerinin ize düşmemesi için filtre
Sağlık/health · /alive · /readyAynı üçlü
ProfilPyroscopeSürekli profilleme — CPU darboğazlarında tek gerçek araç
ToplamaAlloy → Loki / Prometheus / TempoAynı toplayıcı; jet-api yalnızca OTLP uç noktasını gösterir
AlarmPrometheus kuralları + AlertmanagerHer alarmda severity, component, team ve runbook_url
PanoGrafana (signgate, easy, clm, log-analytics, tracing)Yeni pano seti: funnel, signature-health, token-economy, sms
Asıl referans: SignGate denetimi ORM kancasıyla yapmıyor

SignGate'in denetim izi SignGate.Data altında amaca özel bir olay şemasıdır: cihaz → çalışan örnek → bağlantı → istek → olay, ayrıca kimlik ve sertifika kayıtları. Üzerine raporlama için önceden toplanmış günlük istatistik tablosu. Yani denetim, kayıt katmanına takılan genel bir kanca değil, alanın kendi olay modelidir. Jetimza da aynısını yapar: token_ledger, transaction_events ve audit_events.

Log Tasarımı

Her log satırında bulunması zorunlu alanlar

AlanKaynağı ve niçin
timestampUTC. Yerel saat asla yazılmaz.
levelAşağıdaki seviye disiplinine göre.
serviceimzaio-jet-api. Tek serviste bile zorunlu: Loki'de servis bazlı ayrım yapılabilsin.
environmentOrtam ayrımı. Aynı Loki birden çok ortamı toplar.
correlation_idAra katmandan. İş kayıtlarıyla köprü.
trace_id · span_idOTel bağlamından. Log satırından ize tek tıkla geçiş.
user_idKimliği doğrulanmış isteklerde. Telefon veya kimlik numarası değil.
request_path · request_methodZenginleştiriciden.
client_ip · user_agentZenginleştiriciden.

Seviye disiplini

SeviyeNe yazılır
Errorİşlem tamamlanamadı ve müdahale gerekebilir: altyapı erişilemedi, beklenmeyen istisna, token muhasebesi tutarsızlığı.
Warningİşlem tamamlanamadı ama beklenen bir sonuç: yanlış OTP, Easy kurulu değil, kart takılı değil, bakiye yetersiz. Bunlar hata değil kullanıcı durumudur; Error yazmak alarm gürültüsü üretir.
Informationİş olayları: OTP istendi/doğrulandı, kayıt tamamlandı, işlem başlatıldı/sonuçlandı, token askıya alındı/kesinleşti, gözcü işlemi kapattı.
DebugYalnızca geliştirme. Üretimde kapalı.
Yaşanmış tuzak — varsayılan seviyeyi Warning bırakmak

SignGate'te varsayılan log seviyesi Warning bırakıldığı için imza işlemlerinin log'ları tamamen kesilmişti; bir sorun yaşandığında elde hiçbir iz kalmadı. Ders: iş olayları Information seviyesindedir ve varsayılan seviye Information olmalıdır. Gürültü, Microsoft.* ve System.* ad alanları Warning'e çekilerek kısılır — kendi kodumuz kısılarak değil.

// serilog.Production.json — seviye ayarı "MinimumLevel": { "Default": "Information", // kendi kodumuz: iş olayları görünür "Override": { "Microsoft": "Warning", "Microsoft.AspNetCore": "Warning", "Microsoft.EntityFrameworkCore": "Warning", "System.Net.Http": "Warning" } }

Log'a ASLA yazılmayacaklar

  • OTP kodu — ne düz ne özet hâliyle; hata ayıklama gerekçesiyle bile
  • Kimlik numarası — veritabanında şifreli saklanıyor olması log'a yazılabileceği anlamına gelmez; gövde loglaması kapalı olmalı, gösterim daima maskeli
  • Telefon numarası — maskeli yazılır: +90 532 *** ** 67
  • Oturum ve yenileme jetonları, yetkilendirme başlığı
  • Belge içeriği, imza baytları, PIN
  • Tam istek/yanıt gövdeleri — yalnızca hata durumunda, alan bazlı seçilerek ve maskelenerek
Maskeleme nerede yapılır

Uygulama içinde, log yazılmadan önce — toplayıcıda değil. Toplayıcıda maskelemek, verinin bir kez de olsa maskesiz üretildiği anlamına gelir; yerel dosya log'u veya konsol çıktısı açıksa veri oradan sızar. Maskeleme kaynağında yapılır.

Metrik Tasarımı

SignGate'in ayrımını izleyerek metrikler alan bazlı ölçüm gruplarına bölünür. Bu, hem dışa aktarımın seçmeli yapılabilmesini hem de panoların temiz kalmasını sağlar.

imzaio-jet-api // HTTP yüzeyi (büyük ölçüde hazır enstrümantasyon) imzaio-jet-auth // OTP, kayıt, oturum imzaio-jet-token // Jet Token muhasebesi imzaio-jet-transaction // imza / doğrulama / zaman damgası imzaio-jet-signgate // dış çağrı istemcisi imzaio-jet-sms // gönderim ve maliyet

Ölçüm listesi

MetrikTipEtiketler ve amaç
imzaio_jet_otp_requested_totalcounterpurpose — SMS talebi hacmi
imzaio_jet_otp_verified_totalcounterpurpose, result (success·invalid_code·expired·max_attempts) — OTP başarı oranı
imzaio_jet_sms_delivery_totalcounterprovider, status — teslim oranı
imzaio_jet_sms_delivery_secondshistogramprovider — kullanıcının kodu bekleme süresi
imzaio_jet_sms_cost_micros_totalcounterprovidertek gerçek değişken maliyet
imzaio_jet_registration_totalcounterresult — üyelik dönüşümü
imzaio_jet_token_grant_totalcounterkind — dağıtılan token
imzaio_jet_token_movement_totalcounterreason (hold·commit·release·expiry) — muhasebe akışı
imzaio_jet_token_stuck_holdsgaugeaskıda kalmış token sayısı; muhasebe sağlığının tek göstergesi
imzaio_jet_transaction_totalcountertype, channel
imzaio_jet_transaction_succeeded_totalcountertype, channel
imzaio_jet_transaction_failed_totalcountertype, channel, failure_code
imzaio_jet_transaction_duration_secondshistogramtype, channel — uçtan uca süre
imzaio_jet_transaction_queue_secondshistogramtype — kuyrukta bekleme; işçi yetersizliğinin ilk işareti
imzaio_jet_transaction_inflightgaugechannel — anlık açık işlem
imzaio_jet_transaction_expired_totalcounterchannel — gözcünün kapattıkları
imzaio_jet_preflight_totalcounterchannel, reason — kullanıcı hangi engele takılıyor
imzaio_jet_signgate_duration_secondshistogramoperation — dış bağımlılığın payı
imzaio_jet_signgate_failed_totalcounteroperation, error

Histogram kovaları — alan bazlı

Tek bir kova seti tüm ölçümlere uymaz. SignGate bunu doğru yapmış: Easy kanalı için 0,5–300 saniye aralığı kullanılıyor çünkü arada insan var, PIN giriyor. Jetimza aynı mantığı uygular.

Api = 0.01, 0.05, 0.1, 0.25, 0.5, 1, 2, 5 // saf sunucu işi Sms = 1, 2, 3, 5, 8, 13, 21, 34, 60 // operatör şebekesi SignEasy = 1, 2, 5, 10, 20, 30, 60, 120, 180, 300 // kullanıcı PIN giriyor SignMobile = 5, 10, 20, 30, 45, 60, 90, 120, 180, 300 // operatör onayı bekleniyor Verify = 0.1, 0.25, 0.5, 1, 2, 5, 10 // sunucu işi Queue = 0.1, 0.25, 0.5, 1, 2, 5, 10, 30 // kuyruk beklemesi

Kova seçimi keyfi değildir: alarm eşiği hangi değerse, o değerin bir kova sınırı olması gerekir. Aksi hâlde yüzdelik hesabı kovalar arasında doğrusal tahmin yapar ve alarm eşiği etrafında yanlış sonuç verir.

Etiket kardinalitesi — sessiz katil

Metrik etiketlerine kullanıcı kimliği, telefon, kimlik numarası, işlem kimliği veya belge adı konulmaz. Her benzersiz etiket birleşimi ayrı bir zaman serisi üretir; kullanıcı kimliği etiketi 9 bin kullanıcıda 9 bin seri demektir ve bu Prometheus'u birkaç günde tüketir. Bu tür ayrıntı log'a ve ize aittir, metriğe değil. Metrik "kaç tane ve ne kadar sürdü" sorusunu; log ve iz "hangisi ve neden" sorusunu cevaplar.

İz & Profil

Dağıtık iz, imza akışının hangi adımında zaman geçtiğini gösteren tek araçtır: jet-api'nin kendi işi mi, kuyrukta bekleme mi, SignGate çağrısı mı, yoksa kullanıcının PIN girmesi mi.

İz kapsamları

Kapsamİçerdiği öznitelikler
POST /v1/signaturesGelen istek. transaction.id, transaction.type, channel, document.size
token.holdAskıya alma. grant.kind, balance_after
transaction.queue_waitKuyrukta geçen süre — işçi darboğazı burada görünür
signgate.sign_fileDış çağrı. operation, signgate.request_ref, http.status_code
token.commit / token.releaseMuhasebenin kapanışı
Örnekleme kararı

İmza işlemleri %100 örneklenir. Bunlar düşük hacimli ve yüksek değerli olaylardır; bir imzanın izi kaybolursa o kullanıcının şikâyeti araştırılamaz. Sağlık uçları ve statik istekler ize hiç alınmaz. Dışa aktarım isteklerinin kendisinin ize düşmemesi için filtre uygulanır — SignGate'te bu filtre geri besleme döngüsünü önlemek için zaten var.

Profil

Pyroscope sürekli profillemesi ilk günden açılır. Gerekçe deneyimseldir: imza altyapısında yaşanan CPU baskısı sorunlarında darboğazın nerede olduğunu gösteren tek araç sürekli profillemeydi; olaydan sonra açmak, olayı kaçırmak demektir.

Denetim Kaydı

Denetim, veritabanındaki üç append-only tabloya dayanır. Hiçbiri kayıt katmanına takılan genel bir kanca değildir; her biri alanın kendi olay modelidir.

TabloNeyi kanıtlarYazılma anı
token_ledgerBakiyenin her kuruşunun nereden geldiği ve nereye gittiğiToken değişimini yapan iş adımının kendi işlem bloğunda
transaction_eventsBir işlemin hayat hikâyesi; kim ilerletti, nerede koptuHer durum geçişinde
audit_eventsHesap sorulabilir yönetsel ve güvenlik eylemleriYalnızca anlamlı eylemlerde

audit_events'e yazılan eylemler

EylemNiçin denetlenir
token_request.approved / rejectedMVP'de onay elle veriliyor — kim, ne zaman, hangi gerekçeyle sorusu cevapsız kalamaz
token.manual_grantElle token tanımlama; ekonominin dışına çıkan tek yol
user.suspended / reactivatedHesap erişimini etkileyen eylem
invite.disabledKötüye kullanım müdahalesi
invite_redemption.fraud_flaggedÖdül iptali; kullanıcıyı doğrudan etkiler
consent.revokedKVKK açısından kanıtlanması gereken irade
auth.refresh_token_reuse_detectedJeton hırsızlığı şüphesi — güvenlik olayı
object.deleted_by_retentionBelgenin saklama süresi dolduğu için silindiğinin kanıtı
Neden "her değişikliği yaz" değil

Her satır güncellemesini yazan bir denetim mekanizması üç sorun üretir: yazma yolu yavaşlar, tablo okunamayacak kadar büyür, ve en önemlisi gürültü içinde asıl olay kaybolur. Bir operatörün 200 token'ı elle tanımlaması ile bir kullanıcının son giriş zamanının güncellenmesi aynı tabloda aynı ağırlıkta duramaz. Denetim, hesap sorulabilir eylemlerin kaydıdır; veri değişikliklerinin dökümü değil.

Alarm & Servis Düzeyi Hedefleri

Alarmlar, SignGate'in kural dosyalarındaki biçimi izler: her kuralda önem derecesi, bileşen, takım ve çalıştırma kitabı bağlantısı bulunur. Bağlantısı olmayan alarm, gece 3'te uyanan kişiye hiçbir şey söylemez.

AlarmÖnemKoşul ve gerekçe
OtpDeliveryFailureRatewarningBaşarısız gönderim oranı 10 dakika boyunca %5'i aşarsa. Kullanıcı üye olamıyor demektir — huninin en üstü kırılır.
OtpDeliveryStalledcritical15 dakikadır hiç teslim yok ama talep var. Sağlayıcı tamamen düşmüş.
OtpVerificationRateLowwarningDoğrulanan / istenen oranı 30 dakika boyunca %50'nin altında. Ya SMS gecikiyor ya akışta bir kusur var.
SignatureSuccessRateLowwarningKanal bazında başarı oranı 15 dakika boyunca %85'in altında.
SignatureLatencyHighwarningP95 süre kanal eşiğini aşarsa (Easy 180 sn, mobil 120 sn).
TokenStuckHoldscriticalAskıda kalmış token sayısı sıfırdan büyük ve artıyorsa. Kullanıcının bakiyesi haksız yere kilitli demektir; para benzeri bir hatadır.
TransactionQueueBacklogwarningKuyruk bekleme P95'i 30 saniyeyi aşarsa. İşçi yetersiz ya da takılmış.
WatchdogExpiryRateHighwarningSüre aşımıyla kapanan işlem oranı yükselirse. Altyapı yanıt vermiyor olabilir.
SignGateUnavailablecriticalDış çağrı hata oranı %50'yi aşarsa. İmza tamamen durmuş demektir.
SmsCostSpikewarningSaatlik SMS maliyeti normalin katına çıkarsa. Kötüye kullanımın faturaya yansımadan önce yakalandığı tek yer.
# jetimza-sla.yml — SignGate kural biçimiyle birebir groups: - name: jetimza_sla interval: 15s rules: - alert: TokenStuckHolds expr: imzaio_jet_token_stuck_holds > 0 for: 10m labels: { severity: critical, component: token, team: jetimza } annotations: summary: "Askıda kalmış token var" description: "{{ $value }} işlemde token askıda; bakiye haksız kilitli" runbook_url: "https://docs.imza.io/runbooks/jetimza-token-stuck-holds"
Askıda kalan token ölçümü nereden gelir

Bu değer metrik akışından değil, veritabanından periyodik olarak okunur: sonuçlanmış görünmeyen ama askı kaydı olan işlemler sayılır. İş doğruluğunu ilgilendiren ölçümlerde kaynak daima doğruluk kaynağıdır — sayaçların kendisi değil. Sayaç kaybolabilir; veritabanı kaybolmaz.

Panolar

PanoKaynakİçerik ve kime hitap eder
jetimza-funnelPostgreSQLÜrün panosu. Günlük özet tablolarından: OTP başarı oranı, üyelik dönüşümü, üyelik → ilk imza, davet dönüşümü. Stratejinin dört başarı ölçütü birebir burada.
jetimza-signature-healthPrometheusMühendislik panosu. Kanal bazında başarı oranı, süre yüzdelikleri, hata kodu dağılımı, kuyruk bekleme, açık işlem sayısı, ön-uçuş engelleri.
jetimza-token-economyPostgreSQL + PrometheusDağıtılan/harcanan token, askıdakiler, ek talep kuyruğu, davet ödülleri, kullanıcı başına ortalama tüketim.
jetimza-smsPrometheusSağlayıcı bazında teslim oranı, gecikme, saatlik maliyet, hata kodu dağılımı.
jetimza-logsLokiHata akışı, ilişkilendirme kimliğiyle arama, seviye dağılımı.
Ürün panosu neden Prometheus'tan değil

Dönüşüm oranları kesin olmalıdır ve geçmişe dönük değişmemelidir. Metrik sistemi örnekleme, kesinti ve saklama sınırı olan bir sistemdir; üç ay önceki dönüşüm oranını oradan okumak güvenilir değildir. Günlük özet tabloları bu yüzden var: pano onları okur, sayı değişmez. Mühendislik panoları ise anlıklığı önemsediği için Prometheus'tan beslenir. Aynı ayrımı imza.io altyapısında sertifika yaşam döngüsü panosu da yapıyor — kaynağı doğrudan PostgreSQL.

Saklama, Maliyet & KVKK

VeriÖnerilen süreGerekçe
Log (Loki)30 günOlay incelemesi için yeterli; kişisel veri riski taşıdığı için uzun tutulmaz
Metrik (Prometheus)15 gün hamUzun dönem eğilim için kayıt kuralları ile seyreltilmiş seri
İz (Tempo)7 günHacmi büyük, değeri kısa ömürlü
Profil (Pyroscope)7 günPerformans incelemesi penceresi
otp_challenges90 günKötüye kullanım incelemesi; sonrası gereksiz kişisel veri
sms_deliveries1 yılMaliyet mutabakatı ve sağlayıcı anlaşmazlıkları
token_ledgerKalıcıPara benzeri kayıt; silinemez
transactions · transaction_eventsUzunHukuki sonuç doğuran işlem; süre hukuk görüşüyle belirlenir
audit_eventsKalıcıHesap verebilirlik
daily_*_statsKalıcıKişisel veri içermez, hacmi ihmal edilebilir
Belgeler (nesne deposu)delete_after · ~15 dk yönelimiPolitika kodda değil veride. Kısa saklama seçilirse "İşlemlerim" işlemi gösterir ama belgeyi indirtemez — sınır kullanıcıya imza anında söylenmeli
Kimlik numarasıHesap ömrüŞifreli saklanır (aydınlatma metni kapsamında). Silme talebinde ilk anonimleştirilen alandır
Silme talebi geldiğinde

Kullanıcı verisinin silinmesi istendiğinde token hareketleri ve imza kayıtları silinmez — hukuki sonuç doğuran ve hesap verebilirlik taşıyan kayıtlardır. Bunun yerine kullanıcı kaydı yumuşak silinir, kişisel alanlar anonimleştirilir ve işlem kayıtları kimliksizleştirilmiş hâlde kalır. Bu yaklaşımın aydınlatma metninde açıkça anlatılması gerekir; şemanın buna hazır olması yetmez.

Uygulama Sırası

Gözlemlenebilirlik sonradan eklenen bir katman değildir; ilk dikey kesitle birlikte gelir. Aşağıdaki sıra, her adımın kendinden önceki adımı gerektirmesine göre kurulmuştur.

SıraAdımNeden bu sırada
1İlişkilendirme ara katmanı + log zenginleştiriciDiğer her şeyin bağlanacağı kimlik burada doğar. İlk kod satırıyla birlikte gelmezse sonradan geriye dönük eklemek her yeri dolaşmak demektir
2Serilog + seviye disiplini + maskelemeMaskeleme sonra eklenirse, o zamana kadar üretilen log'lar kişisel veri taşır
3correlation_id / trace_id kolonlarıŞema göçüyle birlikte; sonradan eklenen kolon geçmiş kayıtlar için boş kalır
4OTel: iz + hazır enstrümantasyon + sağlık uçlarıYürüyen iskeletin ilk gününde çalışır durumda olmalı
5Alan metrikleri (auth, token, transaction)İş kodu yazılırken eklenir; ayrı bir "metrik ekleme" turu israftır
6Denetim olaylarıYönetsel eylemler ortaya çıktıkça
7Günlük özet işi + ürün panosuÖlçülecek gerçek kullanıcı verisi oluştuktan sonra anlamlı
8Alarm kuralları + çalıştırma kitaplarıEşikler ancak gerçek veriyle kalibre edilebilir; erken konan eşik ya sürekli çalar ya hiç çalmaz
Gözlemlenebilirlik Prensibi

Metrik kaç tane ve ne kadar sürdü sorusunu, log ve iz hangisi ve neden sorusunu, veritabanı ne oldu ve kim sorumlu sorusunu cevaplar. Üçü birbirinin yerine geçmez.