---
title: 'Uyarı Tasarımı'
source: 'https://academia.sh/tr/kurslar/gozlemlenebilirlik/uyari-tasarimi'
course: 'Gözlemlenebilirlik ve Güvenilirlik'
language: tr
updated: '2026-08-17T18:06:52+00:00'
license: 'CC BY-SA 4.0'
---

# Uyarı Tasarımı

Uyarı kuralının kaynağının sonucu belirlemesi: on iki neden tabanlı kural ile dört belirti tabanlı kuralın aynı yedi günün üzerinden geçirilmesi, ürettikleri uyarı sayısının, aynı olayda kaç kuralın birden çaldığının ve hiç uyarı üretmeyen gerçek olayların sayılması.

Önceki dersin kalan bütçe tablosunda karar 12. günde verilmeliydi. O gün kimse tabloya bakmıyorsa
sayının bir değeri yok; birinin çağrılması gerekir. Çağrının hangi kuraldan doğacağı ise açık bir
soru. Kural bildirim kuyruğunun derinliğine mi bakar, ödünç servisinin bellek kullanımına mı, yoksa
doğrudan üyenin gördüğü hata oranına mı?

Bu ders eşik seçmez. Eşik ve pencere taraması Başarım Karşıt Kalıpları ve İzleme kursunda
yapıldı; buradaki soru başka: kuralın **kaynağı**. Aynı yedi günün üzerinden iki ayrı kural kümesi
geçirilir ve üç sayı karşılaştırılır — üretilen uyarı, aynı olayda birden çalan kural, hiç uyarı
üretmeyen olay.

## Kuralın Kaynağı

**Neden tabanlı kural** bir bileşenin iç ölçütünü okur: bellek kullanımı, disk doluluğu, önbellek
isabet oranı, bağlantı havuzu doluluğu, çöp toplama süresi. Bu ölçütler süreçlerin içinden gelir ve
sayıları servis sayısıyla birlikte artar.

**Belirti tabanlı kural** üyenin gördüğü şeyi okur: hata oranı, gecikme, trafik sapması, bildirim
teslim oranı. Bu ölçütler sistemin dışından bakınca da aynıdır ve sayıları servis sayısından
bağımsızdır.

Ayrım keyfi değil: bir uyarı bir kişiyi çağırır, ve çağrılan kişinin yapacak bir işi olmalıdır.
Ödünç servisinin belleğinin yüzde 91 olması tek başına bir iş tanımlamaz; ödünç isteklerinin yüzde
4'ünün başarısız dönmesi tanımlar. Bu, gösterge tablosu ile uyarının farklı sorular yanıtladığı
ayrımının kural yazımına düşen karşılığıdır.

## On Altı Kural ve Altı Olay

Aşağıdaki üreteç yedi günü dakikalık örneklerle yazar. On iki bileşen ölçütü ve dört kullanıcı
ölçütü aynı dakikalarda üretilir; her ölçütün tabanı, gürültüsü ve eşiği kendi satırındadır. Altı
olay bu ölçütlerin bir kısmını hedef değere doğru taşır.

```js
// uyari/olcut.mjs — 7 gunluk dakikalik olcut ornegi. On iki bilesen olcutu (neden) ile dort
// kullanici olcutu (belirti) ayni dakikalarda uretilir. Kural bicimi: [ad, taban, gurultu,
// yon, esik]; yon "ust" ise esigin ustu, "alt" ise alti kotudur.
export const DK = 7 * 1440, TOHUM = 20260731;
export const NEDEN = [
  ["katalog.onbellek_isabet", 92, 2, "alt", 70], ["katalog.islemci", 38, 6, "ust", 85],
  ["odunc.bellek", 58, 3, "ust", 90], ["odunc.cop_toplama_ms", 25, 6, "ust", 120],
  ["odunc.yeniden_baslatma", 0, 0, "ust", 0], ["uyelik.havuz_doluluk", 44, 6, "ust", 90],
  ["uyelik.bagimlilik_ms", 40, 8, "ust", 300], ["bildirim.kuyruk", 12, 8, "ust", 400],
  ["bildirim.etkin_isci", 8, 1, "alt", 3], ["ucret.disk", 70, 1, "ust", 95],
  ["ucret.dosya_tanitici", 900, 60, "ust", 1800], ["genel.yeniden_deneme", 3, 2, "ust", 30],
];
export const BELIRTI = [
  ["hata_orani", 0.2, 0.15, "ust", 1], ["p95_gecikme_ms", 180, 25, "ust", 400],
  ["trafik_sapmasi", 0, 6, "ust", 45], ["teslim_orani", 99.5, 0.3, "alt", 97],
];
// SD1 (varsayim): alti olay [gun, saat, sure dk, ad, [[olcut, olay icindeki deger], ...]]
export const OLAY = [
  [1, 10, 90, "onbellek cokusu", [["katalog.onbellek_isabet", 35], ["katalog.islemci", 91],
    ["p95_gecikme_ms", 520]]],
  [2, 8, 240, "bellek sizintisi", [["odunc.bellek", 96], ["odunc.cop_toplama_ms", 190],
    ["odunc.yeniden_baslatma", 2]]],
  [3, 0, 300, "disk dolmasi", [["ucret.disk", 98], ["ucret.dosya_tanitici", 2100]]],
  [4, 14, 120, "bagimlilik yavaslamasi", [["uyelik.bagimlilik_ms", 680],
    ["uyelik.havuz_doluluk", 96], ["genel.yeniden_deneme", 48], ["p95_gecikme_ms", 690],
    ["hata_orani", 1.8]]],
  [5, 9, 180, "sessiz teslim kaybi", [["teslim_orani", 3]]],
  [6, 11, 60, "yayin sonrasi hata artisi", [["hata_orani", 4.6]]],
];
export const pencere = (i) => [OLAY[i][0] * 1440 + OLAY[i][1] * 60, OLAY[i][2]];

// SD2 (varsayim): bilesen olcutu tek surecten okundugu icin 1500 dakikada bir 3-7 dakikalik
// sivri yapar; kullanici olcutu binlerce istekten ortalandigi icin 6000 dakikada bir.
export function seri() {
  let s = TOHUM;
  const rast = (n) => Math.floor(((s = (s * 1664525 + 1013904223) >>> 0) / 2 ** 32) * n);
  const cikti = {};
  for (const [ad, taban, gur, yon, esik] of [...NEDEN, ...BELIRTI]) {
    const bilesen = NEDEN.some((k) => k[0] === ad);
    const v = new Float64Array(DK);
    let sivri = 0;
    for (let t = 0; t < DK; t += 1) {
      let d = taban + (gur ? (rast(2001) - 1000) / 1000 * gur : 0);
      if (sivri > 0) { sivri -= 1; d = yon === "ust" ? esik * 1.15 + 1 : esik * 0.85; }
      else if (rast(bilesen ? 1500 : 6000) === 0) sivri = 3 + rast(5);
      for (let i = 0; i < OLAY.length; i += 1) {
        const [bas, sr] = pencere(i), hedef = OLAY[i][4].find((h) => h[0] === ad);
        if (!hedef || t < bas || t >= bas + sr) continue;
        const ilerleme = Math.min(1, (t - bas + 1) / Math.max(1, sr * 0.2));
        d = taban + (hedef[1] - taban) * ilerleme;
      }
      v[t] = d;
    }
    cikti[ad] = v;
  }
  return cikti;
}

if (import.meta.filename === process.argv[1]) {
  const S = seri();
  console.log(`tohum ${TOHUM}, ${DK} dakika, ${NEDEN.length} bilesen olcutu, ` +
    `${BELIRTI.length} kullanici olcutu, ${OLAY.length} olay`);
  const [b, sr] = pencere(0);
  console.log(`ornek — onbellek cokusu penceresi (${b}. dakika, ${sr} dk): ` +
    `onbellek isabet ${S["katalog.onbellek_isabet"][b + 30].toFixed(1)}, ` +
    `islemci ${S["katalog.islemci"][b + 30].toFixed(1)}, ` +
    `p95 ${S["p95_gecikme_ms"][b + 30].toFixed(0)} ms, ` +
    `hata orani ${S["hata_orani"][b + 30].toFixed(2)}`);
}
```

```
tohum 20260731, 10080 dakika, 12 bilesen olcutu, 4 kullanici olcutu, 6 olay
ornek — onbellek cokusu penceresi (2040. dakika, 90 dk): onbellek isabet 35.0, islemci 91.0, p95 520 ms, hata orani 0.07
```

## İki Kümeyi Aynı Haftadan Geçirmek

Bir kural, koşulu üst üste üç dakika sağlandığında bir uyarı üretir ve koşul düşene kadar
tekrarlamaz. İki küme aynı ölçütlerin üzerinde bağımsız çalıştırılır.

```js
// uyari/kural.mjs — ayni yedi gunun uzerinden iki kural kumesi gecirilir: on iki neden tabanli
// kural ve dort belirti tabanli kural. Bir kural, kosulu ust uste 3 dakika saglandiginda bir
// uyari uretir ve kosul dusene kadar yeniden uretmez.
import { seri, NEDEN, BELIRTI, OLAY, DK, pencere } from "./olcut.mjs";
const S = seri();
const asar = (k, v) => (k[3] === "ust" ? v > k[4] : v < k[4]);

function uyarilar(kume) {
  const m = new Map();
  for (const k of kume) {
    const v = S[k[0]], dk = [];
    let ard = 0, etkin = false;
    for (let t = 0; t < DK; t += 1) {
      if (asar(k, v[t])) { ard += 1; if (ard >= 3 && !etkin) { etkin = true; dk.push(t - 2); } }
      else { ard = 0; etkin = false; }
    }
    m.set(k[0], dk);
  }
  return m;
}
const KUME = [["neden tabanli", NEDEN, uyarilar(NEDEN)], ["belirti tabanli", BELIRTI, uyarilar(BELIRTI)]];

console.log(`${"olay".padEnd(26)}${"sure".padStart(7)}` +
  `${KUME.map(([ad]) => `${ad} kural`.padStart(24) + "ilk uyari".padStart(11)).join("")}`);
const yakalanan = KUME.map(() => new Set());
OLAY.forEach(([, , sr, ad], i) => {
  const [bas] = pencere(i);
  const s = KUME.map(([, , m], j) => {
    const c = [...m.values()].map((dk) => dk.filter((t) => t >= bas && t < bas + sr));
    const kural = c.filter((x) => x.length > 0).length;
    const ilk = Math.min(...c.flat().map((t) => t - bas), Infinity);
    if (kural > 0) yakalanan[j].add(i);
    return [kural, ilk];
  });
  console.log(`${ad.padEnd(26)}${(sr + " dk").padStart(7)}` +
    `${s.map(([kural, ilk]) => String(kural).padStart(24) +
      (ilk === Infinity ? "-" : `${ilk}. dk`).padStart(11)).join("")}`);
});

const ici = (t) => OLAY.some((o, i) => t >= pencere(i)[0] && t < pencere(i)[0] + o[2]);
console.log(`\n${"kume".padEnd(16)}${"kural".padStart(7)}${"uyari".padStart(7)}` +
  `${"olay disi".padStart(11)}${"yakalanan".padStart(11)}${"olay basina".padStart(13)}  kacan olay`);
KUME.forEach(([ad, kume, m], j) => {
  const hepsi = [...m.values()].flat();
  const disi = hepsi.filter((t) => !ici(t)).length;
  const ici2 = hepsi.length - disi;
  console.log(`${ad.padEnd(16)}${String(kume.length).padStart(7)}${String(hepsi.length).padStart(7)}` +
    `${String(disi).padStart(11)}${`${yakalanan[j].size}/${OLAY.length}`.padStart(11)}` +
    `${(ici2 / yakalanan[j].size).toFixed(1).padStart(13)}  ` +
    `${OLAY.filter((_, i) => !yakalanan[j].has(i)).map((o) => o[3]).join(", ") || "-"}`);
});

const birlikte = new Set([...yakalanan[0], ...yakalanan[1]]);
console.log(`\nikisi birlikte: ${NEDEN.length + BELIRTI.length} kural, ` +
  `${birlikte.size}/${OLAY.length} olay`);
const cok = OLAY.map((o, i) => {
  const [bas] = pencere(i);
  return [o[3], [...KUME[0][2].values()].filter((dk) =>
    dk.some((t) => t >= bas && t < bas + o[2])).length];
}).sort((a, b) => b[1] - a[1])[0];
console.log(`en gurultulu olay: ${cok[0]} — tek olayda ${cok[1]} neden tabanli uyari birden`);
const enCok = [...KUME[0][2]].sort((a, b) => b[1].length - a[1].length)[0];
console.log(`en cok uyaran tek kural: ${enCok[0]} — 7 gunde ${enCok[1].length} uyari`);
```

```
olay                         sure     neden tabanli kural  ilk uyari   belirti tabanli kural  ilk uyari
onbellek cokusu             90 dk                       2      6. dk                       1     11. dk
bellek sizintisi           240 dk                       5      0. dk                       0          -
disk dolmasi               300 dk                       3     45. dk                       0          -
bagimlilik yavaslamasi     120 dk                       3      9. dk                       2     10. dk
sessiz teslim kaybi        180 dk                       0          -                       1      0. dk
yayin sonrasi hata artisi   60 dk                       0          -                       1      2. dk

kume              kural  uyari  olay disi  yakalanan  olay basina  kacan olay
neden tabanli        12     81         67        4/6          3.5  sessiz teslim kaybi, yayin sonrasi hata artisi
belirti tabanli       4      9          4        4/6          1.3  bellek sizintisi, disk dolmasi

ikisi birlikte: 16 kural, 6/6 olay
en gurultulu olay: bellek sizintisi — tek olayda 5 neden tabanli uyari birden
en cok uyaran tek kural: bildirim.kuyruk — 7 gunde 10 uyari
```

## Üç Sayı

**Üretilen uyarı.** On iki neden tabanlı kural yedi günde 81 uyarı üretti, dört belirti tabanlı
kural 9 uyarı. Kural sayısı üç kat, uyarı sayısı dokuz kat. Bunun 67'si hiçbir olaya denk gelmiyor:
neden tabanlı uyarıların yüzde 83'ü boşa çıkıyor. Belirti tabanlı kümede aynı oran 9'da 4.
Farkın kaynağı SD2'de yazılı: bileşen ölçütü tek bir süreçten okunur ve kısa sıvrılar yapar,
kullanıcı ölçütü binlerce isteğin ortalamasıdır ve düzgündür. Tek bir kural — bildirim kuyruğu —
yedi günde 10 uyarı üretti.

**Aynı olayda birden çalan kural.** Neden tabanlı kümede olay başına 3,5 uyarı düşüyor, belirti
tabanlı kümede 1,3. Bellek sızıntısı sırasında beş kural birden çaldı: üçü olayın kendisiydi
(bellek, çöp toplama, yeniden başlatma), ikisi o dört saat içinde denk gelen ilgisiz sıvrılardı.
Çağrılan kişi beş uyarıyı açtığında hangisinin kök neden olduğunu ayırt edemez; uyarıların sayısı
bilgi taşımaz, çünkü hepsi aynı olaydan doğmuştur.

**Hiç uyarı üretmeyen olay.** İki küme de altıda dört olay yakaladı, ama **farklı ikisini kaçırdı.**
Neden tabanlı kurallar sessiz teslim kaybını ve yayın sonrası hata artışını göremedi: ikisinde de
bileşen ölçütleri normaldi, bozuk olan işin kendisiydi. Belirti tabanlı kurallar bellek sızıntısını
ve disk dolmasını göremedi: ikisinde de üye hiçbir şey fark etmemişti, çünkü kaynak henüz
tükenmemişti.

## Uyandıran Kural, Teşhis Eden Ölçüt

Zamanlama sütunu iki kümenin rollerini ayırıyor. Önbellek çöküşünde neden tabanlı kural 6.
dakikada, belirti tabanlı kural 11. dakikada çaldı; bağımlılık yavaşlamasında fark bir dakikaya
iniyor. Neden tabanlı ölçütler biraz daha erken, ama bu beş dakikanın bedeli 67 boş uyarıdır.

Buradan çıkan düzen şudur: **on iki bileşen ölçütü silinmez, uyarı kuralı olmaktan çıkarılır.**
Uyandıran kurallar belirtiden yazılır — dört kural, üyenin gördüğü dört ölçüt. Bileşen ölçütleri
gösterge tablosunda kalır ve çağrılan kişi uyarıyı aldıktan sonra oraya bakar. Uyarı "bir şey
yapılmalı" der, gösterge tablosu "nereye bakılmalı" der. İki kümenin birleşimi altı olayın altısını
kapsıyor, ama bu 16 uyarı kuralıyla değil, 4 uyarı kuralı ve 12 gösterge tablosu paneliyle olur.

Belirti tabanlı kümenin kaçırdığı iki olay bu düzenin gerçek boşluğudur ve eşik değiştirerek
kapanmaz. Disk yüzde 98 doluyken üye hâlâ bir şey görmez; belirti ancak disk dolduğunda ortaya
çıkar ve o an geri dönüşü pahalıdır. Tükenen kaynaklar için kural eşik üzerine değil **tükenme
süresi** üzerine yazılır: "bu doluş hızıyla disk dört saat içinde dolar" cümlesi bir belirtidir,
çünkü bir kişinin yapacağı işi tanımlar. Aynı cümle bellek sızıntısı için de yazılabilir; ikisi de
neden tabanlı bir ölçütten okunur ama belirti tabanlı bir soruya yanıt verir.

## Özet

- Uyarı kuralının kaynağı iki türdür: bileşenin iç ölçütü (neden) ya da üyenin gördüğü ölçüt
  (belirti); ayrımın ölçütü, çağrılan kişinin yapacak bir işi olup olmadığıdır.
- On iki neden tabanlı kural yedi günde 81 uyarı üretti ve 67'si hiçbir olaya denk gelmedi; dört
  belirti tabanlı kural 9 uyarı üretti ve 4'ü boşa çıktı.
- Neden tabanlı kümede olay başına 3,5 uyarı düşüyor: bellek sızıntısında beş kural birden çaldı,
  üçü olayın kendisi, ikisi ilgisiz sıvrıydı.
- İki küme de altıda dört olay yakaladı ama farklı ikisini kaçırdı: neden tabanlı kurallar işin
  kendisinin bozulduğu olayları, belirti tabanlı kurallar üyeye henüz ulaşmamış tükenmeleri.
- Neden tabanlı kurallar önbellek çöküşünde beş dakika erken çaldı; bu beş dakikanın bedeli 67 boş
  uyarıdır.
- Çözüm bileşen ölçütlerini silmek değil, uyarı kuralı olmaktan çıkarmaktır: dört uyarı kuralı ve
  on iki gösterge tablosu paneli altı olayın altısını kapsar.

## Sonraki Adım

Bu derste kurulan her kural bir insanı çağırıyor ve insan dakikalar içinde yanıt veriyor. Bazı
kararlar ise insana hiç sorulmaz. Ödünç sisteminin süreçlerinden birinin yaşayıp yaşamadığına ve
trafik alıp almayacağına makine karar verir, üstelik saniyeler içinde ve bir günde binlerce kez.
Bu karar iki ayrı soruya bakar — süreç ölmüş mü, ve süreç şu an iş alabilir mi — ve iki soru tek
bir uca bağlandığında verilen yanıt yalnız yanlış olmaz, kendini besleyen bir döngü kurar. Sonraki
ders iki ucu kodda ayırır ve ayırmamanın bedelini yeniden başlatma sayısıyla düşen istek sayısıyla
ölçer.
