Formules de métriques dans l’éditeur de graphiques
Démo par @wrn14897
Les graphiques de métriques savent désormais faire de l’arithmétique. Jusqu’à cette semaine, deux métriques sur un même graphique n’étaient que deux courbes, sans aucun moyen de les combiner.
Les séries d’un graphique sont étiquetées
A, B, C, et ainsi de suite. Une ligne de formule vous permet de construire une série dérivée à partir de ces références. A / (A + B + C) * 100 vous donne un taux d’utilisation de la file d’attente. Vous pouvez calculer la saturation à partir des compteurs de messages reçus et envoyés d’un collector de la même manière.
Vous pouvez ajouter plusieurs formules à un même graphique, choisir d’afficher les séries opérandes en plus du résultat ou seulement la formule, et mélanger des séries provenant de métriques différentes. Les alertes fonctionnent également sur les formules.
Le calcul arithmétique lui-même s’effectue dans ClickHouse. Chaque formule est compilée depuis un AST validé vers la requête de métrique composée, de sorte que ClickHouse la calcule au sein d’une seule requête, plutôt que l’application ne joigne les résultats a posteriori. Chaque série devient une CTE, et la formule est évaluée sur le résultat joint.
Les opérandes manquants comptent pour zéro : un groupe sans erreurs affiche donc 0 % plutôt que N/A. Chaque dénominateur de division est encapsulé dans nullif(..., 0), si bien qu’un dénominateur nul ou manquant se traduit par un trou dans la courbe plutôt que par un zéro ou une erreur.
Un correctif ultérieur a déplacé HAVING, ORDER BY et LIMIT sur la jointure finale, au lieu de les appliquer à chaque branche UNION. Auparavant, ces clauses s’exécutaient dans un scope où les noms de sortie visibles par l’utilisateur n’existaient pas. Chaque série était donc filtrée indépendamment avant la jointure, tandis que l’ordre final des lignes restait non déterministe.
Le champ de saisie accepte les références par lettre et l’arithmétique simple, mais pas du SQL arbitraire pour l’instant. Les références de séries inconnues, les expressions mal formées et les expressions constituées uniquement de constantes sont signalées en direct sous le champ. La même validation bloque l’enregistrement et l’exécution, de sorte qu’une expression invalide n’atteint jamais ClickHouse.
Les operators bitwise et les fonctions ClickHouse ne sont pas encore pris en charge. Il n’y a pas de raison profonde à cela : c’est simplement là que s’est arrêtée la première version, et une prise en charge plus large des expressions fait partie de ce que nous pourrions ajouter ensuite.
Deux points évoqués lors des discussions n’ont pas été implémentés. Les formules ne peuvent pas référencer d’autres formules : vous ne pouvez donc pas chaîner F1 dans F2. Des contrôles d’affichage/masquage par série seraient par ailleurs plus utiles que le toggle global des opérandes à l’échelle du graphique. Masquer A et B tout en les conservant dans la formule est le cas d’usage que les utilisateurs recherchent réellement.
Une question légitime a également été soulevée : jusqu’où peut-on pousser les jointures avant qu’elles ne cessent d’être utiles ? Quiconque a utilisé la division dans PromQL connaît le mode de défaillance : une jointure qui ne correspond pas comme prévu et ne renvoie silencieusement aucune donnée.
PR associées : #2908 rendu des formules dans la requête de métrique composée, #2909 UI de l’éditeur de graphiques pour les formules de métriques, #2946 application de HAVING/ORDER BY/LIMIT à la jointure de métrique composée, et non aux branches par série, #2952 prise en charge des formules sur l’ensemble des surfaces d’API, #2953 prise en charge des formules pour les sources d’événements de logs et de traces
Variables de dashboard dépendantes et macros
Démo par @pulpdrew
Deux demandes formulées lors de la démo de la semaine dernière sont désormais disponibles.
Les définitions de filtres peuvent désormais référencer d’autres variables dans leur clause
WHERE : un menu déroulant peut ainsi restreindre le périmètre d’un autre. Un filtre de sévérité qui référence le filtre sur le nom de service démarre vide. Une fois un service sélectionné, il ne propose plus que les sévérités existant pour ce service.
Les options restent interrogées même lorsqu’une variable référencée n’a aucune sélection. Utilisez $__filters ou $__conditionalAll si vous souhaitez que des valeurs soient renseignées dans cet état. Un simple <expression> IN ($var) ne renvoie rien tant que $var n’a pas de sélection. Une infobulle en explique désormais la raison, au lieu de vous laisser face à une liste vide sans explication. L’autocomplétion des variables et des macros fonctionne également dans le champ WHERE de la fenêtre modale de filtre.
Vous pouvez créer des dépendances circulaires, mais elles sont sans réelle conséquence, car les variables sont remplacées par leurs sélections plutôt qu’évaluées de manière récursive.
Les macros développent désormais les variables passées en arguments : $__timeFilter($TimeColumn) fonctionne donc. Choisissez une colonne timestamp depuis une variable, et la macro se développe en un filtre temporel complet autour de celle-ci. Les variables passées à $__filter et $__conditionalAll doivent désormais utiliser la forme $var. Un simple var était auparavant accepté, une tolérance qui semait surtout la confusion.
L’API externe v2 comme le MCP Server comprennent les variables, ce qui vaut donc aussi pour Terraform. Un agent peut construire un dashboard avec des filtres de variable et de diffusion (broadcast), des menus déroulants dépendants et des tiles qui référencent ces variables directement ou via une macro. Les outils de création, d’enregistrement et de patch signalent les cas où des variables sont utilisées à un endroit où elles ne fonctionneront pas.
Les outils de tiles de requête acceptent également des valeurs de variables : un agent peut ainsi vérifier ses propres substitutions avant de livrer le dashboard.
PR associées : #2923 prise en charge des requêtes de valeurs de variables dépendantes, #2937 prise en charge des macros imbriquées et des références de variables dans les macros, #2944 ajout des dashboard variables à l’API externe, #2951 prise en charge des dashboard variables dans le MCP Server
Schémas d’outils MCP acceptés par les clients stricts
Démo par @teeohhem
Un client nous a signalé qu’il ne parvenait pas du tout à utiliser notre MCP Server avec son agent.
Certains frameworks d’agents listent les outils disponibles et valident chaque schéma d’entrée avant de les transmettre au provider de modèles. Si un seul schéma est invalide, le framework rejette la liste d’outils dans son intégralité plutôt que le seul outil fautif, donnant l’impression que le serveur est totalement hors service.
Bon nombre de harnais d’agents se montrent plus tolérants, mais pas tous. Pour les clients concernés, détacher le serveur était le seul moyen de refaire fonctionner l’agent.
Un test vérifie désormais que le schéma d’entrée de chaque outil est un JSON Schema draft 2020-12 valide, afin qu’un nouvel outil ne puisse plus casser les clients stricts de la même manière.
PR associées : #2925 émission de schémas d’entrée d’outils conformes au draft 2020-12, #2971 déclaration du niveau de quantile en tant qu’enum de chaînes
Personal API access keys pouvant faire l’objet d’une rotation
Démonstration par @teeohhem
Les Personal API access keys peuvent désormais faire l’objet d’une rotation depuis Team Settings → API & Agents.
La key sert de bearer token pour l’API externe v2 et le MCP server. Auparavant, elle était générée une seule fois à la création de l’account et ne pouvait plus jamais être modifiée : en cas de fuite, il fallait supprimer l’utilisateur.
La rotation est immédiate, sans période de grâce, et votre session de navigateur reste connectée. Attention toutefois : la key est rattachée à l’account, et non à une équipe. Si vous appartenez à plusieurs équipes, tout ce qui utilise cette key dans l’ensemble de ces équipes doit être mis à jour.
Enterprise affiche un avertissement à ce sujet. Sur une installation open source à équipe unique, il n’y a rien à signaler : l’avertissement n’y apparaît donc pas.
Deux limitations ont été posées délibérément. La route
PATCH /me/accessKey n’accepte aucun identifiant d’utilisateur, car l’ID provient de la session. Elle ne peut donc effectuer la rotation que de la key du caller lui-même.
Cette route n’est pas non plus exposée via l’API externe v2 authentifiée par bearer. Une key divulguée permet déjà de se lire elle-même à cet endroit ; l’autoriser également à effectuer une rotation permettrait à un tiers de priver l’Owner de l’accès à son propre outillage.
PR associées : #2926 rendre les Personal API access keys rotatives
Clés alphabétiques dans l’onglet Column Values
Démonstration par @teeohhem
Les clés de l’onglet Column Values du panneau latéral des lignes sont désormais triées par ordre alphabétique à chaque niveau d’imbrication, aussi bien pour les logs que pour les traces.
L’arborescence JSON affichait auparavant les clés dans l’ordre de stockage physique de ClickHouse, qui paraissait tout simplement aléatoire. Une colonne
Map comme ProfileEvents, qui compte 125 clés, n’obéissait à aucun ordre repérable : en trouver une supposait donc de parcourir toute la liste.
L’aspect le moins évident du problème tenait au fait que chaque niveau est limité à 50 lignes et que ce découpage s’effectuait avant le tri. Les 50 clés affichées formaient donc un sous-ensemble arbitraire, « Expand 75 more properties » étant le seul moyen d’accéder aux autres.
Le tri intervient désormais dans TreeNode, avant le découpage de la liste. Il tient compte des valeurs numériques : key2 précède ainsi key10.
PR associées : #2943 tri alphabétique des clés dans la visionneuse JSON
Storybook comme design system navigable
Démo par @elizabetdev
Storybook est désormais un design system navigable plutôt qu’un bac à sable de composants. La barre latérale suit l’ordre Guidelines → Brand → Icons → Design Tokens → Components.
La section Guidelines affiche directement le Markdown de
agent_docs : le style de code, la gestion des thèmes, la mise en page et les couleurs de visualisation de données sont ainsi réunis au même endroit. Cela s’adresse autant aux agents qu’aux personnes. Orienter un agent vers le document que lit un nouveau membre de l’équipe permet de garder les composants générés cohérents avec l’existant.
Les sections Brand et Icons contiennent les logos HyperDX et ClickStack ainsi que nos icônes personnalisées, dont IconAiNotebook. Vous pouvez copier ou télécharger les SVG, avec des indications sur les cas où utiliser une icône en trait compatible Tabler et ceux où utiliser une marque.
Ce travail a commencé par les icônes, car les présentations utilisaient tout ce qui s’en approchait de près ou de loin. Si vous avez besoin d’une marque pour une présentation, prenez-la ici.
Une barre d’outils Brand permet de basculer entre HyperDX et ClickStack, tandis qu’une barre d’outils Theme couvre les thèmes clair et sombre. Les nouveaux composants peuvent être vérifiés dans toutes les combinaisons avant leur livraison. Les stories de composants jusque-là non catégorisées sont maintenant regroupées sous Components/, avec les composants de cartes de graphiques exposés à leurs côtés.
Deux constats sont apparus en chemin. Les variables CSS de police de Storybook sont désormais définies sur <html>, comme dans l’application : le texte courant et les popovers portalisés ne s’affichent donc plus en Times.
Par ailleurs, nous n’utilisons pas le jeu d’icônes Tabler de façon cohérente. PromQL mériterait sans doute sa propre icône, et les metrics et les traces sont actuellement représentées par des icônes différentes selon les endroits. Storybook constitue désormais la référence à suivre.
Lancez-le en local avec yarn workspace @hyperdx/app storybook.
PR associées : #2935 transformer Storybook en design system navigable
Palette catégorielle sur les graphiques histogramme
Démonstration par @elizabetdev
Les graphiques histogramme, dont Request Latency sur le dashboard Services, utilisaient la couleur
#50FA7B codée en dur. Ce vert néon ne fait pas partie de la palette des graphiques et n’offrait pas un contraste suffisant. L’infobulle affichait elle aussi « Number of events » dans cette même couleur.
Le graphique résout désormais chart-blue via getColorFromCSSToken. Son infobulle s’appuie sur les composants partagés ChartTooltipContainer et ChartTooltipItem, ce qui l’aligne sur les graphiques en courbes, en barres et en secteurs.
Le lien View events de l’infobulle a disparu. generateSearchUrl était bien accepté par l’histogramme interne et par l’infobulle, mais n’était jamais transmis depuis DBHistogramChart : le lien n’apparaissait donc jamais en production.
Le seul caller ne dispose d’aucun builder d’URL de recherche pour un bucket de durée, et filtrer les événements sur une plage de latency relève d’une feature à part entière, pas d’un simple correctif de câblage.
Une petite finition, mais tout compte.
PR associées : #2949 use categorical palette on histogram graphiques