Analyse de la Télémétrie et du Stockage
[!IMPORTANT] Contexte de l'incident et Recommandations Gandi Suite à un incident de surcharge sur l'infrastructure de production, notre hébergeur Gandi a recommandé de réduire la taille des données stockées dans la table de télémétrie afin de limiter la pression d'écriture et de lecture sur le serveur de base de données.
Ce document présente l'analyse détaillée du volume de données généré par le système afin de rationaliser la rétention des données et d'anticiper la scalabilité de l'infrastructure.
1. Structure de la table de Télémétrie (telemetries) dans MySQL
Dans la base de données MySQL, la table telemetries stocke les rapports périodiques envoyés par chaque client de bureau. Elle se compose des colonnes suivantes :
| Nom de Colonne | Type SQL | Rôle et Explication Technique |
|---|---|---|
id | BigInt (Primary Key) | Identifiant unique séquentiel de l'enregistrement. |
appname | String (VARCHAR) | Nom de l'application cliente à l'origine de l'envoi (ex: alta-call). |
version | String (VARCHAR) | Version du logiciel de bureau Alta Call installée (ex: 0.33.0). |
process_id | String (VARCHAR) | Identifiant unique (UUID) du processus d'exécution client. |
date | DateTime | Horodatage exact de capture des métriques par le client. |
cp_nbrunningproc | Int | Nombre total de processus Alta Call en cours d'exécution dans la session Windows. |
payload | LongText (JSON Cast) | Objet JSON contenant l'intégralité des mesures nettoyées (voir section 1.8). |
client_id | Int (Foreign Key) | Référence vers l'organisation cliente dans la table clients. |
user_id | Int (Foreign Key) | Référence vers l'agent d'appels dans la table users. |
first_for_date | TinyInt (Boolean) | Indicateur signalant s'il s'agit du premier paquet de télémétrie reçu pour ce jour. |
last_for_date | TinyInt (Boolean) | Indicateur signalant s'il s'agit du dernier paquet de télémétrie reçu pour ce jour. |
created_at | DateTime | Date et heure de l'insertion de l'enregistrement en base. |
updated_at | DateTime | Date et heure de la dernière mise à jour de l'enregistrement. |
1.2. Architecture Globale de la Base de Données (MySQL)
L'écosystème d'Alta Voce s'appuie sur une structure de base de données relationnelle MySQL normalisée et optimisée. L'analyse complète de toutes les tables, de leurs cardinalités, de leurs colonnes SQL précises, ainsi que les recommandations stratégiques d'indexation, sont disponibles sur la page dédiée :
👉 Architecture de la Base de Données (MySQL)
1.5. Optimisation du Payload Telemetry (TelemetryCleaningService)
Pour résoudre les surcharges du serveur et limiter la taille de la base de données, un service de nettoyage des charges utiles (payloads) de télémétrie a été déployé côté backend Laravel (App\Services\Telemetry\TelemetryCleaningService).
Métriques d'Optimisation
- Réduction de taille de la charge utile : 96,32 % de réduction en moyenne.
- Taille moyenne initiale : ~14 Ko par payload.
- Taille moyenne optimisée : ~535 Octets par payload.
- Espace de stockage économisé : ~13,6 Ko par enregistrement.
Clés Conservées (Whitelist / Données Utiles)
- Niveau racine :
audio_state,transfo_preset,name,version,reach_data_consent,consent_data_collection,from_downtime,datetime,virtdev_out_appname,ACP(nécessaire pour l'identification des périphériques),PT(nécessaire pour les transformations vocales et la facturation). - Niveau
libs.voimooo:machine_id,process_id,user_id,session_id_current,session_id_active,session_is_locked,cpu_machine,cpu(monitoring CPU du processus),session_active_unlocked,session_active_unlocked_since,audio. - Niveau
PT:transfo_mode,processing_state,tcfp,pvoccmb,levels,ctxb,alpha,beta,delta.
Clés Supprimées (Données Nettoyées)
- Section
RT: Suppression intégrale de la section (statistiques d'exécution, compteurs d'API, clés de licence). - Section
UI: Suppression intégrale de la section (valeurs de sliders et état graphique de l'application). - Section
configs: Supprimée car redondante avec la tableusers_configs. - Section
libs.voimooo(partielle) : Retrait des spécifications matérielles complètes du système, de l'historique exhaustif des périphériques et des hashes de sessions de debug.
1.8. Dictionnaire Exhaustif de la Charge Utile (Payload JSON)
Le tableau suivant présente la liste exhaustive de tous les paramètres transmis par le client de bureau Alta Call dans le JSON de télémétrie, ainsi que leur rôle fonctionnel précis :
Clés à la Racine du Payload (Root Level)
| Clé JSON | Type | Rôle et Contenu Fonctionnel |
|---|---|---|
name | String | Nom officiel de l'application cliente (toujours alta-call). |
version | String | Version exacte de l'application (ex: 0.33.0). |
audio_state | String | État d'activité du moteur audio (RUN, STP, LOD, FAI, CRA). |
transfo_preset | String | Identifiant de la configuration active de transformation vocale. |
reach_data_consent | Int (0/1) | Indique si les popups de consentement ont été présentées à l'utilisateur. |
consent_data_collection | Int (0/1) | Statut de consentement de l'agent pour la collecte de ses données vocales. |
from_downtime | Boolean | Indique si le paquet provient d'une file d'attente hors-ligne (restauration réseau). |
datetime | String | Date et heure d'origine en cas d'envoi différé (format ISO 8601). |
virtdev_out_appname | String | Nom du processus softphone connecté à la sortie virtuelle d'Alta Call. |
ACP | Object | Données du panneau de contrôle des périphériques audio (voir ci-dessous). |
PT | Object | Paramètres d'analyse et de traitement vocal en temps réel (voir ci-dessous). |
libs | Object | Données système collectées par le noyau de la machine (voir ci-dessous). |
UI | Object | États graphiques et verrouillages de l'interface utilisateur. |
configs | Object | Configuration complète du profil utilisateur à la livraison. |
RT | Object | Statistiques de requêtes API et d'exécution du runtime client. |
connectedapp_connected_apps | Object | Liste brute des applications vocales actives détectées en arrière-plan. |
Détails de la Section ACP (Audio Control Panel)
capture(Object) :using(String) : Nom exact du microphone physique actif.available(Object) : Dictionnaire complet de tous les microphones branchés, avec leur pilote (WASAPI/DirectSound), leur taux d'échantillonnage et leurs identifiants matériels uniques.
playback(Object) :using(String) : Nom exact du casque ou haut-parleur physique actif.available(Object) : Dictionnaire de tous les périphériques de restitution audio connectés.
Détails de la Section PT (Processing Telemetry)
transfo_mode(String) : Mode de modification acoustique appliqué (SMA: Sourire,VMO: Voix,STP: Arrêté).processing_state(String) : Statut de traitement (RUNouSTP).levels(Object) : Mesures de volume sonore médian de la voix en décibels (dB) d'entrée et de sortie.ctxb(Object) : Caractéristiques vocales fondamentales calculées, notamment la fréquence fondamentale (hauteur de voix F0) et les coefficients LSF (Line Spectral Frequencies) représentant le timbre.alpha,beta,delta(Float) : Facteurs mathématiques de traitement et coefficients du modèle vocal appliqué.
Détails de la Section libs.voimooo (Données Système)
machine_id(String) : Identifiant matériel (UUID unique) généré pour le poste de travail.process_id(String) : UUID de l'instance d'exécution actuelle du processus Alta Call.user_id(String) : Identifiant utilisateur Windows de l'agent.session_id_current(String) : Identifiant unique de la session système en cours.session_id_active(String) : Identifiant de la session Windows active et visible sur le bureau.session_is_locked(Boolean) : Flag indiquant si la session utilisateur Windows est verrouillée.cpu_machine(Float) : Utilisation processeur globale de l'ordinateur.cpu(Float) : Consommation processeur dédiée exclusivement au processus Alta Call (ex:0.12= 12%).session_active_unlocked(Boolean) : Indique si la machine est allumée et en utilisation déverrouillée.session_active_unlocked_since(String) : Horodatage exact depuis lequel l'agent utilise activement son poste déverrouillé.audio(Object) : Statut des pilotes virtuels et intégrations VoiceMeeter/Câbles Virtuels.
2. Volumétrie et Fréquence (Télémétries brutes)
- Taille moyenne d'une télémétrie : ~13 Ko
- Fréquence standard : 1 télémétrie par heure d'activité (soit environ 8 par jour pour un utilisateur moyen).
- Événements complémentaires : ~10 événements par jour (premier lancement de l'application, crash audio, verrouillage/déverrouillage de la session Windows, verrouillage/déverrouillage du logiciel), représentant ~130 Ko supplémentaires.
Calcul du volume par utilisateur
$$\text{Volume quotidien} = (13\text{ Ko} \times 8) + 130\text{ Ko} = 234\text{ Ko / utilisateur / jour}$$
Stockage pour 700 utilisateurs (parc actuel)
- 1 jour : ~163 Mo
- 3 jours : ~489 Mo
- 6 jours : ~976 Mo
- 7 jours : ~1,1 Go
- 30 jours (1 mois) : ~4,4 Go
3. Projection de stockage par paliers (Télémétries brutes)
Voici l'évolution estimée du stockage de la table telemetries en fonction de la croissance du parc d'utilisateurs actifs :
| Nb. Utilisateurs | 1 jour | 3 jours | 7 jours | 30 jours (Go) |
|---|---|---|---|---|
| 1 000 | ~228 Mo | ~684 Mo | ~1,56 Go | ~6,8 Go |
| 2 000 | ~457 Mo | ~1,37 Go | ~3,12 Go | ~13,6 Go |
| 5 000 | ~1,14 Go | ~3,42 Go | ~7,80 Go | ~34,0 Go |
| 10 000 | ~2,29 Go | ~6,87 Go | ~15,20 Go | ~68,0 Go |
4. Analyse de la table de Résumé (users_summaries)
Les résumés d'activité (users_summaries) sont calculés chaque matin à partir des données accumulées la veille. Ils offrent une vue consolidée beaucoup plus légère.
Description des colonnes de la table users_summaries
| Nom de la Colonne | Type / Format | Rôle et Explication Métier |
|---|---|---|
user_vid | UUID | Identifiant unique universel de l'utilisateur. |
user_id | Int | Identifiant unique interne de l'utilisateur. |
process_id | Int | Identifiant du processus d'exécution lié. |
version | String | Version de l'application cliente utilisée. |
process_first_update | DateTime | Date et heure du premier signal d'activité du processus. |
nb_telemetries | Int | Nombre total de paquets de télémétrie bruts reçus pour ce jour. |
session_is_active | Boolean (0/1) | Indique si cette session était la session active en cours d'utilisation. |
session_is_locked | Boolean (0/1) | Indique si la session utilisateur était verrouillée. |
nbrunningprocs_mean | Float | Moyenne du nombre de processus Alta Call s'exécutant simultanément. |
is_up | Boolean (0/1) | Indique si le système d'exploitation et l'application étaient pleinement opérationnels. |
date | Date | Jour concerné par le résumé d'activité. |
transfo_id | String | Identifiant de la transformation audio appliquée. |
transfo_mode | String | Mode de transformation vocale actif. |
transfo_params | JSON | Paramètres détaillés du traitement de voix appliqué. |
audio_params | JSON | Paramètres techniques de l'API audio. |
time_start | DateTime | Début de la période analysée dans la journée. |
time_end | DateTime | Fin de la période analysée dans la journée. |
duration | Float (sec) | Durée totale d'activité cumulée sur le canal audio. |
abtest_id | String | Identifiant du test A/B en cours s'il y a lieu. |
abtest_label_id | String | Label attribué à l'utilisateur dans le cadre du test A/B. |
device_capture_name | String | Nom complet du périphérique de capture audio (microphone). |
device_playback_name | String | Nom complet du périphérique de lecture audio (haut-parleur). |
device_capture_id | String | Identifiant technique du périphérique de capture. |
device_playback_id | String | Identifiant technique du périphérique de lecture. |
virtdev_out_appname | String | Nom de l'application ou softphone virtuel connecté à la sortie audio. |
audio_state | Enum | État du moteur audio (RUN, STP, CRA, FAI, LOD - voir nomenclature). |
audio_features | JSON | Données acoustiques extraites (ex: histogramme F0, frames vocales). |
stat_f0_median | Float | Médiane de la fréquence vocale fondamentale (hauteur de la voix). |
stat_f0_iqr | Float | Écart interquartile de la fréquence fondamentale (variabilité). |
stat_inputvoiceddb_median | Float | Niveau médian du signal de la voix d'entrée (en dB). |
stat_inputunvoicedlowdb_median | Float | Niveau médian du bruit résiduel / silence d'entrée. |
created_at | DateTime | Date de création de l'enregistrement de résumé. |
updated_at | DateTime | Date de dernière mise à jour de l'enregistrement. |
5. Volumétrie et Fréquence (users_summaries)
- Taille moyenne d'un résumé : ~1 Ko
- Fréquence moyenne : ~10 enregistrements par utilisateur par jour (selon le nombre de sessions ouvertes ou de changements d'états majeurs).
- Volume quotidien estimé par utilisateur : ~10 Ko
Stockage pour 700 utilisateurs (parc actuel)
- 1 jour : ~7 Mo
- 3 jours : ~21 Mo
- 7 jours : ~49 Mo
- 30 jours (1 mois) : ~210 Mo
Projection de stockage par paliers (users_summaries)
| Nb. Utilisateurs | 1 jour | 3 jours | 7 jours | 30 jours (Mo/Go) |
|---|---|---|---|---|
| 1 000 | ~10 Mo | ~30 Mo | ~70 Mo | ~300 Mo |
| 2 000 | ~20 Mo | ~60 Mo | ~140 Mo | ~600 Mo |
| 5 000 | ~50 Mo | ~150 Mo | ~350 Mo | ~1,5 Go |
| 10 000 | ~100 Mo | ~300 Mo | ~700 Mo | ~3,0 Go |
6. Recommandations d'Architecture pour la Rétention
[!TIP] Stratégie de partitionnement et de purge automatique (Retention Policy) Afin de résoudre de manière permanente la surcharge de la base de données signalée par Gandi, les recommandations d'ingénierie suivantes sont appliquées ou préconisées :
Purge des télémétries brutes (
telemetries) : Mettre en place un script de nettoyage quotidien pour supprimer toutes les lignes de la tabletelemetriesdatant de plus de 7 jours. Une semaine de télémétries brutes est largement suffisante pour analyser un crash récent ou investiguer un problème utilisateur ponctuel.Rétention des résumés (
users_summaries) : Étant donné que les résumés sont 23 fois plus légers par jour de stockage (10 Ko contre 234 Ko par utilisateur), nous pouvons conserver l'historique complet desusers_summariesindéfiniment ou sur une période de 2 ans pour des besoins de Business Intelligence (BI) et de rapports à long terme, sans risquer de surcharger l'infrastructure.Optimisation des index : Assurer que les index existants sur
telemetries(notamment sur les colonnescreated_atetuser_id) sont bien optimisés pour que la requête périodique de purge ne verrouille pas la table d'écriture lors de son exécution.