
Les fichiers de logs générés par votre serveur Web contiennent toutes les statistiques de fréquentation de votre site, encore faut-il pouvoir les lire. Que vous hébergiez un blog personnel, des services auto-hébergés ou un serveur web avec un portail d’entreprise, le fichier access.log accumule chaque jour des centaines, voire des milliers de lignes que personne ne consulte. GoAccess transforme ce flux brut en un tableau de bord lisible, en quelques secondes et sans base de données.
Vous avez envie d’en savoir plus ? Dans cet article, je vous propose de découvrir GoAccess et de l’installer sur une machine Debian (ou Ubuntu). Nous verrons comment l’utiliser en ligne de commande, en allant jusqu’à générer un rapport HTML mettant en évidence les logs de façon propre et lisible.
GoAccess en bref
Pour analyser les logs d’un serveur web avec GoAccess, installez le paquet, puis exécutez la commande suivante : goaccess /var/log/apache2/access.log –log-format=COMBINED. Vous n’avez qu’à adapter le chemin vers le fichier de log. Le tableau de bord s’affiche directement dans le terminal. Par la suite, ajoutez -o rapport.html pour produire un rapport HTML consultable dans un navigateur.
Note : GoAccess travaille uniquement à partir des journaux du serveur. Aucun script JavaScript ni cookie n’est déposé sur l’appareil de vos visiteurs.
Qu’est-ce que GoAccess ?
GoAccess est un analyseur de logs web développé depuis 2010 par Gerardo Orellana. Écrit en C, il s’appuie sur la bibliothèque ncurses et c’est un outil open source particulièrement léger et efficace. Il est publié sous licence MIT et est entièrement gratuit (pas d’édition commerciale).
Son principe est simple : il lit un fichier de journalisation, en extrait les champs utiles, puis restitue les statistiques sous la forme d’un tableau de bord avec différentes sections. Vous y retrouvez les visiteurs uniques par date, les pages les plus demandées, les erreurs 404, les hôtes, les systèmes d’exploitation, les navigateurs, les adresses IP sources les plus fréquentes ou encore les codes de statut HTTP.
L’avantage de cet outil, c’est qu’il reconnaît de nombreux formats de logs, ce qui lui permet de prendre en charge les serveurs Web les plus populaires. On peut citer notamment Combined et Common (Apache, Nginx), W3C (IIS), Squid, Caddy, Traefik, Amazon CloudFront, S3, ou encore Google Cloud Storage. Et si cela ne vous convient pas, vous pouvez déclarer un format personnalisé à partir d’un fichier de configuration.
GoAccess s’installe sur les différents systèmes d’exploitation, autant Linux que Windows. Pour Linux, il existe des paquets natifs, tandis que pour Windows, il faudra passer par WSL ou alors l’exécution d’un conteneur Docker.
Pour en savoir plus à propos de GoAccess, lisez la suite de cet article et consultez ces deux ressources officielles :
Installer GoAccess sur Debian ou Ubuntu
Le paquet présent dans les dépôts officiels de la distribution Debian fonctionne, mais il est fort probable qu’il ne permette pas de récupérer une version à jour. Je vous recommande donc d’ajouter le dépôt du projet, qui fournit la dernière version stable.
# Récupération et conversion de la clé de signature du dépôt
wget -O – https://deb.goaccess.io/gnugpg.key | gpg –dearmor | sudo tee /usr/share/keyrings/goaccess.gpg >/dev/null
# Déclaration du dépôt, associé à la clé précédente
echo “deb [signed-by=/usr/share/keyrings/goaccess.gpg arch=$(dpkg –print-architecture)] https://deb.goaccess.io/ $(lsb_release -cs) main” | sudo tee /etc/apt/sources.list.d/goaccess.list
# Installation
sudo apt update
sudo apt install goaccess
Vérifiez ensuite que l’installation s’est bien déroulée :
# Affiche la version
goaccess –version
Analyser un fichier access.log dans le terminal
C’est probablement pour analyser vos logs d’accès, en principe stockés dans le fichier access.log, que vous avez installé GoAccess sur votre serveur. Pour analyser les journaux correctement, il a besoin de connaître le format du journal. Si vous avez personnalisé le format, c’est indiqué dans le fichier Virtual Host du site en question. Sinon, c’est sûrement au format par défaut, à savoir Combined.
Voici comment lancer une analyse sur le fichier access.log d’Apache2 :
sudo goaccess /var/log/apache2/access.log –log-format=COMBINED -a
Détail des éléments utilisés :
–log-format=COMBINED correspond au format par défaut d’Apache et de Nginx. Pour un serveur multi-sites, utilisez VCOMBINED, qui intègre le nom d’hôte virtuel.
-a active la liste des user agents par hôte, pratique pour identifier un robot trop insistant.
Pour pousser GoAccess dans le cadre de la rédaction de cet article, je l’ai lancé sur un journal Apache agrégé de 24,4 Go couvrant sept mois d’activité sur le service web IT-Connect, soit plus de 99 millions de requêtes. Le traitement du fichier entier a demandé environ 38 minutes, sans base de données et en consommant très peu de RAM. Suite à cette analyse, GoAccess annonce 11,1 millions de visiteurs uniques, 130 383 requêtes non abouties et 2,37 To de données transférées.
Il est important de comprendre que GoAccess travaille sur un fichier de logs brut. Ce fichier de log contient tout : les requêtes des humains, des bots, etc… Donc, il y a toute la pollution, ou en tout cas tout le trafic parvenu à atteindre le site web : tout ne correspond pas à de réelles visites. D’ailleurs, l’analyse de ce jeu de données montre que /wp-login.php totalise près de 2,9 millions de requêtes : il s’agit de tentatives d’authentification automatisées sur l’interface de connexion par défaut de WordPress. Les robots pèsent d’ailleurs près de 17 % des hits.
Une fois dans l’interface de GoAccess, quelques touches permettent de naviguer : TAB passe d’un panneau à l’autre, ENTRÉE déplie le panneau sélectionné, / lance une recherche (les expressions régulières sont acceptées) et q quitte l’application. Attention, quand vous quittez GoAccess supprime ses traces (par défaut la persistance est désactivée). Donc, le fait de relancer la même analyse demande d’attendre de nouveau (sur un fichier journalier, vous n’attendrez que quelques secondes).
Vous pouvez analyser plusieurs fichiers d’un coup, ce qui est indispensable après une rotation de logs. C’est même le comportement logique, puisque dans l’idéal, le serveur web effectue une rotation des logs. Dans l’exemple ci-dessus, j’ai abusé pour voir si l’outil réagissait bien avec de gros fichiers.
Dans le cas où vous souhaitez analyser le journal courant et l’archive précédente (.1), cela donne cette commande :
sudo goaccess /var/log/apache2/access.log /var/log/apache2/access.log.1 –log-format=COMBINED
Adapter GoAccess à votre format de logs
Si votre serveur utilise un log_format maison, les formats prédéfinis ne conviendront pas. Il faut alors décrire le format de votre journal à l’aide de spécificateurs. Dans ce cas, vous devez vous appuyer notamment sur : %h (adresse IP du client), %d (date), %t (heure), %r (ligne de requête), %s (code de statut), %b (taille de la réponse), %R (référent), %u (user agent) et %^ (champ à ignorer).
Trois champs sont obligatoires : %h, %d et %r. Si l’on déclare un format personnalisé correspondant au format Combined, cela donnerait :
# Format de date et d’heure, puis structure de la ligne
date-format %d/%b/%Y
time-format %H:%M:%S
log-format %h %^[%d:%t %^] “%r” %s %b “%R” “%u”
Vous allez me dire, on indique cela dans quel fichier ? Vous pouvez les placer dans le fichier de configuration global, dont le chemin s’obtient avec goaccess –dcf. En principe, ce sera ce fichier :
/etc/goaccess/goaccess.conf
Si vous parcourez ce fichier, vous verrez d’ailleurs qu’il contient de nombreux exemples de formats de logs pour divers services. Il y a aussi les options générales de GoAccess. Parmi les options disponibles, il y a notamment celles-ci que vous pouvez configurer :
agent-list true : équivalent de l’option -a, elle affiche la liste des user agents associés à chaque hôte quand vous dépliez le panneau des visiteurs.
ignore-crawlers true : elle écarte des statistiques les robots reconnus par GoAccess, ce qui évite qu’ils gonflent le nombre de visiteurs uniques.
anonymize-ip true : elle masque la fin des adresses IP des clients avant leur affichage, dernier octet pour l’IPv4 et une partie des bits pour l’IPv6.
persist true : elle enregistre sur disque les données analysées à la fin du traitement, au lieu de les perdre à la fermeture (ce que j’évoquais précédemment).
restore true : elle recharge au démarrage les données précédemment enregistrées, ce qui permet de cumuler l’historique au fil des exécutions.
db-path /var/lib/goaccess/ : elle indique le répertoire de stockage de ces données, la valeur par défaut étant /tmp qui ne survit pas à un redémarrage.
Dans le cadre de la rédaction de ce tutoriel, j’ai installé GoAccess sur le serveur où je déploie les conteneurs Docker de mes démos. Il y a un reverse proxy Traefik qui maintient un fichier access.log. Il centralise les requêtes à destination de tous les services exposés.
Si vos logs Traefik sont au format CLF, vous pouvez directement utiliser cette syntaxe :
sudo goaccess /opt/docker-compose/traefik/logs/access.log –log-format=TRAEFIKCLF -a
Mais si, comme moi, vos journaux sont au format JSON, alors vous l’avez dans l’os. En effet, j’ai bien spécifié format: json dans ma configuration Traefik. Ce n’est pas grave, cela me permet de mettre en pratique la déclaration d’un format de log personnalisé.
Pour parcourir les logs de Traefik au format JSON, voici la syntaxe que j’ai utilisée :
datetime-format %Y-%m-%dT%H:%M:%S
log-format {“ClientHost”:”%h”,”RequestMethod”:”%m”,”RequestPath”:”%U”,”RequestProtocol”:”%H”,”DownstreamStatus”:”%s”,”DownstreamContentSize”:”%b”,”request_Referer”:”%R”,”request_User-Agent”:”%u”,”RequestHost”:”%v”,”Duration”:”%n”,”StartLocal”:”%x.%^”}
La modification étant effectuée directement dans le fichier de configuration global de GoAccess, elle sera appelée systématiquement (sinon créez un fichier à part et appelez-le avec l’option -p /chemin/vers/traefik.conf).
Générer un rapport HTML, statique ou en temps réel
Le mode terminal convient à une inspection rapide en SSH. Pour partager ou conserver une analyse, le rapport HTML autonome est plus adapté. L’occasion de tester la syntaxe précédente sur les logs de Traefik et d’en sortir un rapport HTML. Ce qui donne :
sudo goaccess /opt/docker-compose/traefik/logs/traefik.log -a -o /tmp/rapport.html
Il ne reste plus qu’à télécharger le fichier HTML et à le consulter quand bon vous semble. Le rapport est bien fait, avec des sections, des graphes. Ci-dessous un exemple partiel sur le fichier de log Traefik. Sympa, non ?
Analyser les logs de Traefik avec GoAccess et Docker Compose
Voici un scénario concret, que j’ai monté sur mon lab. L’objectif : analyser les journaux d’accès d’un reverse proxy Traefik et publier le rapport en temps réel sur goaccess.it-connectlab.fr, le tout en conteneurs. Car oui, GoAccess sait aussi maintenir le rapport HTML à jour en continu (actualisation chaque 1 seconde) grâce à un serveur WebSocket intégré, qui écoute par défaut sur le port 7890.
Dans les faits, GoAccess ne sert pas la page HTML, il n’expose que son serveur WebSocket. Il faut donc un serveur web à côté pour distribuer le fichier. Nous aurons deux services, et un seul nom de domaine grâce à un routage par préfixe de chemin.
Avant de commencer et pour rappel : Traefik n’écrit aucun journal d’accès par défaut. Veillez donc à configurer le reverse proxy de façon à générer les logs d’accès.
L’arborescence du projet
L’instance GoAccess dockerisée sera organisée de cette façon :
/opt/docker-compose/goaccess/
├── docker-compose.yml
├── .env
├── goaccess.conf
├── goaccess-data/ # rapport HTML généré
└── goaccess-db/ # base persistante
Créez l’arborescence de répertoires :
sudo mkdir -p /opt/docker-compose/goaccess/{goaccess-data,goaccess-db}
cd /opt/docker-compose/goaccess
Désormais, passons à la préparation des différents fichiers.
Le fichier .env
Créez le fichier avec les variables d’environnement en ajoutant ce contenu :
# Domaine où est accessible le rapport
GOACCESS_DOMAIN=goaccess.it-connectlab.fr
# Emplacement des journaux Traefik sur l’hôte
TRAEFIK_LOGS=/opt/docker-compose/traefik/logs
Le fichier docker-compose.yml
Créez le fichier docker-compose.yml à la racine du projet et insérez le code ci-dessous.
services:
goaccess:
image: allinurl/goaccess:latest
container_name: goaccess
restart: unless-stopped
command:
– –no-global-config
– –config-file=/srv/config/goaccess.conf
volumes:
# Journaux Traefik montés en lecture seule
– ${TRAEFIK_LOGS}:/srv/logs:ro
– ./goaccess.conf:/srv/config/goaccess.conf:ro
– ./goaccess-data:/srv/report
– ./goaccess-db:/srv/db
read_only: true
security_opt:
– no-new-privileges:true
tmpfs:
– /tmp
networks:
– frontend
labels:
– “traefik.enable=true”
– “traefik.http.routers.goaccess-ws.rule=Host(`${GOACCESS_DOMAIN}`) && PathPrefix(`/ws`)”
– “traefik.http.routers.goaccess-ws.entrypoints=websecure”
– “traefik.http.routers.goaccess-ws.priority=100”
– “traefik.http.routers.goaccess-ws.tls=true”
– “traefik.http.routers.goaccess-ws.tls.certresolver=ovhcloud”
– “traefik.http.services.goaccess-ws.loadbalancer.server.port=7890”
goaccess-web:
image: nginx:alpine
container_name: goaccess-web
restart: unless-stopped
depends_on:
– goaccess
volumes:
# Le rapport produit par GoAccess, servi en lecture seule
– ./goaccess-data:/usr/share/nginx/html:ro
read_only: true
security_opt:
– no-new-privileges:true
tmpfs:
– /tmp
– /var/cache/nginx
– /var/run
networks:
– frontend
labels:
– “traefik.enable=true”
– “traefik.http.routers.goaccess.rule=Host(`${GOACCESS_DOMAIN}`)”
– “traefik.http.routers.goaccess.entrypoints=websecure”
– “traefik.http.routers.goaccess.tls=true”
– “traefik.http.routers.goaccess.tls.certresolver=ovhcloud”
– “traefik.http.services.goaccess.loadbalancer.server.port=80”
Le réseau frontend est le réseau Docker externe partagé avec Traefik, à déclarer en fin de fichier (ajoutez à la suite du code présenté ci-dessus).
networks:
frontend:
external: true
Ce fichier Docker Compose déclare deux services, l’un avec l’image principale de GoAccess et l’autre avec un serveur web Nginx minimaliste utilisé pour publier le rapport HTML de GoAccess. Ainsi, il sera accessible à l’adresse déclarée dans le fichier .env, à savoir ici : https://goaccess.it-connectlab.fr.
De plus, si vous lisez le fichier Docker Compose, vous verrez que deux routeurs Traefik cohabitent sur le même domaine. En pratique, Traefik classe les règles par longueur, celle qui porte le PathPrefix passe naturellement devant, et la directive priority rend l’intention explicite. Notez qu’aucun port n’est publié sur l’hôte : Traefik joint le port 7890 par le réseau interne, ce qui évite d’exposer le WebSocket en direct.
Le fichier goaccess.conf
Il nous reste un fichier à préparer, c’est celui avec toute la configuration de GoAccess. C’est un fichier personnalisé capable de lire les logs Traefik au format JSON et il adapte également le comportement de GoAccess. Il reprend des options de configuration évoquées précédemment.
# Format des journaux d’accès Traefik en JSON
datetime-format %Y-%m-%dT%H:%M:%S
log-format {“ClientHost”:”%h”,”RequestMethod”:”%m”,”RequestPath”:”%U”,”RequestProtocol”:”%H”,”DownstreamStatus”:”%s”,”DownstreamContentSize”:”%b”,”request_Referer”:”%R”,”request_User-Agent”:”%u”,”RequestHost”:”%v”,”Duration”:”%n”,”StartLocal”:”%x.%^”}
# Entrée et sortie
log-file /srv/logs/access.log
output /srv/report/index.html
# Rapport temps réel derrière le reverse proxy
real-time-html true
ws-url wss://goaccess.it-connectlab.fr:443/ws
origin https://goaccess.it-connectlab.fr
addr 0.0.0.0
port 7890
# Options d’analyse
agent-list true
ignore-crawlers true
anonymize-ip true
no-query-string true
# Persistance de l’historique
persist true
db-path /srv/db/
# À décommenter après le premier démarrage (donc après le premier Docker Compose up)
#restore true
Ce fichier de configuration sera chargé par le conteneur global de GoAccess. C’est pour cette raison qu’il y a ces lignes dans le fichier Docker Compose :
command:
– –no-global-config
– –config-file=/srv/config/goaccess.conf
Démarrer et vérifier
Quand tout est prêt et que les fichiers sont enregistrés, lancez la construction de la stack :
docker compose up -d
Vous pouvez aussi afficher les journaux pour voir si tout se passe bien :
docker compose logs -f goaccess
Le rapport est accessible sur https://goaccess.it-connectlab.fr. Il affiche les journaux d’accès de Traefik, avec une actualisation chaque seconde.
Décommentez ensuite restore true, puis relancez avec docker compose restart goaccess.
Attention : ce rapport expose des adresses IP, des URL internes et des habitudes de navigation. Ne le déposez jamais dans un répertoire web public sans authentification. Une page protégée par TinyAuth, Authentik, etc… ou une simple authentification HTTP règle le problème.
Automatiser la production des rapports
GoAccess sait conserver ses données entre deux exécutions, ce qui évite de tout relire à chaque fois et permet de garder un historique au-delà de la rotation des logs. J’en ai parlé précédemment en évoquant les options –persist et –db-path.
Voici comment vous pouvez en bénéficier directement via la commande goaccess et sans gérer un fichier de configuration comme nous venons de le faire. Ceci peut s’avérer utile pour automatiser la génération d’un rapport via l’exécution périodique de cette commande.
# Premier passage : on constitue la base
sudo goaccess /var/log/nginx/access.log –log-format=COMBINED –persist –db-path=/var/lib/goaccess/
# Passages suivants : on restaure, on ajoute, on conserve
sudo goaccess /var/log/nginx/access.log –log-format=COMBINED \
–restore –persist –db-path=/var/lib/goaccess/ -o /var/www/html/rapport.html
Le répertoire indiqué par –db-path doit exister (la valeur par défaut est /tmp, à éviter en production). Il ne reste plus qu’à planifier la seconde commande, par exemple toutes les heures, via une tâche cron ou un timer systemd.
Conclusion
GoAccess occupe une place à part : ce n’est pas une solution de web analytics complète, et ce n’est pas non plus une pile de centralisation lourde. Pourtant, il apporte une visibilité immédiate sur ce qui se passe réellement sur un serveur web, avec la lecture et la mise en forme des logs, le tout en quelques minutes. C’est un outil indispensable si vous hébergez des services web, et comme vous le savez, il y a beaucoup d’outils et de solutions qui ont une interface web…
FAQ
Qu’est-ce que GoAccess ?
GoAccess est un analyseur de logs web, écrit en C et publié sous licence MIT (open source). Il est conçu pour lire les journaux d’accès d’un serveur web (Apache, Nginx, Caddy, Traefik, etc.) et affiche les statistiques dans un tableau de bord, soit directement dans le terminal, soit sous forme de rapport prêt à l’emploi.
GoAccess est-il gratuit ?
Oui. GoAccess est distribué sous licence MIT et reste entièrement gratuit. C’est une pépite open source et il n’y a pas de licences commerciales.
Comment installer GoAccess sur Debian ou Ubuntu ?
Pour disposer de la dernière version stable, ajoutez le dépôt officiel du projet en enregistrant sa clé GPG dans /usr/share/keyrings/ puis en déclarant le dépôt avec l’option signed-by. Installez ensuite le paquet depuis ce dépôt avec apt install goaccess. Ceci permet de récupérer la dernière version.
Quelle est la commande de base pour analyser un fichier access.log ?
La commande goaccess /var/log/nginx/access.log –log-format=COMBINED ouvre le tableau de bord dans le terminal. Ajoutez -o rapport.html pour générer un rapport HTML à la place.
Quels formats de logs GoAccess prend-il en charge ?
GoAccess propose des formats prédéfinis pour Combined et Common (Apache, Nginx), leurs variantes avec hôte virtuel, W3C (IIS), Squid, Caddy, Traefik, Amazon CloudFront, S3, ELB et ALB, ainsi que Google Cloud Storage. Tout autre format peut être décrit manuellement à l’aide de spécificateurs : vous êtes donc libre de l’adapter à vos besoins.
Comment générer un rapport HTML avec GoAccess ?
Utilisez l’option -o suivie d’un chemin se terminant par .html, par exemple goaccess access.log –log-format=COMBINED -o rapport.html. Le fichier produit est autonome et s’ouvre dans n’importe quel navigateur.
GoAccess fonctionne-t-il derrière un reverse proxy ?
Oui, à deux conditions. Le rapport doit être lancé avec –ws-url pointant vers l’URL publique en wss://, et le reverse proxy doit être configuré pour relayer les connexions WebSocket vers le port d’écoute de GoAccess. Nous avons vu un exemple avec Traefik.
Comment exclure les robots des statistiques GoAccess ?
L’option –ignore-crawlers écarte les robots reconnus par GoAccess. L’option complémentaire –unknowns-as-crawlers classe les systèmes et navigateurs non identifiés comme robots, ce qui affine encore la mesure du trafic humain.
Comment GoAccess compte-t-il les visiteurs uniques ?
Une visite unique correspond à la combinaison d’une même adresse IP, d’une même date et d’un même user agent. La granularité peut être affinée à l’heure ou à la minute avec l’option –date-spec.
GoAccess conserve-t-il l’historique des statistiques ?
Oui, grâce au traitement incrémental. Les options –persist et –restore, associées à –db-path, enregistrent les données sur disque et les rechargent au lancement suivant. L’historique survit ainsi à la rotation des journaux. Mais ce n’est pas son comportement par défaut, donc vous devez activer ces options (dans la config ou en tant qu’arguments de la commande).
GoAccess peut-il remplacer Google Analytics ou Matomo ?
Partiellement. GoAccess mesure le trafic réel, y compris celui des visiteurs équipés d’un bloqueur de publicités, puisqu’il n’utilise ni script ni cookie. En revanche, il ne fournit ni temps passé par page, ni parcours de navigation, ni suivi de conversion. Il est susceptible d’être moins précis, y compris pour identifier le trafic généré par les agents IA.
GoAccess est-il compatible RGPD ?
GoAccess ne dépose ni cookie ni traceur, ce qui le place en dehors du champ du consentement. Il traite toutefois des adresses IP, considérées comme des données personnelles. L’option –anonymize-ip et la durée de conservation des journaux reste à définir de votre côté.
Cofondateur d’IT-Connect et Microsoft MVP “Cloud and Datacenter Management”. Mon obsession depuis près de 15 ans ? Rendre l’administration système et la cybersécurité accessibles, que vous soyez junior ou confirmé. Plus qu’un métier, l’IT est pour moi une véritable passion. J’accompagne au quotidien les sysadmins et les professionnels de l’IT dans leur montée en compétences et leur veille technique.
