مقدمة: لماذا تعتبر المراقبة أمرًا حيويًا لتطبيقات TypeScript
\nTypeScript أداة قوية لبناء تطبيقات ويب قابلة للتوسع، ولكن حتى أفضل كود ليس محصنًا ضد الأعطال في بيئة الإنتاج. بدون نظام مراقبة، فإنك تخاطر بمعرفة المشكلات من المستخدمين بدلاً من التنبيهات التلقائية. في هذه المقالة، سنشرح الدورة الكاملة لإعداد المراقبة: من جمع المقاييس إلى إرسال الإشعارات.
\nسنناقش الركائز الثلاث الرئيسية للمراقبة (observability): المقاييس (المؤشرات الرقمية للنظام)، السجلات (تسجيلات مفصلة للأحداث)، والتتبع (تتبع الطلبات). سنركز بشكل خاص على التكامل مع الأدوات الشائعة — Prometheus و Grafana و Sentry.
\n\n1. المقاييس الأساسية لتطبيقات TypeScript
\nقبل إعداد التنبيهات، يجب تحديد المقاييس الحيوية لتطبيقك. سنقسمها إلى ثلاث مجموعات:
\n\n1.1 مقاييس الأعمال
\nتعكس صحة التطبيق من وجهة نظر المستخدم:
\n- \n
- عدد الطلبات في الثانية (RPS) — يوضح الحمل على الخادم \n
- وقت الاستجابة (الكمون) — النسب المئوية p50، p95، p99 \n
- عدد الأخطاء — حالات 4xx و 5xx \n
- المستخدمون النشطون — الجلسات، اتصالات WebSocket \n
1.2 المقاييس التقنية
\nتظهر حالة البنية التحتية:
\n- \n
- CPU والذاكرة — تحميل المعالج وتسريبات الذاكرة \n
- تأخر حلقة الأحداث (Event Loop Lag) — التأخيرات في دورة أحداث Node.js \n
- جمع القمامة (Garbage Collection) — تواتر ومدة جمع القمامة \n
- مجموعة اتصالات HTTP — عدد الاتصالات المفتوحة \n
1.3 مثال: جمع المقاييس مع Prometheus في TypeScript
\nسنقوم بتثبيت مكتبة prom-client لـ Node.js:
npm install prom-client @types/prom-client\n\nسننشئ ملف metrics.ts:
import client from 'prom-client';\nimport express, { Request, Response } from 'express';\n\n// إنشاء سجل المقاييس\nconst register = new client.Registry();\nclient.collectDefaultMetrics({ register });\n\n// مقياس مخصص: عدد طلبات HTTP\nconst httpRequestCounter = new client.Counter({\n name: 'http_requests_total',\n help: 'Total number of HTTP requests',\n labelNames: ['method', 'route', 'status_code'],\n registers: [register],\n});\n\n// رسم بياني لوقت الاستجابة\nconst httpRequestDuration = new client.Histogram({\n name: 'http_request_duration_seconds',\n help: 'Duration of HTTP requests in seconds',\n labelNames: ['method', 'route', 'status_code'],\n buckets: [0.1, 0.5, 1, 2, 5],\n registers: [register],\n});\n\n// Middleware لجمع المقاييس\nexport function metricsMiddleware(req: Request, res: Response, next: Function) {\n const end = httpRequestDuration.startTimer();\n res.on('finish', () => {\n const labels = {\n method: req.method,\n route: req.route?.path || 'unknown',\n status_code: res.statusCode.toString(),\n };\n httpRequestCounter.inc(labels);\n end(labels);\n });\n next();\n}\n\n// نقطة نهاية لـ Prometheus\nexport function metricsEndpoint(req: Request, res: Response) {\n res.set('Content-Type', register.contentType);\n res.send(register.metrics());\n}\n\n2. إعداد التنبيهات: من النظرية إلى التطبيق
\nيجب أن تكون التنبيهات ذكية — فالكثير من الإنذارات الكاذبة يرهق الفريق. سنستخدم قاعدة "ثلاث سيجما" للشذوذ والقيم الحدية للمقاييس الحرجة.
\n\n2.1 قواعد التنبيهات في Prometheus
\nأنشئ ملف alerts.yml:
groups:\n - name: typescript-app\n rules:\n - alert: HighErrorRate\n expr: |\n rate(http_requests_total{status_code=~"5.."}[5m]) \n / \n rate(http_requests_total[5m]) > 0.05\n for: 2m\n labels:\n severity: critical\n annotations:\n