مقدمة: لماذا تعتبر مراقبة تطبيقات Swift أمرًا لا غنى عنه للإنتاج
\nعندما يصل تطبيق Swift الخاص بك إلى مرحلة الإنتاج، لا يكفي مجرد التأكد من أنه لا يتعطل. المستخدمون المعاصرون يطالبون بالاستجابة والاستقرار والسرعة. بدون نظام مراقبة، أنت تطير في الظلام: تأخيرات واجهة المستخدم، تسرب الذاكرة، طلبات الشبكة البطيئة - كل هذا يبقى غير ملحوظ حتى أول تعليقات سلبية. في هذه المقالة، سنستعرض المستوى المتقدم لمراقبة تطبيقات Swift: من جمع المقاييس المخصصة إلى إعداد التنبيهات في الوقت الفعلي. ستتعلم كيفية استخدام os_log و Signposts والتكامل مع Prometheus و Grafana، وكذلك كيفية الاستجابة تلقائيًا للشذوذ.
1. بنية جمع المقاييس في Swift: من OSLog إلى المزودين المخصصين
\nالمراقبة الأساسية في Swift تُبنى على os_log و OSSignposter. ولكن للتحليل المتقدم، هذا لا يكفي. تحتاج إلى ناقل بيانات موحد يجمع المقاييس من مصادر مختلفة: الشبكة، واجهة المستخدم، المعالجة الخلفية، الذاكرة.
1.1. استخدام OSSignposter لقياس الأداء
\nOSSignposter هي أداة قوية لتحديد الأداء. تتيح لك إنشاء أحداث زمنية ومنفصلة، والتي تكون مرئية بعد ذلك في Instruments ويمكن تصديرها إلى لوحات معلومات مخصصة.
import os\n\nlet signposter = OSSignposter(subsystem: "com.yourapp.network", category: "API")\n\n// قياس وقت تنفيذ الطلب\nlet state = signposter.beginInterval("FetchUserData", id: signposter.makeSignpostID())\nURLSession.shared.dataTask(with: url) { data, _, error in\n if let error = error {\n signposter.emitEvent("Error", "\\(error.localizedDescription)")\n }\n signposter.endInterval("FetchUserData", state)\n}.resume()\nنصيحة: قم بتجميع الفترات حسب نوع العملية (الشبكة، قاعدة البيانات، العرض) لرؤية الصورة الكاملة في لوحة المعلومات.
\n\n1.2. جامع المقاييس المخصص MetricCollector
\nأنشئ كلاس singleton يقوم بجمع المقاييس في مخزن مؤقت آمن للخيوط وإرسالها إلى الخادم كل N ثانية. هذا هو الأساس للتكامل مع أي خلفية.
\nfinal class MetricCollector {\n static let shared = MetricCollector()\n private let queue = DispatchQueue(label: "com.yourapp.metrics", qos: .utility)\n private var buffer: [String: Double] = [:]\n \n func record(_ name: String, value: Double) {\n queue.async {\n self.buffer[name, default: 0] += value\n }\n }\n \n func flush() -> [String: Double] {\n queue.sync {\n let copy = self.buffer\n self.buffer.removeAll()\n return copy\n }\n }\n}\n\n2. مقاييس مخصصة لـ Swift: ما يجب قياسه وكيف
\nالمقاييس القياسية (FPS، استخدام الذاكرة) هي الأساس. المستوى المتقدم يتطلب مقاييس الأعمال ومقاييس تجربة المستخدم.
\n- \n
- الوقت حتى التفاعل (TTI): قياس من بدء التطبيق حتى اللحظة التي يمكن للمستخدم فيها القيام بأول إجراء. \n
- معدل أخطاء منطق الأعمال: على سبيل المثال، محاولات تسجيل الدخول الفاشلة، فشل الدفع. \n
- حجم ذاكرة التخزين المؤقت والقرص: التحكم لضمان عدم استهلاك التطبيق للجيجابايتات. \n
- سرعة الرسوم المتحركة: قياس الإطارات في الثانية (FPS) باستخدام CADisplayLink. \n
2.1. مثال: مراقبة FPS مع تنبيه للأداء المنخفض
\nimport UIKit\n\nfinal class FPSMonitor {\n private var displayLink: CADisplayLink?\n private var lastTimestamp: CFTimeInterval = 0\n private var frameCount = 0\n \n func start() {\n displayLink = CADisplayLink(target: self, selector: #selector(tick))\n displayLink?.add(to: .main, forMode: .common)\n }\n \n @objc private func tick() {\n frameCount += 1\n let delta = displayLink?.targetTimestamp ?? 0 - lastTimestamp\n if