Journal du 02/01
Se plonger dans l’observabilité
Contexte
Suite à un échange avec un autre tech, où je mentionnais des erreurs de connexion à une DB de prod, sans qu’il y ait beaucoup de connexions utilisateurs en même temps, il me demande ce que j’utilise comme outil d’instrumentation !
Je n’ai rien de particulier en place, à pars Sentry pour suivre les logs d’erreurs des applications que je développe (en .NET).
Opérations
0. Analyse des outils existants
Datadog, Sentry, Grafana, etc… Je pars sur la solution la moins chère mais coûteuse en temps : Grafana.
1. Qu’est ce que je veux “observer” ?
- mes apps en .NET
- mon proxy Nginx
- mes base de données
Je pars donc sur l’installation de librairies pour configurer l’observabilités de ma web app et de ma console app en .NET. Facile pour la partie web, il me suffit d’exposer une URL HTTP, que Prometheus pourra contacter ensuite, pour récupérer les données exposées (attention par contre à bien gérer la sécurité). Pour l’instant, j’ai juste généré une URL random.
Pour la partie console, je ne veux pas la transformer en web app, juste pour exposer une URL. Il faut donc que j’envoi les données sur un collecteur. Il y a OpenTelemetry Collector qui existe et qu’il me faudrait installer sur un node de mon PaaS.
Je tente le coup, mais erreur, la version de l’OS de l’image Docker, n’est pas supporté par mon PaaS. Faudrait sûrement que je prévois de passer sur une version moins récente. À ce stade, ça me semble pas un bon “move”.
Peut-être que passer la console app en web app serait plus approprié, à voir plus tard, si ça consomme plus de RAM et si l’image prends beaucoup plus de place ! Je reste focus sur la partie web app, qui serait déjà une belle avancée.
2. Tentative d’installation de l’extension “Grafana + Prometheus”, disponible sur la marketplace du PaaS que j’utilise
C’est un échec pour l’instance Prometheus, qui renvoie une erreur 500. Je passe pas plus de temps dessus, autant partir sur une install de 0, en regardant la doc de Grafana.
3. Utilisation de la version gratuite de Grafana Cloud
Lors de l’installation, je choisi que je veux monitorer une install PG. Il me propose directement du code qui va installer l’outil Alloy, qui est une “station de monitoring” global pour permettre de récupérer plus d’infos que juste les métrics de l’exporter PG (qui est intégéré à Alloy).
Je lance le script d’installation qu’il m’a automatiquement généré sur mon instance de PG, mais c’est un echec, car il me faut avoir des droits sudo. Or, ce n’est pas possible sur mon PaaS, quand j’installe des applications via la marketplace.
Il faut que je pars sur un VPS et que j’installe Alloy dessus, pour le configurer correctement pour qu’il puisse ensuite se connecter à PG.
4. Installation d’un VPS basé sur debian
RàS par ici.
5. Configuration de Alloy sur le nouveau VPS
Je pars sur une installation de Alloy via le script proposé. Je fais un test de connection via l’interface de Grafana Cloud mais, ça ne fonctionne pas !
En cherchant dans les logs de Alloy:
1
journalctl -u alloy.service -n 100 --no-pager
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Jan 02 08:46:15 myhostname systemd[1]: Started alloy.service - Vendor-agnostic OpenTelemetry Collector distribution with programmable pipelines.
Jan 02 08:46:15 myhostname alloy[5850]: Error: /etc/alloy/config.alloy:75:1: expected identifier, got .
Jan 02 08:46:15 myhostname alloy[5850]: 74 | prometheus.relabel "integrations_postgres_exporter" {
Jan 02 08:46:15 myhostname alloy[5850]: 75 | .forward_to = [prometheus.remote_write.metrics_service.receiver]
Jan 02 08:46:15 myhostname alloy[5850]: | ^
Jan 02 08:46:15 myhostname alloy[5850]: 76 |
Jan 02 08:46:15 myhostname alloy[5850]: Error: /etc/alloy/config.alloy:82:1: expected identifier, got .
Jan 02 08:46:15 myhostname alloy[5850]: 81 |
Jan 02 08:46:15 myhostname alloy[5850]: 82 | .rule {
Jan 02 08:46:15 myhostname alloy[5850]: | ^
Jan 02 08:46:15 myhostname alloy[5850]: 83 | source_labels = ["__name__"]
Jan 02 08:46:15 myhostname alloy[5850]: interrupt received
Jan 02 08:46:15 myhostname alloy[5850]: Error: could not perform the initial load successfully
Jan 02 08:46:15 myhostname systemd[1]: alloy.service: Main process exited, code=exited, status=1/FAILURE
Jan 02 08:46:15 myhostname systemd[1]: alloy.service: Failed with result 'exit-code'.
Jan 02 08:46:15 myhostname systemd[1]: alloy.service: Scheduled restart job, restart counter is at 4.
Jan 02 08:46:15 myhostname systemd[1]: Stopped alloy.service - Vendor-agnostic OpenTelemetry Collector distribution with programmable pipelines.
Je comprends, à l’aide aussi d’un outil d’IA, que le problème est qu’il y a des ‘.’ dans la config, et qu’il ne faut pas. Je vire les points, et c’est un peu mieux !
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Jan 02 10:36:49 myhostname alloy[6154]: Error: /etc/alloy/config.alloy:62:1: Failed to build component: building component: cannot parse DSN: invalid connection protocol: observability
Jan 02 10:36:49 myhostname alloy[6154]: 61 |
Jan 02 10:36:49 myhostname alloy[6154]: 62 | prometheus.exporter.postgres "integrations_postgres_exporter" {
Jan 02 10:36:49 myhostname alloy[6154]: | _^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jan 02 10:36:49 myhostname alloy[6154]: 63 | | data_source_names = ["username:password@tcp(url:portNumber)/databaseName"]
Jan 02 10:36:49 myhostname alloy[6154]: 64 | | }
Jan 02 10:36:49 myhostname alloy[6154]: | |_^
Jan 02 10:36:49 myhostname alloy[6154]: 65 | discovery.relabel "integrations_postgres_exporter" {
Jan 02 10:36:49 myhostname alloy[6154]: interrupt received
Jan 02 10:36:49 myhostname alloy[6154]: Error: could not perform the initial load successfully
Jan 02 10:36:49 myhostname systemd[1]: alloy.service: Main process exited, code=exited, status=1/FAILURE
Jan 02 10:36:49 myhostname systemd[1]: alloy.service: Failed with result 'exit-code'.
Jan 02 10:36:50 myhostname systemd[1]: alloy.service: Scheduled restart job, restart counter is at 5.
Jan 02 10:36:50 myhostname systemd[1]: Stopped alloy.service - Vendor-agnostic OpenTelemetry Collector distribution with programmable pipelines.
Jan 02 10:36:50 myhostname systemd[1]: alloy.service: Start request repeated too quickly.
Jan 02 10:36:50 myhostname systemd[1]: alloy.service: Failed with result 'exit-code'.
Jan 02 10:36:50 myhostname systemd[1]: Failed to start alloy.service - Vendor-agnostic OpenTelemetry Collector distribution with programmable pipelines.
Il y a une erreur sur le format du DSN passé pour la connection : c’est pourtant Grafana Cloud qui me l’a proposé lorsque je lui indique que je voulais monitoré une instance de PG.
C’est la que je me dis, que ce serait bien de pouvoir historiser les modifications que je fais sur le serveur debian !
Je demande à mon IA favorite, si elle peut m’indiquer ce qui serait le mieux pour historiser mes commandes et mes modifications de fichiers, comme ceux de config, dans le cas présent.
GIT, auditd (Linux Audit Framework), Tlog / Sudo, termtosvg, asciinema2md, etckeeper
Je jette un oeil sur auditd, je tombe sur cette article, https://goteleport.com/blog/linux-audit/, et je me dis que c’est peut-être “too much” !
Via le blog de Stephane Robert, SRE connu, je découvre qu’il parle de etckeeper dans sa liste d’outils indispensable. Ce qui me convainc suffisamment pour partir sur cet outil !
6. Détour avec etckeeper
J’ai suivi à la lettre tout ce qui est indiqué par Stephane Robert, dans sont tutoriel sur etckeeper.
Je n’ai pas trouvé la config “PRESERVE_METADATA” dans le fichier de config, je l’ai ajouté manuellement, sait-on jamais.
7. Retour sur la configuration d’Alloy
Je dois modifier la chaîne de connexion de PG, d’après les logs d’erreurs.
J’ai du indiquer qu’il ne fallait pas utiliser de SSL, préfixer par, virer la notion TCP et ne pas utiliser l’alias DNS proposé par le PaaS.
En effet, mon node est dans le même environnement, la résolution de l’alias ne fonctionne que entre environnement ou via internet.
L’intégration des metrics fonctionne mais celles des logs ne fonctionne pas, mais c’est probablement lié au fait que j’utilise la v18, il doit y avoir un paramètre à changer. Ce n’est pas important à ce stade, je vais plutôt me focus sur ma WebApp en .NET à présent.
8. Intégration des metrics d’une Web App .NET 8
Dans ce cas, Grafana Cloud propose une intégration avec une librairie Nuget dédiée.
Je préfère ne pas dépendre, dans mon application .NET, de Grafana directement mais uniquement de la norme qu’apporte OpenTelemetry.
Dans ce cas, il faut que j’intègre un Collector dans mon environnement, qui pourra récupérer les données que j’expose sur l’endpoint custom metrics de ma web app ET aussi de ma console app (si déjà je mets en place un collector sur mon environnement).
J’installe OpenTelemetry Collector Contrib et non OpenTelemtry Collector (Core). Le premier contient des exportes customisés et la possibilité de récupérer des logs, ce que ne permet par la version Core.
Je ne peux pas installer directement sur un node de mon PaaS, car l’OS n’est pas supporté (comme déjà indiqué dans la section 1).
Je passe donc par l’installation de Docker Engine CE sur un noeud puis je déploie un nouveau conteneur basé sur OpenTelemetry Collector Contrib.
Mon instance de Grafana Cloud a décidé de planter.. Je ne peux plus configurer de nouvelles source de données.
Affaire à suivre, donc ?