log.warn("Ce journal vous coûtera") Sur l'optimisation du coût du journal

Dec 05 2022
Vous souvenez-vous du moment où vous avez appris que les logs ne sont pas gratuits ? C'est certain. C'était juste après une étape importante que notre équipe a franchie - nous venons de lancer un nouveau service évolutif brillant qui est sur le point de remplacer un service hérité à débit extrêmement élevé et extrêmement inefficace.
un autre type de journaux coûteux par @usefulcollective sur unsplash

Vous souvenez-vous du moment où vous avez appris que les logs ne sont pas gratuits ? C'est certain. C'était juste après une étape importante que notre équipe a franchie - nous venons de lancer un nouveau service évolutif brillant qui est sur le point de remplacer un service hérité à débit extrêmement élevé et extrêmement inefficace. Nous venons de réduire la taille de la flotte d'environ 300 instances EC2 à environ 30 pods sur un cluster kubernetees multi-locataires. Atteindre une meilleure fiabilité, réduire la latence de traitement et réduire les coûts d'un ordre de grandeur.

C'est alors que nous avons involontairement fait monter en flèche la facture de notre fournisseur de journaux. Nous enregistrions de gros volumes de données à haut débit. Nous avons presque effacé toutes les économies de coûts opérationnels.

C'est alors que j'ai appris à quel point ces bûches que j'utilise quotidiennement et sans trop réfléchir peuvent coûter cher.

Dans cet article, je couvrirai les mesures que nous avons prises pour réduire les coûts liés à la journalisation générée par nos systèmes et les pratiques générales pour une journalisation efficace.

Toute optimisation commence par la mesure

Nous ne pouvons pas optimiser l'utilisation des journaux si nous ne savons pas combien nous utilisons, ce que nous enregistrons et pourquoi.

À l'époque, nous utilisions un fournisseur tiers pour les journaux - une plate-forme ELK gérée si vous pouvez.

Nous avons donc commencé par mesurer la quantité de logs que nous indexons, et qui sont « les principaux contrevenants », c'est-à-dire quels sont les logs qui sont le plus envoyés.

Les deux choses intéressantes qui peuvent vous aider ici (lors de l'utilisation de Kibana, mais qui peuvent probablement être appliquées n'importe où) sont de mesurer la taille du journal :

Et l'onglet modèle qui affiche les modèles de journal les plus courants :

Comme il s'agissait d'un tout nouveau système, nous n'avons encore jamais utilisé les journaux générés par ce système - leur valeur était donc assez difficile d'accès - alors que le coût était évident. Cela nous a amenés à réfléchir sérieusement au système dans son ensemble.

Comprendre l'utilisation

A quoi serviront vos logs ?

  • Seront-ils utilisés uniquement lors des arrêts pour comprendre ce qui se passe en production ?
  • Les journaux sont-ils utilisés à des fins d'audit pour comprendre un parcours de demande ? Seront-ils utilisés pour déboguer des cas d'utilisation métier ?
  • Ces journaux sont-ils utiles après une heure ? Après une journée ?
  • Le système sert-il les demandes de longue durée ? Ou les demandes sont-elles temporelles ?
  • Les journaux font-ils partie d'une exigence réglementaire ?
  • Quel est le coût d'une panne ?

Passons en revue quelques exemples :

Disons que vous avez un système où chaque demande est critique, chaque demande échouée affectera négativement les activités de l'entreprise. Le meilleur exemple d'un tel système est un site de commerce électronique - chaque commande qui n'a pas été passée est une perte de revenus ! Nous voudrions probablement enregistrer chaque étape du parcours de cette demande pour savoir ce qui s'est passé, ce qui a échoué, et peut-être être en mesure d'utiliser ces journaux pour répondre à des questions telles que "pourquoi la commande passe par le flux X et non par le flux Y".

Dans un tel cas d'utilisation, les journaux sont très précieux et doivent être conservés pendant une période assez longue - probablement 7 à 14 jours.

Une bonne règle empirique pour votre période de conservation des journaux requise - le temps général nécessaire pour prendre en charge les demandes de renseignements et les demandes vous sont renvoyées.

Dans notre cas cependant, les demandes concernaient un système de support, aucune corrélation étroite avec les revenus, chaque demande est de très courte durée et temporelle, et le coût de la panne est assez faible.

De plus - le système avait un très faible nombre de flux de traitement, donc la probabilité qu'un problème n'affecte qu'un sous-ensemble spécifique de demandes est très faible - c'est-à-dire qu'en cas de problème, ce sera probablement une sorte de panne totale ou rien .

De plus, aucun audit au niveau de la demande n'est nécessaire, personne ne nous demandera jamais pourquoi la demande X s'est comportée comme elle l'a fait.

Cette analyse nous a amené aux conclusions suivantes :

  • La requête unique n'a aucun sens dans notre système
  • À part les échecs de traitement, nous n'avons trouvé aucune raison de vérifier les journaux du système (nous avons obtenu son comportement et son SLI couverts par la surveillance des métriques)
  • Les données sont tellement temporelles qu'il n'y a aucune chance que quelqu'un se soucie des demandes quelques heures après leur traitement

Utilisation du temps de rétention correct

Nous avons commencé par une solution rapide - réduire la conservation de nos journaux à une période minimale d'un jour, cela nous a permis de réduire rapidement les coûts, avant de résoudre le problème sous-jacent.

Mais il y a aussi une leçon à tirer ici : les niveaux de rétention par défaut de 7 à 14 jours que la plupart des entreprises utilisent sont des valeurs par défaut aléatoires et peuvent avoir un impact compris entre 10 et 90 % sur les coûts.

Pensez combien de temps vos journaux restent précieux dans vos cas d'utilisation ? Ajustez la rétention à la valeur minimale.

Étendez et réduisez dynamiquement les niveaux de rétention nécessaires au fur et à mesure que vos besoins évoluent : la publication de fonctionnalités importantes est une excellente cause pour des rétentions plus longues, tandis que de longues fenêtres de maintenance peuvent être de bonnes chances de réduire la rétention.

Cela a une grande différence si vous avez 5 To de journaux quotidiens que vous stockez pendant une journée ou un mois.

Journaux significatifs et non utilisation des journaux comme métriques

Il est assez courant de voir des messages de journal tels que "Serving request" . À moins que vous n'enregistriez ce qu'est cette requête, et qu'il y ait une vraie signification précieuse derrière cette requête — c'est une métrique , cela peut être remplacé par un simple compteur !

Ces journaux n'ont aucun sens :

Cela aurait dû être une métrique

Donc, n'utilisez pas log pour les métriques, utilisez les métriques pour les métriques , c'est moins cher et beaucoup plus efficace.

En ce qui concerne les journaux - enregistrez des données significatives, si cette demande est précieuse, enregistrez ce qu'est cette demande, comment la trouver, ce qui la rend significative et ce sont des données ! Quelque chose dans la lignée de :

Compte Premium de service <nom du compte>, demande <id>, <contexte supplémentaire sur le flux et la demande>

Depuis que nous avons créé un service à haut débit, nous avons supprimé des centaines de Go de « demandes de service » et de « processus terminé x » , réduisant ainsi nos coûts de journalisation d'environ 5 à 10 %.

De plus, cela a effacé nos journaux de service encombrés et a rendu la recherche de problèmes beaucoup plus facile.

Journalisation basée sur la gravité

Nous définissons généralement le niveau de journalisation minimum en production pour INFO , de cette façon nous excluons les lignes de débogage que nous avons utilisées pour développer le système, sans perdre le contexte de ce qui se passe.

Nous avons décidé d'aller plus haut et de mettre le niveau de journalisation sur WARNING , et plus tard sur ERROR .

Nous avons appris que nous n'avons pas besoin du contexte et que nous ne nous soucions de la journalisation que lorsque le système tombe en panne et s'écrase.

Cela a réduit notre utilisation des journaux d'environ 90 % supplémentaires, sans aucune perte réelle d'utilisabilité.

Nous avons ajouté un indicateur de configuration dynamique qui permet d'abaisser les niveaux de journalisation à la demande dans tous les cas.

Journalisation dynamique

Lorsque nous avons commencé à réduire les journaux, il est devenu clair que l'exécution manuelle des choses dans les environnements de production et de préproduction devenait un peu plus difficile, car nos journaux étaient presque toujours vides.

Il est devenu évident que même si nous utilisons rarement les journaux, nous avons toujours besoin d'indications sur ce qui se passe dans nos systèmes. nous avons besoin de * quelques * journaux.

Nous avons intégré un mécanisme qui décide dynamiquement s'il faut enregistrer les journaux d'une requête en fonction des propriétés de la requête. Par exemple:

  • Pour les tests et l'exploration, nous avons activé la journalisation pour tout identifiant de demande commençant par test. Ou envoyé depuis certains de nos comptes de test.
  • Nous avons activé la journalisation complète pour les requêtes de test synthétiques par propriétés de la requête testée, nous aurons donc un groupe de contrôle constant.
  • Pour l'intégration des produits/clients, nous avons activé les journaux lors des premières étapes de l'intégration par préfixes de nom de client.

Cela a permis de réduire nos coûts, tout en permettant une meilleure convivialité de notre système.

journalisation d'un flux de décision de message

Niveau de trace Échantillonnage

Généralement, je ne suis pas fan des solutions d'échantillonnage. L'échantillonnage pour ceux d'entre vous qui ne sont pas familiers - utilise une fonctionnalité uniquement sur un sous-ensemble du trafic ou des cas d'utilisation - par exemple, activer les journaux pour seulement 10 % du trafic, ou uniquement le trafic provenant d'un espace IP ou d'une région spécifique.

Dans notre cas, nous pouvons facilement réduire les coûts en enregistrant uniquement sur un sous-ensemble de pods dans notre déploiement, ou en enregistrant uniquement un petit % des requêtes.

C'est un cas d'utilisation assez courant pour réduire les coûts opérationnels. Dans notre cas cependant, après toutes les optimisations effectuées, nous n'avons vu aucune raison d'aller dans cette direction, mais si vous choisissez de le faire, n'oubliez pas de consigner l'intégralité du journal des demandes et d'échantillonner chaque ligne de journal séparément - vous obtenir des flux interrompus et aucune valeur réelle de cette façon.

Limitation des "tempêtes d'erreurs", coûts de journalisation prévisibles

Étant donné que notre système enregistre désormais uniquement les messages de journal avec la gravité ERROR , nous avons découvert un phénomène intéressant, que nous avons surnommé "tempête d'erreurs".

La tempête d'erreurs est ce qui se passe dans votre système lorsqu'il atteint un état erroné, une panne. Lorsque cela se produit, nos journaux sont remplis d'une vague massive de journaux d'erreurs répétitifs, enregistrant la même erreur encore et encore. Et à grande échelle, cela a très peu de valeur.

Nous avons implémenté un petit verrou en mémoire (un mécanisme qui "verrouille" dans un certain état), qui se verrouille lorsque le même message de journal est enregistré plus de X fois et arrête la tempête d'erreurs.

Cela nous a donné suffisamment d'informations sur l'erreur et a arrêté le flot d'erreurs, réduisant ainsi les coûts supplémentaires pendant les pannes, et plus important encore, rendant nos coûts de journalisation prévisibles pendant les pannes.

Il est également important de mentionner ici que nous avions une excellente couverture des métriques, nous n'avions donc besoin de ces journaux d'erreurs que pour le contexte et des informations supplémentaires sur l'erreur en question.

Limiter le verrouillage des fournisseurs et changer de fournisseur

Nous avons pu réduire d'environ 50 % le coût global en changeant de fournisseur de journalisation.

Essentiellement, nous payions pour un OpenSearch géré glorifié (ElasticSearch à l'époque), nous n'utilisions pas beaucoup des capacités avancées des outils.

La plupart de nos visualisations étaient basées sur des métriques, et celle que nous avions sur les journaux était une visualisation de base de Kibana , qui fonctionnera sur toute autre plate-forme prenant en charge Kibana.

Ainsi, grâce à un processus de migration pas trop compliqué, nous avons pu économiser des sommes importantes sur les coûts de journalisation globaux, certains fournisseurs ont des processus de migration pour faciliter le déplacement de leurs concurrents. Utilise le.

Si vous ne tirez pas parti des fonctionnalités avancées de la plate-forme de journalisation de votre choix et que votre pile de surveillance n'est pas exclusivement ou principalement basée sur les journaux, n'ayez pas peur de faire du shopping auprès des fournisseurs et de vous lancer dans des guerres de prix.

N'ayez pas peur de SSH et Kubectl

Dans certains (généralement des systèmes sans état), vous n'avez pas nécessairement besoin d'avoir des journaux centralisés. Si vos exigences de sécurité le permettent, vous pouvez vous connecter par défaut à une machine à l'aide de l'outil de votre choix, et suivre les fichiers journaux et stdout . Je sais que c'est barbare, et très 1998. Mais ça marche, et c'est pas cher.

Dans nos systèmes, même si les journaux ELK étaient de gravité Erreur, tous les journaux INFO étaient toujours disponibles dans un fichier journal rotatif sur l'instance, donc en accédant à l'instance, nous pouvions obtenir beaucoup de contexte si nécessaire.

Étant donné que nous avons réalisé des réductions de coûts aussi incroyables grâce aux étapes mentionnées ci-dessus, nous ne sommes pas vraiment allés aussi loin, mais nous avons fait un petit POC d'utilisation des journaux de cette manière, et ce n'était pas trop horrible dans notre cas d'utilisation spécifique.

Dernières pensées

Vous pensez peut-être que nous sommes allés trop loin ici et que nous nous sommes sur-conçus ici. Vous aurez probablement raison. Mais:

Tout d'abord, nous avons utilisé cet effort de réduction des coûts comme un levier supplémentaire lors des négociations de prix avec le fournisseur de journalisation, il avait donc une valeur supplémentaire et nous pouvons réellement y mettre une étiquette de prix.

Deuxièmement, à part le mécanisme de « verrouillage », la plupart de ces efforts étaient vraiment des fruits à portée de main avec un effort de développement minimal nécessaire.

Troisièmement, nous avons utilisé cet effort comme une opportunité d'apprentissage pour certains des développeurs juniors de l'équipe, en nous concentrant sur les difficultés de faire quoi que ce soit à grande échelle - et en "entraînant" leur esprit à penser - à l'échelle de tout ce sur quoi ils mettent la main.

En fin de compte, le coût des journaux ne devrait pas être le premier élément de votre ordre du jour, mais il fait partie de votre posture d'observabilité et peut représenter une dépense énorme.

Cela ne devrait pas être le cas.

Comme toujours, les pensées et les commentaires sont les bienvenus sur Twitter à @cherkaskyb