Monitoring ve Observability
Cloudflare Workers observability, Sentry hata izleme, logging ve performance monitoring stratejisi.
Achidemy, production’da Sentry (hata izleme), Cloudflare Workers Observability (log/trace) ve Session Replay ile izlenir. Bu sayfa monitoring yapılandırmasını, Sentry çalışma yapısını ve log/performance stratejisini açıklar.
Sentry Hata İzleme Sistemi
Section titled “Sentry Hata İzleme Sistemi”Durum: Aktif. Backend (Worker) ve frontend (tarayıcı) hataları Sentry’ye gönderilir; Stripe webhook ve kritik akışlarda özel sensörler kullanılır.
Paketler: @sentry/cloudflare (Worker), @sentry/react (client).
Sentry Çalışma Yapısı
Section titled “Sentry Çalışma Yapısı”Aşağıdaki yapı, hataların nerede yakalandığı ve Sentry’ye nasıl iletildiğini özetler.
┌─────────────────────────────────────────────────────────────────────────────┐│ SENTRY VERİ AKIŞI │├─────────────────────────────────────────────────────────────────────────────┤│ ││ BACKEND (Cloudflare Worker) ││ ┌──────────────────────────────────────────────────────────────────────┐ ││ │ workers/app.ts │ ││ │ • Sentry.withSentry(env => ({ dsn, tracesSampleRate }), handler) │ ││ │ • Tüm fetch/scheduled hataları otomatik + manuel captureException │ ││ │ • scheduled: updateCachedRates() catch → Sentry.captureException │ ││ │ • fetch: requestHandler catch → Sentry.captureException (tag: │ ││ │ service: "worker_router", extra: url) │ ││ └──────────────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌──────────────────────────────────────────────────────────────────────┐ ││ │ app/routes/api.stripe.webhook.ts │ ││ │ • İmza doğrulama hatası → Sentry (tag: stripe_webhook_signature) │ ││ │ • Sepet satışı hatası → Sentry (tag: stripe_cart_sale, │ ││ │ extra: sessionId, userId) │ ││ │ • Refund hatası → Sentry (tag: stripe_refund, extra: eventType) │ ││ └──────────────────────────────────────────────────────────────────────┘ ││ │ │├───────────┼─────────────────────────────────────────────────────────────────┤│ │ ││ FRONTEND (Tarayıcı) ││ ┌──────────────────────────────────────────────────────────────────────┐ ││ │ app/entry.client.tsx │ ││ │ • Sentry.init({ dsn: VITE_SENTRY_DSN, browserTracingIntegration, │ ││ │ replayIntegration, tracesSampleRate: 0.1, replaysSessionSampleRate:│ ││ │ 0.1, replaysOnErrorSampleRate: 1.0 }) │ ││ └──────────────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌──────────────────────────────────────────────────────────────────────┐ ││ │ app/root.tsx │ ││ │ • Layout: unhandledrejection / error → Sentry.captureException │ ││ │ (tags: type: "unhandled_rejection" | "global_error") │ ││ │ • App ReactErrorBoundary onError → Sentry.captureException │ ││ │ (contexts: react: errorInfo) │ ││ │ • Route ErrorBoundary useEffect → Sentry.captureException │ ││ │ (tags: route: pathname) │ ││ └──────────────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ Sentry Dashboard (Issues, Performance, Replays) ││ │└─────────────────────────────────────────────────────────────────────────────┘Ortam Değişkenleri
Section titled “Ortam Değişkenleri”| Ortam | Değişken | Açıklama |
|---|---|---|
| Worker (backend) | SENTRY_DSN | Sentry proje DSN. wrangler.toml [vars] veya wrangler secret put SENTRY_DSN. Yerelde .dev.vars. |
| Client (frontend) | VITE_SENTRY_DSN | Aynı DSN; client bundle’da build zamanında enjekte edilir. .env / .dev.vars veya CI’da tanımlanmalı. |
Not: DSN boşsa Sentry event göndermez; uygulama çalışmaya devam eder.
Nerede Hata Yakalanır?
Section titled “Nerede Hata Yakalanır?”| Kaynak | Dosya / Yer | Tag / Extra |
|---|---|---|
| Worker genel | workers/app.ts (fetch catch) | service: "worker_router", url |
| Worker scheduled | workers/app.ts (scheduled catch) | — |
| Stripe imza | api.stripe.webhook.ts | context: "stripe_webhook_signature" |
| Stripe sepet satışı | api.stripe.webhook.ts | context: "stripe_cart_sale", sessionId, userId |
| Stripe refund | api.stripe.webhook.ts | context: "stripe_refund", eventType |
| Tarayıcı unhandled rejection | app/root.tsx (Layout) | type: "unhandled_rejection" |
| Tarayıcı global error | app/root.tsx (Layout) | type: "global_error" |
| React Error Boundary | app/root.tsx (App) | contexts.react (errorInfo) |
| Route ErrorBoundary | app/root.tsx (ErrorBoundary) | route: pathname |
Session Replay ve Performance
Section titled “Session Replay ve Performance”- tracesSampleRate (client): 0.1 — trafiğin %10’u performans izlenir.
- replaysSessionSampleRate: 0.1 — oturumların %10’u videoya alınır.
- replaysOnErrorSampleRate: 1.0 — hata olan tüm oturumların replay’i Sentry’ye gönderilir (beyaz ekran / tıklama konumu analizi için).
Detaylı hata sayfaları ve Error Boundary kullanımı için bkz. Hata Yönetimi ve Logging.
Cloudflare Workers Observability
Section titled “Cloudflare Workers Observability”Yapılandırma: wrangler.toml
[observability.logs]enabled = truehead_sampling_rate = 1persist = trueinvocation_logs = trueÖzellikler:
- Enabled: Log kaydı aktif
- Head Sampling Rate: %100 log kaydı (1 = tüm request’ler)
- Persist: Log’lar Cloudflare Dashboard’da saklanır
- Invocation Logs: Her worker invocation için log
Kullanım:
// Worker içindeconsole.log("Request received:", { path: url.pathname, method: request.method });console.error("Error occurred:", error);console.warn("Warning:", message);Görüntüleme:
- Cloudflare Dashboard → Workers → Logs
- CLI:
wrangler tail(real-time logs)
Traces
Section titled “Traces”[observability.traces]enabled = falsepersist = truehead_sampling_rate = 1Not: Şu an traces kapalı; performance profiling için açılabilir.
Kullanım Senaryoları:
- Request latency analizi
- Database query süreleri
- External API çağrı süreleri
Performance Monitoring
Section titled “Performance Monitoring”Request Metrics
Section titled “Request Metrics”Cloudflare Dashboard:
- Request sayısı
- Error rate
- Average response time
- P95/P99 latency
Görüntüleme:
- Cloudflare Dashboard → Workers → Analytics
Database Performance
Section titled “Database Performance”Hyperdrive Metrics:
- Connection pool kullanımı
- Query latency
- Connection errors
Görüntüleme:
- Cloudflare Dashboard → Hyperdrive → Analytics
Custom Metrics
Section titled “Custom Metrics”Örnek: Video izleme süresi tracking
// app/lib/metrics.ts (gelecekte)export function trackVideoWatchTime(courseId: string, seconds: number) { // Analytics servisine gönder (örn: Google Analytics, Mixpanel) if (import.meta.env.PROD) { // analytics.track('video_watched', { courseId, seconds }); }}Logging Best Practices
Section titled “Logging Best Practices”1. Log Levels
Section titled “1. Log Levels”| Level | Kullanım | Örnek |
|---|---|---|
console.log | Genel bilgi | Request path, user action |
console.warn | Uyarı | Deprecated API kullanımı, fallback durumları |
console.error | Hata | Exception, failed request |
2. Structured Logging
Section titled “2. Structured Logging”// ✅ İyi: Structured logconsole.log("User enrolled", { userId: user.id, courseId: course.id, price: enrollment.price, timestamp: new Date().toISOString()});
// ❌ Kötü: Unstructured logconsole.log(`User ${user.id} enrolled in course ${course.id}`);3. Sensitive Data
Section titled “3. Sensitive Data”Loglanmaması Gerekenler:
- Passwords
- API keys
- Credit card numbers
- Personal identifiable information (PII)
Örnek:
// ❌ Kötüconsole.log("User data:", user); // Password içerebilir
// ✅ İyiconsole.log("User enrolled", { userId: user.id, email: user.email, // Email OK, password değil});Real-Time Monitoring
Section titled “Real-Time Monitoring”Wrangler Tail
Section titled “Wrangler Tail”Kullanım: Yerel veya production log’larını real-time görüntüleme
# Production logswrangler tail
# Belirli worker içinwrangler tail --name coursio
# Filter ilewrangler tail --format pretty | grep "ERROR"Cloudflare Dashboard
Section titled “Cloudflare Dashboard”URL: https://dash.cloudflare.com
Bölümler:
- Workers → Logs: Real-time ve geçmiş log’lar
- Workers → Analytics: Request metrics, error rate
- Hyperdrive → Analytics: Database connection metrics
Alerting (Gelecek)
Section titled “Alerting (Gelecek)”Önerilen Alert’ler
Section titled “Önerilen Alert’ler”- Error Rate: %5’in üzerinde error rate
- Response Time: P95 latency 2 saniyenin üzerinde
- Database Errors: Connection pool exhaustion
- Stripe Webhook Failures: Webhook işleme hataları
- Currency Sync Failures: Kur güncelleme cron job hataları
Alert Channels
Section titled “Alert Channels”- E-posta: Kritik hatalar için
- Slack: Ekip bildirimleri için
- PagerDuty: On-call durumlar için
Health Check Endpoint (Gelecek)
Section titled “Health Check Endpoint (Gelecek)”Önerilen: /api/health endpoint’i
export async function loader() { const checks = { database: await checkDatabase(), stripe: await checkStripe(), bunny: await checkBunny(), };
const isHealthy = Object.values(checks).every(c => c.status === 'ok');
return json(checks, { status: isHealthy ? 200 : 503 });}Kullanım: Uptime monitoring servisleri için.
İlgili Dosyalar
Section titled “İlgili Dosyalar”wrangler.toml— Observability ve[vars]içindeSENTRY_DSN,VITE_SENTRY_DSNworkers/app.ts— Sentry.withSentry sarmalayıcı, Worker hata yakalamaapp/entry.client.tsx— Sentry.init (client), browserTracing, replayapp/root.tsx— Global error / unhandledrejection ve ErrorBoundary içinde Sentry.captureExceptionapp/routes/api.stripe.webhook.ts— Stripe webhook Sentry sensörleri (imza, sepet, refund)app/components/ErrorBoundary.tsx— React Error Boundary (onError root’tan gelir)