---
title: 'Enstrümantasyon Standartları'
source: 'https://academia.sh/tr/kurslar/devops-gozlemlenebilirlik/enstrumantasyon-standartlari'
course: 'Gözlemlenebilirlik ve İşletim'
language: tr
updated: '2026-08-17T18:09:06+00:00'
license: 'CC BY-SA 4.0'
---

# Enstrümantasyon Standartları

Beş servisin kendi adlandırmasıyla yazdığı telemetrinin servisler arası birleştirilememesi: on sorunun yerel şemalar ve ortak sözleşme üzerinde ayrı ayrı yanıtlanması, sessizce yanlış yanıtların sayılması ve sözleşmenin alan, servis değişikliği ve uyumsuz servis olarak bedelinin çıkarılması.

Önceki derste beş servisin adım kayıtları tek bir ağaçta birleşti. Birleşmenin nedeni kodda
yazılıydı: her servis aynı alan adlarını, aynı birimi ve aynı iz kimliğini kullanıyordu. Bu
varsayım gerçek bir ağda karşılıksızdır. Beş servisi beş ekip yazar; her ekip kendi kaydını kendi
alışkanlığıyla adlandırır, süreyi kendi birimine göre yazar, hatayı kendi bildiği biçimde işaretler.
Kayıtlar tek tek doğrudur ve her ekip kendi gösterge tablosunda doğru sayıları görür. Kırılan şey,
**servisler arası** sorudur.

Bu ders bölgesel ölçüm ağının (kurgu) beş servisini kendi yerel şemalarıyla yazdırır, aynı on soruyu
önce bu şemalar üzerinde sorar, sonra ortak bir telemetri sözleşmesi tanımlayıp yeniden sorar.
Sözleşmenin ne olduğu ortak yapısıyla anlatılır; şema ders içinde tanımlanır.

## Aynı İsteğin Beş Kaydı

```js
// soz/kayit.mjs — bes servisin ayni istegi kendi yerel semasiyla yazmasinin MODELI. Once dogru
// degerler uretilir (gercek), sonra her servis kendi alan adlari ve birimiyle bir kayit yazar.
// IG7: yerel semalar kurgudur. IG8: okuma ile fatura ayni "sure" adini farkli birimle yazar.
// IG9: fatura zincirden gelen kimligi degil kendi istek numarasini tasir. IG10: isemri disaridan
// alinmis bir bilesendir, kaydi degistirilemez.
export const TOHUM = 20260803, ISTEK = 6000;
export const SERVIS = ["gecit", "okuma", "dogrulama", "fatura", "isemri"];
export const TABAN = { gecit: 6, okuma: 21, dogrulama: 28, fatura: 47, isemri: 19 };
export const AKIS = "fatura_sorgu";

export function gercek() {
  let s = TOHUM;
  const r = () => ((s = (s * 1664525 + 1013904223) >>> 0) / 2 ** 32);
  const cikti = [];
  for (let i = 0; i < ISTEK; i += 1) {
    const t0 = Date.UTC(2026, 7, 3) + Math.floor(r() * 3600000), atlandi = r() < 0.11, adimlar = [];
    for (const ad of SERVIS) {
      if (ad === "dogrulama" && atlandi) continue;
      adimlar.push({ servis: ad, sure_ms: Math.max(1, Math.round(TABAN[ad] * (0.6 + r() * 0.9))),
        durum: r() < ({ fatura: 0.014, isemri: 0.0005 }[ad] ?? 0.004) ? "hata" : "tamam" });
    }
    cikti.push({ iz: `iz-${(i + 1).toString(36).padStart(4, "0")}`, t0, atlandi, adimlar });
  }
  return cikti;
}

// Yerel semalar: ayni bilgi bes ayri adlandirma ve uc ayri birimle yazilir.
export const YEREL = {
  gecit: (z, a) => ({ zaman: new Date(z.t0).toISOString(), servis: "gecit", islem: AKIS,
    sure_ms: a.sure_ms, durum: a.durum, iz: z.iz }),
  okuma: (z, a) => ({ t: Math.floor(z.t0 / 1000), birim: "okuma", eylem: "sorgu",
    sure: a.sure_ms * 1000, sonuc: a.durum === "hata" ? 1 : 0, izlem: z.iz }),
  dogrulama: (z, a) => ({ ts: z.t0, bilesen: "dogrulama", islem: "dogrula",
    gecikme: a.sure_ms / 1000, hata: a.durum === "hata", iz_kimlik: z.iz }),
  fatura: (z, a) => ({ zaman: new Date(z.t0).toISOString(), uygulama: "fatura", uc: "hesapla",
    sure: a.sure_ms, durum_kodu: a.durum === "hata" ? 500 : 200, istek_no: `f-${z.iz.slice(3)}` }),
  isemri: (z, a) => ({ zaman: z.t0, servis: "isemri", yordam: "emir_ac",
    islem_suresi: a.sure_ms, hata_kodu: a.durum === "hata" ? 7 : 0 }),
};
export const yerelAkis = (G) => G.flatMap((z) => z.adimlar.map((a) => YEREL[a.servis](z, a)));

if (import.meta.filename === process.argv[1]) {
  const G = gercek(), z = G[0];
  console.log(`tohum ${TOHUM}, ${ISTEK} istek, ${SERVIS.length} servis, ` +
    `${G.reduce((x, y) => x + y.adimlar.length, 0)} kayit`);
  console.log(`\nbir istegin (${z.iz}) bes serviste yazdigi kayit:`);
  for (const a of z.adimlar) console.log(`  ${JSON.stringify(YEREL[a.servis](z, a))}`);
  const alan = new Map();
  for (const a of z.adimlar) for (const k of Object.keys(YEREL[a.servis](z, a)))
    alan.set(k, (alan.get(k) || 0) + 1);
  console.log(`\ntoplam ${alan.size} ayri alan adi, bes serviste ortak olan: ` +
    `${[...alan].filter(([, n]) => n === 5).map(([k]) => k).join(", ") || "yok"}`);
}
```

```
tohum 20260803, 6000 istek, 5 servis, 29362 kayit

bir istegin (iz-0001) bes serviste yazdigi kayit:
  {"zaman":"2026-08-03T00:21:34.006Z","servis":"gecit","islem":"fatura_sorgu","sure_ms":5,"durum":"tamam","iz":"iz-0001"}
  {"t":1785716494,"birim":"okuma","eylem":"sorgu","sure":30000,"sonuc":0,"izlem":"iz-0001"}
  {"ts":1785716494006,"bilesen":"dogrulama","islem":"dogrula","gecikme":0.035,"hata":false,"iz_kimlik":"iz-0001"}
  {"zaman":"2026-08-03T00:21:34.006Z","uygulama":"fatura","uc":"hesapla","sure":54,"durum_kodu":200,"istek_no":"f-0001"}
  {"zaman":1785716494006,"servis":"isemri","yordam":"emir_ac","islem_suresi":25,"hata_kodu":0}

toplam 24 ayri alan adi, bes serviste ortak olan: yok
```

Tek bir isteğin beş kaydında üç ayrılık birden var. **Alan adı:** aynı kavram beş serviste `sure_ms`,
`sure`, `gecikme`, `islem_suresi` adlarıyla geçiyor; toplam 24 ayrı alan adı sayılıyor ve beş
servisin hepsinde bulunan tek bir ortak alan yok. **Birim:** süre üç ayrı birimde yazılmış —
milisaniye, mikrosaniye, saniye — ve alan adı birimi söylemiyor. **Değer uzayı:** hata beş serviste
`"hata"` metni, `1` sayısı, `true` mantıksal değeri, `500` kodu ve `7` kodu olarak işaretlenmiş.
Dördüncü ayrılık kimlikte: fatura zincirden gelen iz kimliğini değil kendi istek numarasını
taşıyor, iş emri hiçbir kimlik taşımıyor.

## Sözleşmenin Ortak Yapısı

Telemetri sözleşmesi bir araç değil, bir **anlaşmadır**: hangi alanın hangi adla, hangi birimde,
hangi değer uzayında yazılacağını ve isteğin kimliğinin çağrıdan çağrıya nasıl taşınacağını
sabitler. Bu derste kullanılan altı alanlık şema şudur:

| Alan | Anlam | Birim ve değer uzayı |
|---|---|---|
| `iz` | isteğin çağrı zinciri boyunca taşınan kimliği | metin, beş serviste aynı |
| `zaman_ms` | adımın başlangıcı | epoch milisaniye, tam sayı |
| `servis` | kaydı yazan servis | katalogdaki ad |
| `akis` | adımın ait olduğu iş akışı | ortak akış adı |
| `sure_ms` | adımın süresi | milisaniye |
| `durum` | adımın sonucu | `tamam` ya da `hata` |

Sözleşmenin karşısındaki çözüm, sorgu tarafında elle yazılmış bir **eşleme tablosudur**: "şu alan
adını görürsen süre say, şu değeri görürsen hata say". Aşağıdaki karşılaştırma iki yolu aynı soru
kümesiyle ölçer.

## On Soru, İki Aşama

```js
// soz/sorgu.mjs — on soru iki asamada sorulur: once yerel semalar uzerinde elle yazilmis esleme
// tablosuyla (IG11), sonra ortak sozlesmeye gecmis kayitlar uzerinde. Her yanit gercek degerle
// karsilastirilir: sapma yuzde 5'i asarsa "yanlis", okunabilir alan yoksa "yok".
import { gercek, YEREL, SERVIS, AKIS, ISTEK } from "./kayit.mjs";
const G = gercek();
// IG11: esleme tablosu ilk buldugu alani kullanir, deger uzayini bilmez.
const ESLEME = { iz: ["iz", "izlem", "iz_kimlik", "istek_no"], zaman_ms: ["zaman_ms", "zaman", "ts", "t"],
  servis: ["servis", "birim", "bilesen", "uygulama"], akis: ["akis", "islem", "eylem", "yordam", "uc"],
  sure_ms: ["sure_ms", "sure", "gecikme", "islem_suresi"],
  durum: ["durum", "hata", "sonuc", "durum_kodu", "hata_kodu"] };
const oku = (k, alan) => { for (const a of ESLEME[alan]) if (a in k) return k[a]; return null; };
const sayi = (v) => (typeof v === "number" && Number.isFinite(v) ? v : null);
const hataMi = (v) => v === "hata" || v === true;      // eslemeyi yazanin bildigi iki bicim
// IG12: sozlesme gecisi kaydin uretildigi yerde yapilir; isemri (IG10) yerel kaydinda kalir.
const SOZLESME = ["iz", "zaman_ms", "servis", "akis", "sure_ms", "durum"], UYUMSUZ = ["isemri"];
const sozlesmeli = (z, a) => (UYUMSUZ.includes(a.servis) ? YEREL[a.servis](z, a)
  : { iz: z.iz, zaman_ms: z.t0, servis: a.servis, akis: AKIS, sure_ms: a.sure_ms, durum: a.durum });
const kayitlar = (f) => G.flatMap((z) => z.adimlar.map((a) => f(z, a)));
const [YEREL_K, SOZ_K] = [kayitlar((z, a) => YEREL[a.servis](z, a)), kayitlar(sozlesmeli)];

const ort = (x) => (x.length ? x.reduce((a, b) => a + b, 0) / x.length : null);
const p95 = (x) => (x.length ? x.slice().sort((a, b) => a - b)[Math.floor(x.length * 0.95)] : null);
const grup = (K, alan) => { const m = new Map();
  for (const k of K) { const g = oku(k, alan); if (g !== null) m.set(g, [...(m.get(g) ?? []), k]); }
  return m; };
const sure = (k) => sayi(oku(k, "sure_ms")) ?? 0;
const izToplam = (K) => [...grup(K, "iz").values()].map((v) => v.reduce((x, k) => x + sure(k), 0));
const servisSure = (K, s) => (grup(K, "servis").get(s) ?? []).map((k) => sayi(oku(k, "sure_ms")))
  .filter((v) => v !== null);
const enYavas = (K) => SERVIS.map((s) => [s, p95(servisSure(K, s)) ?? -1]).sort((a, b) => b[1] - a[1])[0];
const gS = (s) => G.flatMap((z) => z.adimlar.filter((a) => a.servis === s).map((a) => a.sure_ms));
const gAdim = G.flatMap((z) => z.adimlar), uctanUca = G.map((z) => z.adimlar.reduce((x, a) => x + a.sure_ms, 0));

const SORU = [
  ["en yavas servis", "fatura", (K) => enYavas(K)[0]],
  ["en yavas servisin p95 (ms)", p95(gS("fatura")), (K) => enYavas(K)[1]],
  ["en cok hata ureten servis", "fatura", (K) => SERVIS.map((s) => [s,
    (grup(K, "servis").get(s) ?? []).filter((k) => hataMi(oku(k, "durum"))).length])
    .sort((a, b) => b[1] - a[1])[0][0]],
  ["hata orani (%)", gAdim.filter((a) => a.durum === "hata").length / gAdim.length * 100,
    (K) => K.filter((k) => hataMi(oku(k, "durum"))).length / K.length * 100],
  ["saatlik istek sayisi", ISTEK, (K) => ((g) => (g.length ? g.length : null))(
    (grup(K, "servis").get("gecit") ?? []).filter((k) => sayi(+oku(k, "zaman_ms")) !== null))],
  ["uctan uca ortalama sure (ms)", ort(uctanUca), (K) => ort(izToplam(K))],
  ["istek basina birlesen kayit", ort(G.map((z) => z.adimlar.length)),
    (K) => ort([...grup(K, "iz").values()].map((v) => v.length))],
  ["dogrulamasi atlanan istek", G.filter((z) => z.atlandi).length,
    (K) => [...grup(K, "iz").values()].filter((v) => v.every((k) => oku(k, "servis") !== "dogrulama")).length],
  [`${AKIS} akisinin toplam suresi (ms)`, uctanUca.reduce((a, b) => a + b, 0),
    (K) => (grup(K, "akis").get(AKIS) ?? []).reduce((x, k) => x + sure(k), 0) || null],
  ["isemri adiminin uctan uca payi (%)", ort(gS("isemri")) / ort(uctanUca) * 100,
    (K) => { const m = grup(K, "iz"), i = [...m.values()].flat()
      .filter((k) => oku(k, "servis") === "isemri" && oku(k, "iz") !== null);
      return i.length ? ort(i.map(sure)) / ort(izToplam(K)) * 100 : null; }],
];
const bicim = (v) => (v === null ? "-" : typeof v === "number" ? v.toFixed(v < 100 ? 2 : 0) : String(v));
const dogruMu = (g, v) => (v === null ? "yok" : typeof g === "number"
  ? (Math.abs(v - g) / g <= 0.05 ? "dogru" : "yanlis") : (v === g ? "dogru" : "yanlis"));

console.log(`${"soru".padEnd(40)}${"gercek".padStart(9)}${"yerel sema".padStart(12)}` +
  `${"durum".padStart(8)}${"sozlesme".padStart(11)}${"durum".padStart(8)}`);
const say = { yerel: {}, soz: {} };
for (const [ad, g, f] of SORU) {
  const [y, s] = [f(YEREL_K), f(SOZ_K)], [dy, ds] = [dogruMu(g, y), dogruMu(g, s)];
  say.yerel[dy] = (say.yerel[dy] || 0) + 1; say.soz[ds] = (say.soz[ds] || 0) + 1;
  console.log(`${ad.padEnd(40)}${bicim(g).padStart(9)}${bicim(y).padStart(12)}${dy.padStart(8)}` +
    `${bicim(s).padStart(11)}${ds.padStart(8)}`);
}
const d = (o) => `dogru ${o.dogru || 0}, yanlis ${o.yanlis || 0}, yok ${o.yok || 0}`;
console.log(`\nyerel sema: ${d(say.yerel)}\nsozlesme  : ${d(say.soz)}`);
const degisim = SERVIS.map((s) => [s, UYUMSUZ.includes(s) ? 0
  : SOZLESME.filter((a) => !(a in YEREL[s](G[0], G[0].adimlar[0]))).length]);
console.log(`sozlesme ${SOZLESME.length} alan; degisen alan: ${degisim.map(([s, n]) => `${s} ${n}`).join(", ")}` +
  `; toplam ${degisim.reduce((x, [, n]) => x + n, 0)} alan degisikligi, ` +
  `uyumsuz kalan ${UYUMSUZ.length}/${SERVIS.length} servis`);
```

```
soru                                       gercek  yerel sema   durum   sozlesme   durum
en yavas servis                            fatura       okuma  yanlis     fatura   dogru
en yavas servisin p95 (ms)                  68.00       31000  yanlis      68.00   dogru
en cok hata ureten servis                  fatura   dogrulama  yanlis     fatura   dogru
hata orani (%)                               0.56        0.18  yanlis       0.54   dogru
saatlik istek sayisi                         6000           -     yok       6000   dogru
uctan uca ortalama sure (ms)                  124       11141  yanlis        104  yanlis
istek basina birlesen kayit                  4.89        1.95  yanlis       3.89  yanlis
dogrulamasi atlanan istek                     638        6638  yanlis        638   dogru
fatura_sorgu akisinin toplam suresi (ms)   744212       37943  yanlis     625249  yanlis
isemri adiminin uctan uca payi (%)          15.99           -     yok          -     yok

yerel sema: dogru 0, yanlis 8, yok 2
sozlesme  : dogru 6, yanlis 3, yok 1
sozlesme 6 alan; degisen alan: gecit 2, okuma 6, dogrulama 6, fatura 6, isemri 0; toplam 20 alan degisikligi, uyumsuz kalan 1/5 servis
```

Yerel şemalar üzerinde on sorudan **hiçbiri** doğru yanıtlanmadı. Asıl bulgu dağılımdadır: yalnız
ikisi yanıtsız kaldı, sekizi **sessizce yanlış** yanıtlandı. Eşleme tablosu okuma servisinin
mikrosaniye değerini milisaniye sanıp p95'i 68 yerine 31.000 buldu ve en yavaş servis olarak
faturayı değil okumayı gösterdi. Hata oranı yüzde 0,56 yerine 0,18 çıktı, çünkü tablo yalnız iki
biçimi tanıyor. En çok hata üreten servis sorusuna fatura yerine doğrulama yanıtı verildi. Uçtan
uca süre 124 ms yerine 11.141 ms göründü. Bu yanıtların hiçbirinin yanında bir uyarı yok; sorgu
çalışıyor, sayı üretiyor, gösterge tablosuna çiziliyor.

Yanıtsız kalan iki soru bu yüzden **daha ucuzdur**: saatlik istek sayısı hiç hesaplanamadı, çünkü
geçit zamanı metin biçiminde yazıyor ve sayıya çevrilemedi. Yanıt yokluğu görülür, yanlış yanıt
görülmez.

Sözleşme uygulandığında altı soru doğru yanıtlandı. Kalan dördün tamamı tek bir kaynağa çıkıyor:
sözleşmeye geçirilemeyen servis. Uçtan uca süre 124 yerine 104 ms, istek başına birleşen kayıt 4,89
yerine 3,89, akış toplamı 744.212 yerine 625.249 ms — üçü de eksik bir adımın açığı. İş emri
adımının uçtan uca paydaki payı ise hâlâ yanıtsız: o servisin kaydında iz kimliği yok, dolayısıyla
adım hiçbir isteğe bağlanamıyor.

## Sözleşmenin Bedeli

Sözleşme altı alandan oluşuyor. Dört servis bu alanlara geçti ve bu geçiş toplam 20 alan
değişikliği demek: geçit iki alan ekledi, öteki üç servis altışar alanını yeniden adlandırdı ya da
birimini çevirdi. Beşinci servis dışarıdan alınmış bir bileşen olduğu için değiştirilemedi ve
uyumsuz kaldı.

Bu üç sayının oranı işin kararını taşıyor. Alan başına kazanç yüksek: 20 alan değişikliği karşılığı
sıfır doğru yanıttan altı doğru yanıta çıkıldı, yani bir doğru yanıt ortalama üç buçuk alan
değişikliğine mal oldu. Buna karşılık kazanç **doğrusal değil**: servislerin yüzde 80'i sözleşmeye
uydu ama soruların yalnız yüzde 60'ı yanıtlandı, çünkü servisler arası soru en zayıf halkaya bağlı.
Bir istek zincirinde tek bir uyumsuz adım, o adımı içeren her soruyu bozuyor.

Yanıtsız kalan sorunun bedeli burada iki katmanlıdır. Birinci katman doğrudan: iş emri adımının payı
bilinmediği için o servisin yavaşlaması uçtan uca ölçümde görünmez. İkinci katman daha pahalı:
sözleşme öncesi sekiz soru **yanlış** yanıtlanıyordu ve bu yanıtlarla karar verilmişti — en yavaş
servis olarak okuma gösterildiği sürece iyileştirme çabası yanlış servise harcanır.

## Özet

- Beş servis kendi adlandırmasıyla yazdığında tek bir istek 24 ayrı alan adına dağılıyor ve beş
  servisin hepsinde bulunan ortak alan kalmıyor.
- Yerel şemalar üzerinde on sorudan sıfırı doğru yanıtlandı; ikisi yanıtsız kaldı, sekizi sessizce
  yanlış yanıtlandı — yanlış yanıt yanıtsızlıktan pahalıdır, çünkü görülmez.
- Ayrılık üç katmanda birden çıkıyor: alan adı, birim (ms, µs, sn) ve değer uzayı (metin, sayı,
  mantıksal değer, kod); kimlik ayrılığı bunlara ek olarak birleştirmeyi tümden engelliyor.
- Altı alanlık sözleşme 20 alan değişikliği ve dört servis değişikliği karşılığında doğru yanıtı
  altıya çıkardı.
- Servislerin yüzde 80'i uydu ama soruların yüzde 60'ı yanıtlandı: tek uyumsuz servis kendi
  adımını içeren dört soruyu birden bozuyor.

## Sonraki Adım

Sözleşme kurulduktan sonra sorular yanıtlanabilir hâle geldi, ama yanıtın nerede okunacağı hâlâ
açık. Bir kişi olay sırasında sorgu yazmaz; önüne çıkan panellere bakar. Panellerin hangi soruya
yanıt verdiği ise çoğu zaman hiç sorulmamıştır — tablolar zamanla eklenen, kimsenin silmediği
panellerle dolar. Sonraki ders bir gösterge tablosunu soru kümesine karşı denetler: kaç panel bir
soruya yanıt veriyor, kaç panel hiçbir soruya yanıt vermiyor, kaç soru panelsiz kalıyor ve bir
soruya yanıt bulmak kaç panel gezmeyi gerektiriyor.
