Introduction : Pourquoi la surveillance des applications Swift est un must-have pour la production
\nLorsque votre application Swift passe en production, il ne suffit pas de vérifier qu'elle ne plante pas. Les utilisateurs modernes exigent réactivité, stabilité et rapidité. Sans système de surveillance, vous volez à l'aveugle : les ralentissements dans l'UI, les fuites mémoire, les requêtes réseau lentes – tout cela reste inaperçu jusqu'aux premiers avis négatifs. Dans cet article, nous aborderons le niveau avancé de la surveillance des applications Swift : de la collecte de métriques personnalisées à la configuration d'alertes en temps réel. Vous apprendrez à utiliser os_log, Signposts, l'intégration avec Prometheus et Grafana, ainsi qu'à réagir automatiquement aux anomalies.
1. Architecture de collecte de métriques en Swift : de OSLog aux fournisseurs personnalisés
\nLa surveillance de base en Swift repose sur os_log et OSSignposter. Mais pour une analyse avancée, cela ne suffit pas. Il faut un bus de données unifié qui agrège les métriques provenant de différentes sources : réseau, UI, traitement en arrière-plan, mémoire.
1.1. Utilisation de OSSignposter pour mesurer les performances
\nOSSignposter est un outil puissant pour le profilage. Il permet de créer des événements intervalés et discrets, visibles ensuite dans Instruments et exportables vers des tableaux de bord personnalisés.
import os\n\nlet signposter = OSSignposter(subsystem: "com.yourapp.network", category: "API")\n\n// Mesure du temps d'exécution de la requête\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()\nConseil : regroupez les intervalles par type d'opération (réseau, base de données, rendu) pour avoir une vue d'ensemble dans le tableau de bord.
\n\n1.2. MetricCollector personnalisé
\nCréez une classe singleton qui collecte les métriques dans un tampon thread-safe et les envoie au serveur toutes les N secondes. C'est la base pour l'intégration avec n'importe quel backend.
\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. Métriques personnalisées pour Swift : quoi mesurer et comment
\nLes métriques standard (FPS, utilisation mémoire) sont la base. Le niveau avancé nécessite des métriques métier et des métriques d'expérience utilisateur.
\n- \n
- Temps d'interactivité (TTI) : Mesure depuis le lancement de l'application jusqu'au moment où l'utilisateur peut effectuer une première action. \n
- Taux d'erreurs de logique métier : Par exemple, tentatives de connexion échouées, échecs de paiement. \n
- Taille du cache et du disque : Contrôle pour que l'application n'occupe pas des gigaoctets. \n
- Vitesse des animations : Mesure des images par seconde (FPS) avec CADisplayLink. \n
2.1. Exemple : surveillance des FPS avec alerte de faible performance
\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