Linux things 🐧

un blog sur les technologies des logiciels libres et autres digressions


VictoriaLogs

agrégation de logs avec VictoriaLogs

Sun, 09 Mar 2025 19:05:12 +0100
# victorialogs   # nomad   # auto-hebergement  

Introduction

Je suivais le streamer s17n qui s’essayait à Nomad et qui m’a fait remarquer que Nomad instanciait pour chaque conteneur un process nomad logmon. Ce processus sert à envoyer les logs du conteneur vers le serveur Nomad afin de pouvoir les consulter via l’interface web. Cela peut dépanner lorsqu’on essaye de lancer un nouveau service et qu’il bug mais ensuite c’est inutile.
Chaque process logmon prend plusieurs Mo en mémoire donc dans un environnement contraint auto-hébergé il vaut mieux le désactiver en ajoutant dans la section task du HCL

logs {
  disabled = true
}

Les logs sont bien sûr toujours accessibles via un docker logs -f ID mais ça reste manuel et lourdingue. Dans un environnement maîtrisé il convient d’avoir un outil de centralisation des logs ; d’ailleur en 2012 j’avais écris un article sur le sujet de la centralisation des logs avec Graylog, article orienté serveurs Windows à l’époque.

Sur mon NUC je suis très limité en ressources matériels, donc même si Graylog est excellent il n’est pas question que j’installe une stack Java dessus. Depuis 2012 il y a d’autres solutions comme Loki du projet Grafana mais j’ai préféré m’orienter vers la solution de VictoriaMetrics (qui développe une base de données Time series en Go du même nom) : VictoriaLogs.

VictoriaLogs

La doc présente ses avantages face à ElasticSearch et Loki en consommation de ressources. L’outil est compatible avec Grafana avec un plugin et propose également un dashboard. Il expose ses metrics vers Prometheus et possède une interface web pour faire des requêtes en LogsQL mais aussi une CLI. Surtout il est compatible avec un grand nombre d’outils pour recevoir les logs : Data ingestion.

Tout d’abord j’ai testé Promtail du projet Grafana, mais il va être abandonné au profit de Alloy. J’ai testé ce dernier rapidement mais je n’ai pas réussi à le configurer correctement. Ensuite un test avec Journald mais il a envoyé 3 tonnes de logs vers VL qui est monté en RAM et a fini killé par Linux…

Finalement j’ai réussi avec Telegraf en utilisant l’output HTTP. Avant de revenir à Telegraf voici la configuration Nomad pour déployer VL.

Nomad

victorialogs.hcl

job "victorialogs" {
  datacenters = ["hetzner"]
  type        = "service"
  group "home" {
    count = 1

    network {
      port "log" {
        to           = 9428 # container port the app runs on
        static       = 9428
        host_network = "tailscale"
      }
    }

    task "victorialogs" {
      driver = "docker"

      constraint {
        attribute = "${attr.unique.hostname}"
        value     = "nuc"
      }

      config {
        image = "victoriametrics/victoria-logs"
        args = [
          "-defaultMsgValue=msg"
#          "-journald.streamFields=_HOSTNAME,_SYSTEMD_UNIT,_PID",
#          "-journald.ignoreFields=MESSAGE_ID,INVOCATION_ID,USER_INVOCATION_ID,_BOOT_ID,_MACHINE_ID,_SYSTEMD_INVOCATION_ID,_STREAM_ID,_UID",
#          "-insert.maxLineSizeBytes=2MB",
        ]

        volumes = [
          "/data/volumes/victorialogs:/victoria-logs-data"
        ]
        ports = [
          "log"
        ]

      }

      resources {
        cpu    = 100
        memory = 1000
      }

      service {
        name     = "victorialogs"
        provider = "consul"
        port     = "log"

        check {
          type     = "http"
          name     = "app_health"
          path     = "/health"
          interval = "120s"
          timeout  = "60s"
        }

      }
    }
  }
}

J’ai laissé en commentaires dans args les options à ajouter pour supporter journald si vous souhaitez tester de votre côté.

Telegraf

J’ai installé Telegraf avec yay -S telegraf-bin (pour rappel mon NUC tourne avec Manjaro basé sur Arch). Puis j’ai ajouté ceci à la fin du fichier de configuration :

/etc/telegraf/telegraf.conf

...

[[inputs.tail]]
  files = ["/var/log/un_fichier_log.log"]
  from_beginning = false
  interval = "10s"
  pipe = false
  watch_method = "inotify"
  data_format = "value"
  data_type = "string"
  character_encoding = "utf-8"
  [inputs.tail.tags]
     metric_type = "logs"
     log_source = "un_fichier_log"

[[outputs.http]]
  url = "http://IP_TAILSCALE_NUC:9428/insert/jsonline?_msg_field=fields.message&_time_field=timestamp,_stream_fields=tags.log_source,tags.metric_type"
  data_format = "json"
  namepass = ["docker_log"]
  use_batch_format = false

[[inputs.docker_log]]
  [inputs.docker_log.tags]
     metric_type = "logs"
     log_source = "telegraf"

[[processors.rename]]
  namepass = ["docker_log"]
  [[processors.rename.replace]]
    field = "message"
    dest = "msg"

Attention Telegraf doit avoir les droits d’accès à la socket Docker. Pour cela j’ai ajouté le user telegraf dans /etc/group docker.

sudo systemctl enable --now telegraf et c’est parti je reçois bien les logs des conteneurs sur le NUC.

La section [[inputs.tail]] montre comment pousser un fichier de log classique.

VictoriaLogs UI

La web UI est accessible ici http://IP_TAILSCALE_NUC:9428/. On regroupe les logs en utilisant la roue denté :

victorialogs_1

On affine par le nom du job et on affiche le contenu de fields.msg qui contient le log. Dans l’interface le champ Log query contient par défaut * ce qui affiche tous les logs

victorialogs_2

On peut remplacer l’étoile par une recherche précise par exemple afficher uniquement le log d’un service :
tags.com.hashicorp.nomad.job_name:"nom_service"

ou uniquement les logs d’un service et contenant error

tags.com.hashicorp.nomad.job_name:"nom_service" AND fields.msg:"error"

ou les logs de tous les services contenant “error”

fields.msg:"error"

CLI

VL propose un outil en ligne de commande vlogscli. On peut le télécharger dans les releases du projet. On le lance :

./vlogscli-prod -datasource.url='http://IP_TAILSCALE_NUC:9428/select/logsql/query'

Ensuite on peut filtrer avec les mêmes commandes qu’en web

;> fields.msg:"level=error";
;> tags.com.hashicorp.nomad.job_name:"shiori" AND fields.msg:"error";

Enfin on peut avoir un flux en temps réel de la requête en préfixant par \tail

;> \tail fields.msg:"level=error";

Ubuntu serveur

Sur le serveur front (VM hébergé chez Hetzner) Ubuntu 24 propose un snap telegraf, mais il sert à rien car il ne peut pas accéder à la socket docker. J’installe alors de manière classique en ajoutant les dépôts InfuxData.
Après avoir modifé la config comme sur le NUC et ajouté le user telegraf dans le groupe Docker, le service pousse bien les logs. On peut consulter les logs des conteneurs du serveur en filtrant comme ceci :

tags.host:"front"

ou en CLI

;> \tail tags.host:"front" AND fields.msg:"error";

Conclusion

C’était un tour rapide de VictoriaLogs, j’y reviendrais peut être.