Revenir aux actualités des développeurs

Découvrir l’inconnu inconnu

Meta dispose d’un écosystème de produits qui sont utilisés chaque jour par des milliards d’utilisateur·ices que ce soit pour des contacts sociaux ou des interactions professionnelles. Ces milliards d’utilisateur·ices nous demandent également de fournir en permanence, et à un rythme accéléré, de nouvelles fonctionnalités et améliorations pour nos produits. En raison de l’importance de notre base d’utilisateur·ices, nous apportons chaque jour des milliers de modifications au code pour répondre à ces attentes.

La publication constante d’un si grand nombre d’améliorations de produits crée un risque de régression de l’état des applications, qui peut entraîner une dégradation de l’expérience utilisateur. Chez Meta, nous disposons d’une série d’outils de prévention sophistiqués pour empêcher la diffusion de modifications de produits défaillantes. Ces outils surveillent différents signaux relatifs aux produits et détectent les régressions avant la publication des applications. Les trois domaines couverts par ces signaux sont les performances, la fiabilité (fonctionnelle et systémique) et l’efficacité, qui sont regroupés sous l’appellation « PFE » (ou « PRE », de l’anglais Performance/Reliability/Efficiency) des produits. La prévention commence par différentes observations et traces analytiques recueillies pendant que les équipes de développement rédigent le code. En outre, les outils d’observabilité et de surveillance recueillent des données sur l’utilisation interne des produits dans les environnements de préproduction. Des outils d’assurance qualité manuels et automatisés testent les produits dans ces environnements.

Bien que ces mécanismes permettent d’évaluer la qualité des modifications de code avant leur mise en production et donc d’éviter l’impact sur les utilisateur·ices, il peut arriver que des modifications ayant un impact sur les utilisateur·ices soient mises en production et doivent donc être retravaillées et remises en production. Afin d’éviter qu’un problème n’affecte le plus grand nombre, nous utilisons divers mécanismes pour diffuser progressivement les modifications au public.

Lorsqu’il y a un écart par rapport à la fonctionnalité attendue par les utilisateur·ices, nous parlons de régression. Nous utilisons le terme « signal » lorsque les utilisateur·ices nous font savoir que quelque chose ne répond pas à leurs attentes. Nous recueillons les signaux de régression dès qu’il est systémiquement possible de le faire grâce aux données disponibles et au code instrumenté, puis nous nous efforçons de réduire l’impact sur les utilisateur·ices en déployant des correctifs. Lorsque nous n’obtenons pas de signal fort de nos outils, nous nous appuyons sur les signalements d’utilisateur·ices pour déterminer qu’une régression a eu lieu. Ces signalements proviennent de divers mécanismes, tels que les utilisateur·ices qui secouent leur téléphone pour signaler un problème lorsqu’ils ou elles se trouvent dans l’application au moment où il survient.

Pour répondre aux besoins de notre clientèle le plus rapidement possible, parfois même dans la journée, nous avons investi massivement dans un certain nombre de programmes et de systèmes fiables qui offrent une réactivité importante à grande échelle.

Les signaux peuvent provenir de nos utilisateur·ices public·ques (individus, entreprises, groupes, etc.) ou d’utilisateur·ices internes. Nous examinons attentivement les signaux envoyés par les utilisateur·ices internes afin d’éviter que des modifications indésirables ne se retrouvent en production. Notez que les signaux sont des agrégats. Par exemple, ils comprennent le nombre de bugs par million d’utilisateur·ices. Les signaux peuvent également provenir d’outils et de scénarios de tests automatisés, d’outils de développement (nous avertissons les équipes de développement des modifications susceptibles de provoquer des problèmes d’exécution), de journaux système et de nombreuses autres sources. Nous disposons également d’outils qui exploitent ces signaux afin d’identifier rapidement les causes et les solutions appropriées.

Dès qu’une régression est identifiée, nous trouvons rapidement les ingénieur·es compétent·es pour appliquer les correctifs et les diffuser. Selon la complexité de la régression, nous employons un certain nombre de méthodes pour identifier les ingénieur·es compétent·es, notamment en tirant parti de l’expertise de Meta en matière de machine learning. Compte tenu du fonctionnement du machine learning, il s’agit d’un processus continu. Nous lançons donc de nouvelles fonctionnalités et entraînons à nouveau nos modèles pour qu’ils puissent s’adapter aux modifications constantes.

Et il y a évidemment une finalité : nous passons de la détection des régressions à leur atténuation, leur prévention et leur endiguement durable. Ce faisant, nous maximisons la réactivité, le retour sur investissement et l’efficacité.

Dans la section suivante, nous verrons plus en détail comment établir avec certitude qu’une régression s’est produite et comment réagir.

Traduire les inconnus en connus et les quantifier

Lorsque nous parlons d’inconnus, nous faisons référence à un bug rencontré par un·e utilisateur·ice ou un système. Il se peut que nous apprenions l’existence d’un éventuel bug par le biais de plusieurs sources différentes.

  • Tests synthétiques du bon fonctionnement de nos applications et de produits spécifiques dans ces applications.
  • Utilisateur·ices internes qui effectuent des tests pour trouver des bugs. Il peut s’agir de nos équipes de test spécialisées ou d’une base d’utilisateur·ices plus large au sein de Meta.
  • Utilisateur·ices externes qui rencontrent un problème et utilisent la boîte de dialogue de signalement d’erreurs dans nos applications pour nous le signaler.

Ces bugs restent inconnus jusqu’à ce qu’ils soient signalés comme des incidents par les utilisateur·ices. Lorsque le nombre de ces rapports de bugs atteint un certain seuil, nous les considérons comme de vrais positifs, représentant un événement de régression : une modification du code a créé un nouveau bug et nous devons agir rapidement pour l’atténuer. Il existe deux types principaux de rapports :

  • « Inconnus connus » - situation dans laquelle le code instrumenté détecte et signale la régression et nous disposons d’un certain nombre d’outils qui aident à produire ce signal
  • “Inconnus inconnus” - situation dans laquelle la régression n’est pas détectée en interne et nous comptons sur l’utilisateur·ice pour la signaler

En outre, les régressions se répartissent en plusieurs catégories, selon qu’il s’agit de bugs de code, de spams ou équivalents ou d’une infraction de la politique de contenu. Nous nous concentrons sur la première catégorie, dans laquelle nous souhaitons aborder les problèmes d’expérience utilisateur liés au code. Mais comment y parvenir lorsque les utilisateur·ices signalent des milliers de problèmes ?

Créer des signaux et des insights

Pour gérer le volume important de rapports, nous générons des signaux spécifiques qui permettent de marquer les problèmes. Le premier type de signal est celui qui, avec des seuils correctement définis, nous informe de la survenance effective d’un incident ou d’une régression. Il convient de noter que plusieurs événements peuvent s’être produits en fonction du type de régression. Par exemple, une régression peut affecter plusieurs produits en raison d’une base de code commune. Nous recherchons ces points communs et les traitons comme un seul incident afin d’aligner les ressources de manière optimale. Le graphe ci-dessous illustre la manière dont nous pouvons constater visuellement l’écart par rapport à la ligne de tendance qui indique une régression.

Nous recueillons ensuite des signaux supplémentaires, dont certains indiquent le type de régression auquel nous pouvons être confrontés. Ces signaux donnent un aperçu des symptômes associés à la régression et sont générés par des algorithmes de machine learning adaptés à des produits Meta particuliers. Les algorithmes analysent les signalements d’utilisateur·ices afin de déterminer la cause de la régression et de désigner l’équipe d’ingénierie compétente qui pourra y remédier au mieux en déployant un correctif de code ou une autre mesure.

De nombreux autres signaux sont également générés sur la base des données de journaux collectées. Ces journaux de diagnostic peuvent être des journaux côté client ou côté serveur qui sont, avec le consentement de l’utilisateur·ice, collectés pour aider à déterminer la cause. Les applications intègrent des flux de consentement appropriés pour déterminer si ce type de données peut être recueilli en fonction des autorisations de l’utilisateur·ice. Nous tenons également compte de la longévité de ces données pour respecter les réglementations applicables.

La combinaison des signaux nous permet d’identifier la régression et de l’attribuer à l’équipe produit compétente afin de résoudre rapidement le problème et de rendre à l’utilisateur·ice l’expérience attendue.

Les résultats globaux permettent également de tirer des enseignements. Nous examinons les données afin de trouver les causes profondes communes et de déterminer si des modifications doivent être apportées pour éviter que les régressions ne se reproduisent. Cela permet de disposer d’une approche solide afin d’aborder les problèmes d’expérience utilisateur, car cela nous aide à réduire le plus possible la surface de régression au fil du temps.

Nos applications mobiles comprennent non seulement des chemins de navigation qui permettent à l’utilisateur·ice de signaler un problème, mais aussi la possibilité d’indiquer un problème en secouant l’appareil. Il est ainsi possible de recueillir des données en contexte par télétransmission. Ces données sont également enrichies par les signaux Black Box provenant de l’application. Black Box est comme une boîte noire d’avion qui capture automatiquement certains journaux (avec l’accord des utilisateur·ices) sur ce qui se passait sur l’application au moment où le bug a été signalé, afin que nous puissions mieux diagnostiquer le problème.

Toutes ces données télétransmises sont regroupées dans un ensemble de vues chronologiques afin d’aider les équipes d’ingénierie à déterminer la cause du problème. En raison de la rapidité de publication de nos applications et des changements dans les composants d’application côté serveur, il serait difficile de localiser les problèmes sans cette fonctionnalité. Toutes ces données télétransmises au fil du temps nous aident à détecter des schémas de régression et à éviter qu’ils ne se reproduisent.

S’adapter à des surfaces de produits réduites

Comme nous avons amélioré notre capacité à générer des signaux plus précis, nous sommes en mesure de traiter une plus grande partie de la surface de régression, dont certaines parties n’auraient pas été détectées auparavant. Une surface représente une offre particulière au sein d’un produit, comme le Fil d’actualités ou les Reels. Il s’agit d’un défi, car les produits ont non seulement de nombreuses fonctionnalités granulaires, mais de nouvelles sont introduites régulièrement. Ainsi, non seulement la surface de régression est grande, mais elle croît également avec le temps. Par conséquent, nos stratégies défensives et offensives doivent s’adapter en permanence.

Plusieurs conditions doivent être remplies pour pouvoir passer à l’échelle supérieure :

  1. Nous devons couvrir avec précision les surfaces de produits existantes et les classifier correctement
  2. Nous devons réduire la surface de régression des produits existants (lire : prévention)
  3. Nous devons étendre la couverture de nos algorithmes à de nouvelles surfaces de produits

Si les conditions ci-dessus ne sont pas remplies, nous risquons de disposer d’un système hypertrophié qui ne peut être géré en raison de sa taille, de sa complexité et de son manque de précision. Nos efforts visent donc à maintenir cet équilibre tout en gérant efficacement nos activités quotidiennes.

Dépasser les bugs

Tout en continuant à réduire la surface de régression (sans baisser la garde), nous nous concentrons davantage sur d’autres sujets importants : la prévention et l’utilisabilité.

La prévention porte sur les points suivants :

  1. Comment tirer des enseignements des régressions antérieures ?
  2. Quelles défenses devons-nous mettre en œuvre pour que ces régressions ne se reproduisent plus ?
  3. Comment s’assurer que la surface de régression continue à diminuer au fil du temps ?

Comme nous l’avons vu précédemment, nous regroupons les données des régressions antérieures pour en tirer des enseignements, qui peuvent donner lieu à :

  1. La mise en place de marqueurs dans notre code pour nous alerter lorsque nous sommes encore dans un environnement de préproduction, afin que nous puissions empêcher une modification indésirable de passer en production
  2. Une meilleure couverture des tests, à différents niveaux, pour détecter ces régressions
  3. La modification du produit à proprement parler pour répondre à ces problèmes

La prévention nous permet de continuer à déplacer les régressions plus en amont du cycle de développement et donc à réduire les coûts. Elle nous permet d’obtenir des signaux suffisamment riches plus tôt dans le processus de développement, en commençant dès la rédaction du code et les cycles de mise en préproduction. Cela permet non seulement d’améliorer l’expérience utilisateur, mais aussi de réduire les coûts de développement et de réorienter les ressources pour le développement de nouveaux produits.

L’amélioration de notre capacité à gérer les régressions de manière plus efficace nous permet de nous concentrer davantage sur les problèmes de confusion ou d’utilisabilité rencontrés par les utilisateur·ices. Il s’agit de préoccupations plus importantes, car elles visent à améliorer les produits plutôt qu’à les réparer. Au fil du temps, la proportion de problèmes d’utilisabilité par rapport aux régressions devrait augmenter et le nombre total de problèmes d’utilisabilité et de régressions devrait diminuer.

Finalement, cela se traduit par une expérience utilisateur qui s’améliore continuellement sur le plan de la fonctionnalité et de l’utilisabilité.

Cet article a été rédigé en collaboration avec Bijan Marjan, gestionnaire de programme technique chez Meta.