---
title: 'Çökme ve Kullanım İzleme'
source: 'https://academia.sh/tr/kurslar/capraz-platform-uretim/cokme-ve-kullanim-izleme'
course: 'Çapraz Platform Üretim Pratiği'
language: tr
updated: '2026-10-21T05:02:51+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'İki platformdan gelen çökme ve kullanım verisinin tek bir olay biçiminde nasıl toplandığını açıklar'
    - 'Çökme raporunun yerelde saklanıp bağlantı dönünce gönderilmesini ölçer'
    - 'Kullanıcı izninin analitik olayını yedeksiz kapattığını gösterir'
    - 'Kurs boyunca ölçülen on dört dersin işlerlik dağılımını okur'
---

# Çökme ve Kullanım İzleme

Çökme ve kullanım izleme, yayımlanmış bir yapının sahada ne yaptığını iki platformdan birleşik olarak toplamayı anlatır. Ders, çevrimdışı oturumda oluşan çökme raporunun ertelenen kaldığını ve kullanıcı izninin olayları kapattığını ölçer.

Önceki ders ilk indirmede gelmeyen bir paketi ele aldı. Ekip o durumu önceden bilebiliyordu: hangi paket nerede yok, kurulumdan okunur. Yayımlanmış bir yapıda ise bilinmeyen çoktur. Hangi aygıtta çöktü, hangi ekranı kim kullanıyor, hangi özellik sessizce çalışmıyor? Bu ders, sahadan gelen bu bilgiyi toplamayı ve toplamanın kendi koşulunu ölçer.

Kursun sorusu aynı kalır: bu koşulda bu özellik ne kadar çalışıyor? Bu kez soru izlemenin kendisine sorulur. Çökmeyi bildiren düzenek, çöktüğü anda ağsız kalmış bir aygıtta ne kadar çalışır?

## İki Platformdan Tek Telemetri

İki platform, iki ayrı çökme düzeneği ve iki ayrı olay kaynağı demektir. iOS'ta sistem tanılama verisini uygulamaya bir sonraki açılışta teslim eder; Android'de uygulama yakalanmamış hata için bir işleyici kaydeder. Verinin biçimi, adı ve zamanı farklıdır. Ekibin işi, bu farkı toplama noktasında kapatmaktır: iki platform da aynı alanlara sahip tek bir olay biçimi üretir, böylece panoda "çökme" tek bir kavram olur.

Birleşik biçim üç şeyi taşımalıdır: olayın türü, oturumun kimliği ve yapının sürümü. Sürüm olmadan bir çökmeyi hangi yayına bağlayacağınız bilinmez. Önceki derslerde gördüğünüz aşamalı yayın ve geri alma kararları bu bağı kullanır: yeni kovaya açılan sürümün çökme raporları artarsa durdurma ve uzaktan kapatma bayrağı o veriyle verilir.

## Çökme Raporu ve Simgeleştirme

Çökme raporu, çöken anın izini taşır: hangi işlevden hangi işleve gidildiği. Yayına çıkan yapıda bu izdeki adlar kısaltılmış ve adresler sayısaldır; okunur olması için yapıyı üretirken oluşan sembol dosyasına bakılır. Adresleri işlev ve satır adlarına çevirmeye simgeleştirme denir. Sembol dosyası yapıyla aynı sürümden olmalıdır ve her yayında saklanmalıdır; saklanmamış bir yayının çökmesi okunamaz.

Aşağıdaki iki parça, çöken anı yerelde kaydetmenin platform tarafını gösterir. Parçalar ölçülmez.

```swift
// Platform kodu: iOS tanilama abonesi
final class DiagnosticsReceiver: NSObject, MXMetricManagerSubscriber {
    func didReceive(_ payloads: [MXDiagnosticPayload]) {
        for payload in payloads { crashStore.save(payload.jsonRepresentation()) }
    }
}
```

```kotlin
// Platform kodu: yakalanmamis hata isleyicisi
Thread.setDefaultUncaughtExceptionHandler { _, error ->
    crashStore.save(error.stackTraceToString())
}
```

İki parçada da ilk iş aynıdır: raporu yerel depoya yazmak. Ağa göndermek çöken süreçte güvenilir değildir; süreç gönderim bitmeden ölebilir. Gönderim, uygulama sonraki açılışında sağlam bir süreçte yapılır.

## Analitik Olayları ve Kullanıcı İzni

Analitik olayı, kullanıcının uygulamada ne yaptığını kaydeder: bir ekran açıldı, bir düğmeye basıldı. Çökme raporu bir hatanın izidir; analitik olayı ise davranıştır ve kullanıcıya bağlanabilir. Bu yüzden ikisi aynı izne tabi tutulmaz. Kullanıcı davranışın izlenmesini kapattıysa analitik olayı hiç üretilmez ve sonradan gönderilmek üzere saklanmaz. Saklamak da bir toplamadır.

Burada bir ayrım önemlidir: izin bir yetenektir ve yedeği yoktur. Ağ yokken olay beklenebilir, çünkü ağ geri gelir. İzin yokken olay beklemez, çünkü izin kendiliğinden gelmez. İlki ertelenen, ikincisi kapalıdır. Çökmesiz oturum sayısı da buraya bağlanır: bir oturumun çökmediğini söylemek için o oturumdan rapor gelmemiş olması yetmez, raporun gelebilecek durumda olması gerekir. Oran burada yazılmaz; sayı oturum sayısıdır.

## İzlemenin Koşulunu Ölçmek

Ölçüm üç özelliği ele alır. `Settings` izlemeye hiç ihtiyaç duymaz. `CrashReport` ağa ihtiyaç duyar ve ağ yoksa ertelenen çalışır. `UsageEvent` hem ağa hem kullanıcı iznine ihtiyaç duyar; ağın yedeği ertelenen, iznin yedeği yoktur. Çekirdek önceki derslerdeki gibidir ve her derste aynı biçimde yeniden verilir.

```javascript
// operability.mjs — bir ozelligin bir kosulda ne kadar calistigini siniflandirir
export const LEVELS = ["tam", "kisitli", "ertelenen", "kapali"];
const FALLBACKS = ["kisitli", "ertelenen"];

export function feature(name, needs, fallback = {}) {
  return { name, needs, fallback };
}

export function condition(name, has) {
  return { name, has };
}

function judge(item, cond) {
  const missing = item.needs.filter((need) => !cond.has.includes(need)).sort();
  let level = "tam";
  for (const need of missing) {
    const given = FALLBACKS.includes(item.fallback[need]) ? item.fallback[need] : "kapali";
    if (LEVELS.indexOf(given) > LEVELS.indexOf(level)) level = given;
  }
  return { level, feature: item.name, condition: cond.name, missing };
}

export function assess(features, conditions) {
  const records = [];
  for (const cond of conditions) {
    for (const item of features) records.push(judge(item, cond));
  }
  return records;
}

export function printLevels(records) {
  for (const r of records) {
    const missing = r.missing.length === 0 ? "-" : r.missing.join(",");
    console.log(`${r.level}: ${r.feature} @ ${r.condition} eksik=${missing}`);
  }
}

export function countLevels(records) {
  for (const name of LEVELS) {
    console.log(`${name}: ${records.filter((r) => r.level === name).length}`);
  }
  console.log(`etkilenen: ${records.filter((r) => r.level !== "tam").length}`);
}
```

Çekirdeğin ardından dersin yardımcı dosyası gelir. `conditionsFor(session)` bir oturumun ağını ve iznini yeteneğe çevirir.

```javascript
// telemetry.mjs — oturumun agini ve kullanici iznini yetenege cevirir
import { feature, condition } from "./operability.mjs";

export function conditionsFor(session) {
  const has = [];
  if (session.network) has.push("network");
  if (session.consent) has.push("consent");
  return condition(session.name, has);
}

export const telemetryFeatures = [
  feature("Settings", []),
  feature("CrashReport", ["network"], { network: "ertelenen" }),
  feature("UsageEvent", ["network", "consent"], { network: "ertelenen" }),
];
```

**YI11.** Model, çökme raporunu ağdan başka hiçbir yeteneğe bağlamaz. Gerçekte raporun gönderimi de kullanıcının tanılama tercihine bağlı olabilir; bu ders raporu yalnız ağ eksikliği için ölçer, tercih ayrıca eklenebilecek bir yetenektir.

İlk ölçüm üç oturumu üç özellikte koşar: ağı ve izni olan, ağı olmayan ve izni olmayan oturum.

```javascript
// main.mjs
import { assess, printLevels } from "./operability.mjs";
import { conditionsFor, telemetryFeatures } from "./telemetry.mjs";

const sessions = [
  { name: "online", network: true, consent: true },
  { name: "offline", network: false, consent: true },
  { name: "no-consent", network: true, consent: false },
];
printLevels(assess(telemetryFeatures, sessions.map(conditionsFor)));
```

```text
tam: Settings @ online eksik=-
tam: CrashReport @ online eksik=-
tam: UsageEvent @ online eksik=-
tam: Settings @ offline eksik=-
ertelenen: CrashReport @ offline eksik=network
ertelenen: UsageEvent @ offline eksik=network
tam: Settings @ no-consent eksik=-
tam: CrashReport @ no-consent eksik=-
kapali: UsageEvent @ no-consent eksik=consent
```

Ağ ve izin varken üç özellik de tamdır. Ağ yokken rapor ve olay ertelenen olur, ayarlar tam kalır. İzin yokken rapor gider, olay kapalıdır ve eksik olan yetenek `consent`'tir. Aynı `UsageEvent` iki farklı eksikle iki farklı düzeye düştü: eksik ağsa ertelenen, eksik izinse kapalı.

## Bağlantı Dönene Dek

Çevrimdışı oturumda çöken uygulama raporu yerel kuyruğa yazar. Kuyruk, ders-yerel `eventQueue` dizisidir. Bağlantı döndüğünde kuyruk boşaltılır ve rapor gider. Gönderimin kendisi bir iştir; işlerlik yalnız o anda raporun gidebilir olup olmadığını söyler.

İkinci ölçüm bir çökmeyi iki an için koşar: bağlantı yokken ve bağlantı döndükten sonra. Aynı ölçümde altı oturumluk bir listede kaç oturumun çökmesiz göründüğü, kaçının gerçekten çökmediğiyle karşılaştırılır.

```javascript
// main.mjs
import { assess, printLevels } from "./operability.mjs";
import { conditionsFor, telemetryFeatures } from "./telemetry.mjs";

const crashReport = telemetryFeatures.filter((item) => item.name === "CrashReport");
const eventQueue = [];

printLevels(assess(crashReport, [conditionsFor({ name: "offline", network: false, consent: true })]));
eventQueue.push({ kind: "crash" });
console.log(`kuyruk: ${eventQueue.length}`);
printLevels(assess(crashReport, [conditionsFor({ name: "reconnected", network: true, consent: true })]));
console.log(`kuyruk bosaltildi: ${eventQueue.splice(0).length}`);

const sessions = [
  { crashed: false, delivered: false },
  { crashed: false, delivered: false },
  { crashed: true, delivered: true },
  { crashed: false, delivered: false },
  { crashed: true, delivered: false },
  { crashed: false, delivered: false },
];
const seen = sessions.filter((item) => !item.delivered).length;
const actual = sessions.filter((item) => !item.crashed).length;
console.log(`oturum: ${sessions.length} cokmesiz gorunen: ${seen} gercek: ${actual}`);
```

```text
ertelenen: CrashReport @ offline eksik=network
kuyruk: 1
tam: CrashReport @ reconnected eksik=-
kuyruk bosaltildi: 1
oturum: 6 cokmesiz gorunen: 5 gercek: 4
```

Rapor çevrimdışıyken ertelenen, bağlantı döndükten sonra tamdır. Kuyruktaki tek rapor gitti. Altı oturumdan ikisi çökmüştü, ama biri henüz teslim edilmemişti; bu yüzden panoda beş oturum çökmesiz görünüyor, gerçekte dördü çökmedi. Bekleyen rapor, çökmesiz oturum sayısını olduğundan iyi gösterir.

**YI12.** Model, kuyruğu tek bir olay için ve kayıpsız varsayar. Gerçekte kuyruk dolabilir, uygulama yeniden kurulduğunda silinebilir ya da gönderim yarıda kesilebilir. Kural bunları görmez; yalnız ağın koşulda olup olmadığına bakar.

## Sınırlayıcı Ölçüm

Bu dersin odak kaydı `CrashReport @ offline`'dır. Sınırlayıcı ölçüm iki şeyi birlikte gösterir. Birincisi, odak kayıt ertelenendir ve dokuz kaydın üçü etkilenir; izin olmayan oturumda `UsageEvent` yedeksiz olduğundan kapalıdır. İkincisi, kuyrukta bekleyen rapor sayısı kayda girmez: kuyrukta hiç rapor olmasa da üç rapor olsa da kayıt aynıdır.

```javascript
// main.mjs
import { assess, printLevels, countLevels } from "./operability.mjs";
import { conditionsFor, telemetryFeatures } from "./telemetry.mjs";

const sessions = [
  { name: "online", network: true, consent: true },
  { name: "offline", network: false, consent: true },
  { name: "no-consent", network: true, consent: false },
];
const records = assess(telemetryFeatures, sessions.map(conditionsFor));
printLevels(records.filter((r) => `${r.feature} @ ${r.condition}` === "CrashReport @ offline"));
printLevels(records.filter((r) => `${r.feature} @ ${r.condition}` === "UsageEvent @ no-consent"));
countLevels(records);

const crashReport = telemetryFeatures.filter((item) => item.name === "CrashReport");
const queued = [0, 3].map((count) => ({
  count,
  level: assess(crashReport, [conditionsFor(sessions[1])])[0].level,
}));
const same = queued[0].level === queued[1].level ? "evet" : "hayir";
console.log(`kuyruk ${queued[0].count} ve ${queued[1].count}: kayit ayni: ${same}`);
```

```text
ertelenen: CrashReport @ offline eksik=network
kapali: UsageEvent @ no-consent eksik=consent
tam: 6
kisitli: 0
ertelenen: 2
kapali: 1
etkilenen: 3
kuyruk 0 ve 3: kayit ayni: evet
```

İlk iki satır dersin iki ucunu verir: ağ eksikse ertelenen, izin eksikse kapalı. Sayımda dokuz kaydın altısı tam, ikisi ertelenen, biri kapalıdır; etkilenen üçtür. Son satır modelin sınırını gösterir: kural kuyruğu görmez. Kuyrukta bekleyen çok rapor bir iş yüküdür ve izleme panosunda ayrıca sayılır; işlerlik düzeyini değiştirmez.

## Kurs Kapanışı

Kurs on dört derste on dört özelliği, her biri kendi koşulunda, aynı dört düzeyle ölçtü. Aşağıdaki tablo her dersin odak kaydını, işlerliğini ve o dersi sınırlayan ölçümü verir. İşlerlik sütunu her dersin `## Özet` bölümünde yazılı olandır.

| Ders | Odak kayıt | İşlerlik | Sınırlayıcı ölçüm |
|---|---|---|---|
| Modüler Kod Paylaşımı | `Scan @ android` | kapalı | `scanner` katmanı yazılmadı, yedek yok |
| Tasarım Sistemi Uyarlaması | `DatePicker @ android` | tam | İki seçici biçimi, aynı `picker` yeteneği |
| Yapılandırma ve Ortam Yönetimi | `Search @ prod-default` | tam | Varsayılanı kapalı bayrakta `prod-default-off` kapalı |
| Erişilebilirlik | `CardSwipe @ screen-reader` | kısıtlı | Yedeksiz `CustomGesture` kapalı |
| Çevrimdışı Öncelikli Tasarım | `FeedLocal @ offline` | kısıtlı | Ağ öncelikli `FeedRemote` kapalı |
| Eşitleme Stratejileri | `EditNote @ offline` | ertelenen | Bağlantı varken `EditNote` tam |
| Arka Plan İşleme Sınırları | `MediaBackup @ background-restricted` | ertelenen | Yedeksiz `LiveLocation` kapalı |
| Bağlantı Durumu Yönetimi | `Gallery @ weak-network` | kısıtlı | Aynı koşulda `Chat` ertelenen |
| Mobil Sürekli Teslimat | `NewCheckout @ production` | kapalı | Modelde imzalanma kayda girmez (tanım gereği) |
| Sürüm Yönetimi | `OrderHistory @ api-v2` | kısıtlı | İstemci sürümü kayda girmez |
| Aşamalı Yayın ve Geri Alma | `NewFeed @ device-a` | tam | Yayın genişleyince kayıt değişmez |
| Zorunlu Güncelleme Stratejisi | `Payments @ client-v4` | kapalı | İstemin sertliği kayda girmez |
| Uygulama Boyutu Yönetimi | `Filters @ base-install` | ertelenen | İlk indirme sınırı kayda girmez |
| Çökme ve Kullanım İzleme | `CrashReport @ offline` | ertelenen | Kuyruktaki rapor sayısı kayda girmez |

Tablodaki on üç satır önceki derslerden alınır; on dördüncü satırın düzeyi bu dersin kendi ölçümünden gelir. Son ölçüm tabloyu sayar ve çekirdeğin ilk derste verdiği açılış sayımını yanına koyar.

```javascript
// main.mjs
import { assess } from "./operability.mjs";
import { conditionsFor, telemetryFeatures } from "./telemetry.mjs";

const earlier = ["kapali", "tam", "tam", "kisitli", "kisitli", "ertelenen", "ertelenen",
  "kisitli", "kapali", "kisitli", "tam", "kapali", "ertelenen"];
const crashReport = telemetryFeatures.filter((item) => item.name === "CrashReport");
const focus = assess(crashReport, [conditionsFor({ name: "offline", network: false, consent: true })])[0];
const lessons = [...earlier, focus.level];

const order = ["tam", "kisitli", "ertelenen", "kapali"];
const spread = order.map((name) => `${name}=${lessons.filter((level) => level === name).length}`);
const opening = { tam: 5, kisitli: 1, ertelenen: 2, kapali: 1 };
const openingTotal = Object.values(opening).reduce((sum, count) => sum + count, 0);

console.log(`ders: ${lessons.length}`);
console.log(`odak: ${focus.feature} @ ${focus.condition} ${focus.level}`);
console.log(`dagilim: ${spread.join(" ")}`);
console.log(`cekirdek acilis: kayit=${openingTotal} etkilenen=${openingTotal - opening.tam}`);
```

```text
ders: 14
odak: CrashReport @ offline ertelenen
dagilim: tam=3 kisitli=4 ertelenen=4 kapali=3
cekirdek acilis: kayit=9 etkilenen=4
```

On dört dersin dağılımı üç tam, dört kısıtlı, dört ertelenen ve üç kapalıdır. Çekirdeğin açılış sayımı ise başka bir şeydir: dokuz kayıttan beşi tam, biri kısıtlı, ikisi ertelenen, biri kapalıydı ve etkilenen dörttü. Çekirdek tek bir uygulamanın dokuz kaydını sayar, tablo on dört dersi sayar. İki sayım aynı şey değildir ve birbirinden türetilemez.

Dağılım bir şeyi daha söyler: bir özelliğin kapalı kalması sık görülen bir sonuç değildir ve tam çalışması da kural değildir. Tablonun her satırı, bir koşulun bir özelliğe ne yaptığını gösteren ayrı bir ölçümdür.

## Özet

- Bu dersin işlerliği: ertelenen. `CrashReport @ offline`, `network` eksik olduğu ve ertelenen yedeği tanımlandığı için ertelenen çıktı; aynı koşulda `UsageEvent` ertelenen, `Settings` tam kaldı.
- Çökme raporu çöken süreçte değil, yerel depoda saklanır ve bağlantı dönünce sağlam bir süreçten gider; kuyruktaki bir rapor bağlantı dönünce boşaldı.
- Kullanıcı izni yedeksiz bir yetenektir: `UsageEvent @ no-consent` kapalı çıktı, aynı olay ağ yokken yalnız ertelenen oldu.
- Teslim edilmemiş rapor çökmesiz oturum sayısını olduğundan iyi gösterir: altı oturumda beş çökmesiz görünürken dördü gerçekten çökmemişti.
- On dört dersin dağılımı üç tam, dört kısıtlı, dört ertelenen ve üç kapalıdır.

## Sonraki Adım

Bu ders kursun ve kataloğun son dersidir; sırada ders yok. Elinizde kalan araç kursun sorusudur: bir özelliği, bir koşulu ve eksik yeteneği yazın, yedeğini tanımlayın ve kaydın hangi düzeye düştüğünü kendi uygulamanızda ölçün.
