zestedesavoir / zds-site

Cœur du projet technique de Zeste de Savoir
https://zestedesavoir.com
Other
268 stars 161 forks source link

Amélioration des statistiques des contenus en les traitant côté serveur #6030

Closed AmauryCarrade closed 3 years ago

AmauryCarrade commented 3 years ago

Bonjour,

Les statistiques des contenus ont été implémentées il y a quelques temps dans #4942 en utilisant l'API de Google Analytics. C'était effectivement une bonne idée afin de se simplifier la vie (après tout, on a déjà des statistiques, autant s'en servir), mais l'on est forcés de constater que concrètement, cette solution ne tient pas la route.

En effet, Google Analytics est massivement bloqué, et l'on constate un énorme gap entre des données statistiques externes et celles reportés dans un contenu. Par exemple, ce billet indique 25 vues le 18 février, quand le tweet de ZdS qui l'a principalement diffusé nous dit que le lien a été cliqué plus d'une centaines de fois (et les statistiques de Twitter sont, elles, fiables).

On ne parle pas d'une petite différence, mais d'un facteur 4, et j'ai déjà constaté un facteur 10.

Je propose donc dans ce ticket plusieurs solutions alternatives pour collecter des statistiques des contenus (et uniquement des contenus).

Méthode 1 — In situ, tout à la main

La première méthode consiste à tout faire nous même. Le concept est simple : pour chaque requête, on collecte les données en temps réel, et on les assemble la nuit.

Concrètement, on aurait deux modèles. Un modèle tutorialv2.LiveStatistics (ou LiveHits) contiendrait :

Dés lors que quelqu'un charge une page d'un contenu, on ajoute un enregistrement horodaté à cette table. Il faudrait exclure les bots, mais la dépendance user-agents introduite par #6021 permet de le faire très simplement (parse(ua_string).is_bot, en gros).

Pour éviter d'accumuler une énorme quantité de données et simplifier l'affichage des statistiques, un cron passerait tous les jours à minuit pour assembler toutes les visites d'une journée dans une autre table, disons tutorialv2.Statistics. Cette table ne contiendrait que quatre champs :

Une commande Django ferait l'assemblage et supprimerait les données de la table contenant les données en temps réel.

Pour afficher les statistiques, il suffirait alors de lire cette table, qui contient directement toutes les données. Pour avoir aussi des données en temps réel, on pourrait agréger les données du jour de la table LiveStatistics (il y en aura beaucoup moins que si on devait le faire avec l'intégralité des vues). Connaître les statistiques en temps réel reste utile, en particulier pour les articles ou billets événementiels.

Avantages — Aucune dépendance, fonctionne dans tous les cas, impossible à bloquer, respectueux (on ne stocke aucune donnée personnelle). Inconvénients — On doit tout gérer nous-même.

Méthode 2 — In situ, mais données des différentes journées depuis les logs nginx

C'est le même principe que la première méthode, mais au lieu de collecter les statistiques en temps réel nous-même dans une table LiveStatistics, on utilise un programme comme goaccess pour lire les logs nginx. Le reste est identique.

À noter que ça avait été tenté mais sans succès sur #3785. Cela dit, les outils ont pu évoluer depuis.

Avantages — On utilise des logs déjà existants. Inconvénients — On dépend fortement de l'infrastructure du projet. Ce n'est pas testable sans nginx, et si l'architecture change d'une telle façon qu'on a pas accès aux logs, ça ne fonctionnera plus. Si logrotate fait tourner les logs durant la journée, les statistiques seront incomplètes (sauf erreur ?).

Méthode 3 — Avec Matomo, installé classiquement dans les règles du RGPD

Matomo est un logiciel libre permettant de collecter des statistiques, concurrent direct de Google Analytics. Il est possible de le configurer d'une telle façon qu'il ne soit pas nécessaire de demander leur accord aux visiteurs pour collecter des statistiques, essentiellement car on ne collecte plus de données personnelles (les adresses IP sont tronquées, notamment).

On utiliserait alors les API de Matomo (installé chez nous, a priori ?) pour faire exactement comme aujourd'hui (où l'on utilise les API de Google Analytics).

Avantages — Rien à gérer : Matomo se débrouille pour collecter, filtrer, dé-dupliquer, les statistiques. Inconvénient — Pas mal de gens bloquent Matomo à vue, même s'il est configuré pour être respectueux (car ils ne peuvent pas le savoir). Il me semble que c'est même le cas de Firefox lui-même, par défaut, quand la protection contre le pistage est activée (mais à vérifier) ; il y a donc un risque de retrouver le même genre de problèmes qu'avec Google Analytics.

Méthode 4 — Avec Matomo, mais collecte côté serveur

Matomo permet également de collecter des statistiques côté serveur. On ferait ça (pour toutes les pages du site, du coup ?), et on afficherait les stats comme actuellement, avec les API de Matomo au lieu de Google Analytics.

Avantages — Rien à gérer : Matomo se débrouille pour collecter, filtrer, dé-dupliquer, les statistiques. Impossible à bloquer. Inconvénient — Ça ajoute une requête vers un service externe côté serveur, ce qui peut créer un goulot de performances si Matomo a un souci ou est juste lent. Il n'y a pas de SDK officiel de Matomo pour Python, seulement un SDK non-officiel maintenu par une personne et mis à jour sporadiquement.


Voilà donc ce qu'il en est.

À noter également que ces solutions ne permettent que de suivre le nombre de pages vues uniques, quand actuellement sont disponibles en plus :

Le nombre de session n'est pas particulièrement utile à mon sens. Le nombre de nouveaux visiteurs, ça se discute, et on pourrait réfléchir comment le stocker si on le juge pertinent — en réalité, il y a moyen que ce ne soit pas si complexe en stockant une liste de hash représentant des visiteurs, mais ça commence furieusement à ressembler à des données personnelles et à une ré-implémentation d'un Matomo.

Concernant le temps de lecture et les mots-clefs et liens entrants, on pourrait fonctionner en mode hybride, surtout que ces choses là dépendent moins du nombre de personnes collectées (statistiquement, ça doit se valoir même si on collecte une sous-partie), en récupérant ces données depuis Matomo/Google Analytics, et les vues depuis un système plus efficace.

De manière générale, je trouve qu'il n'est pas embêtant de perdre des données car ça permet de simplifier les statistiques. L'idée est de savoir à quel point on est lu, pas de faire des campagnes marketing avec ces données ^^ .

my two cents


L'objectif de ce ticket est de récolter des avis sur ces différentes méthodes, sur leur pertinence, et sur ce qu'il serait préférable de faire (“rien” étant également une option, mais je trouve que l'état actuel des choses n'est pas idéal). J'attends donc vos retours avec intérêt.

Bonne journée !

firm1 commented 3 years ago

On en a déjà discuté sur discord, mais j'avoue que je préfère déléguer ce type de taches aux outils qui savent le faire (probablement mieux que nous) quand il en existe.

Pourquoi ?

Les solution 1 et 2 me plaisent moyennement pour trois raisons :

  1. Étant donné qu'on parle de données statistiques, il suffit que l'on se trompe une fois dans les règles de gestion (comment on filtre un robot d'un vrai utilisateur, oublie d'augmenter le compteur sur une page), ou que celles-ci évoluent, pour rendre caduque une partie de nos informations. La solution 2 est déjà moins problématique car on peut recalculer les anciennes valeurs (en supposant qu'on ait une bonne durée de rétention des logs)
  2. On va globalement augmenter notre codebase et probablement maintenir ce code sur le terme
  3. Difficile de faire la séparation entre "pages vues" et "vues uniques" sur un contenu

Je suis plutôt favorable à l'une des options 3 ou 4. Ma préférée étant la 4, parce qu'une fois installé, on peut enlever le bandeau de consentement du site, avoir des stats plutot complètes, et ça me rassure sur les règles de gestions implémentées, puisque matomo est un produit aujourd'hui très mature.

SpaceFox commented 3 years ago

+1 firm1, en gros.

D’autre part il y a une stat que j’aime bien, c’est l’information « d’où viennent les utilisateurs » ? Le champ est rarement mentionné, mais ça permet quand même d’avoir une vague idée de comment le contenu s’est propagé, et pourquoi certains pics. D’ailleurs à une époque c’était assez facile de retrouver un tweet à partir d’un lien Twitter embarqué (t.co/abcdefgh…) mais ça ne semble plus possible (ou en tous cas plus facilement), c’est dommage (et complètement hors sujet).

SpaceFox commented 3 years ago

PS : un détail mais qui peut avoir son importance, c’est d’améliorer le graphe de rendu pour avoir différentes couleurs pour les différents modes de collectes (anciennes données GA / nouvelles données GA avec personne de pris en compte / futures données internes), ça indiquerait que les plages ne sont pas directement comparables entre elles.

AmauryCarrade commented 3 years ago

Ça implique d'avoir un Matomo à installer et maintenir en plus. Qui s'en chargerai ?

Parce que si on part là dessus on peut très rapidement collecter des stats pour tout ZdS côté serveur, même pour la v30 je veux dire (quitte à les utiliser pour les stats de contenus plus tard, au moins y'aura les données).

Sinon, je suis également favorable à l'option 4, tant que ça ne ralentit pas le site si Matomo a un souci (ça peut passer par une queue ou par un timeout court — de toute façon, le point d'entrée de collecte de stats met dans une queue côté Matomo donc ça devrait tourner vite).

PS : un détail mais qui peut avoir son importance, c’est d’améliorer le graphe de rendu pour avoir différentes couleurs pour les différents modes de collectes (anciennes données GA / nouvelles données GA avec personne de pris en compte / futures données internes), ça indiquerait que les plages ne sont pas directement comparables entre elles.

+1, mais alors deux choses.

  1. Ça implique d'importer les données de Google Analytics dans Matomo et d'ajouter aux paramètres de l'app ZdS la date de migration (donc de mise en prod de la v30, si on fait ça vite).
  2. Il faudrait faire attention aux choix de couleurs (plus précisément : choisir deux couleurs de la même teinte mais de luminosité différente), afin de ne pas pénaliser les personnes daltoniennes.
artragis commented 3 years ago

Disons que si on peut mettre le matomo sur un petit VPS ça serait cool. en effet on peut partir rapidement dessus.

AmauryCarrade commented 3 years ago

Sur le VPS de la bêta dans un premier temps ? Ou même sur la prod, sauf si le serveur est trop juste ? @Situphen

Faut juste que le serveur qui l'accueil soit assez réactif, sinon ça pourrait ralentir tout le site (sauf s'il y a une solution pour envoyer la requête vers matomo sans jamais attendre sa réponse, et au pire si ça se perd tant pis)

Situphen commented 3 years ago

J'ai l'impression que Matomo c'est quand même assez gourmand d'après leurs recommandations de configuration :

Tracking 100,000 page views per month or less

While Matomo can scale to millions of pages, it is also very efficient to run on a smaller scale, even on a shared hosting account.

  • One server is sufficient to host both the database and app server
  • App server minimum recommended configuration: 2 CPU, 2 GB RAM, 50GB SSD disk.

Tracking 1 million page views per month or less

  • One server can be sufficient to host both the database and app server
  • App server minimum recommended configuration: 4 CPU, 8 GB RAM, 250GB SSD disk.

J'ai du mal à estimer le nombre de page views par mois mais si on se restreint aux contenus, vu les chiffres des récapitulatifs communautaires, on est en dessous des 100 000 page views par mois. Par contre si on inclut les autres pages du sites web pour des statistiques internes là peut-être qu'on dépasse ?

Sur le serveur de production on a 3 cœurs virtuels de CPU et 6 Go de RAM (dont 2 Go disponible actuellement) tandis que sur le serveur de bêta on a 4 cœurs virtuels (de plus faible puissance que sur le serveur de production) et 4 Go de RAM (dont 1 Go disponible). Après sur le serveur de production on peut augmenter le nombre de cœurs ou la RAM de mémoire, mais sur le serveur de bêta je ne crois pas (enfin pas sans créer une nouvelle instance).

Au niveau de l'espace disque, les 50 Go recommandés c'est sur le long terme. Leur page dédié à l'optimisation donne une estimation de 7 Go en 1 an si on a 3 millions de page views par mois :

A rough estimate of Matomo Mysql database size usage is approximately 1GB for every 5M page views. If your website tracks 100k page views per day (3M page views per month), you can expect a DB size of ~ 7GB after 1 year.

Après il faut prendre en compte le poids de Matomo lui-même et des logiciels liés à PHP donc il faut rajouter quelques Go. Là encore sur le serveur de production l'espace disque s'augmente facilement, sur le serveur de bêta je ne sais pas.

J'aurais tendance à écarter le serveur de bêta car par définition ce n'est pas un serveur de production : on y fait des tests de logiciels, de configuration, on est libre de le redémarrer à tout moment, etc. À mes yeux il y a deux solutions : soit on met Matomo sur le serveur de production (en augmentant si besoin le nombre de cœurs, la RAM ou l'espace disque) ; soit on le met sur un troisième serveur (chez Gandi, à voir quelle formule) où on pourrait mettre aussi un Sentry et un Munin plus tard si on souhaite être autonome par rapport au Sentry de Sandhose et au Munin de cepus (comme il en était question à l'AG).

Je tiens à préciser que je n'ai aucune formation reconnue en administration de serveur (ni en informatique) donc probablement que des contraintes/choses à prendre en compte m'échappent.

AmauryCarrade commented 3 years ago

Malgré ton absence de formation, ton exploration des possibilités est précieuse, merci beaucoup pour ça !

À mes yeux il y a deux solutions : soit on met Matomo sur le serveur de production (en augmentant si besoin le nombre de cœurs, la RAM ou l'espace disque) ; soit on le met sur un troisième serveur (chez Gandi, à voir quelle formule) où on pourrait mettre aussi un Sentry et un Munin plus tard si on souhaite être autonome par rapport au Sentry de Sandhose et au Munin de cepus (comme il en était question à l'AG).

Ne serais-ce pas l'occasion idéale pour migrer Sentry et Munin sur un serveur de l'asso (qui prendrait aussi Matomo, et plus généralement, tous les services annexes à ZdS) ? On en parle depuis un moment, et a priori, on peut largement se le permettre (il faudrait faire une estimation de coûts pour en être sûrs, bien entendu, mais ça ne semble pas être un souci au vu de la dernière AG).

Situphen commented 3 years ago

Ne serais-ce pas l'occasion idéale pour migrer Sentry et Munin sur un serveur de l'asso (qui prendrait aussi Matomo, et plus généralement, tous les services annexes à ZdS) ? On en parle depuis un moment, et a priori, on peut largement se le permettre (il faudrait faire une estimation de coûts pour en être sûrs, bien entendu, mais ça ne semble pas être un souci au vu de la dernière AG).

Alors on n'est pas obligé de migrer Sentry et Munin en même temps que le passage de Google Analytics à Matomo, mais je pense qu'il faut effectivement prévoir ces deux migrations dans le choix du serveur et sa configuration !

AmauryCarrade commented 3 years ago

C'est effectivement surtout à ça que je pensais, anticiper pour pouvoir tout mettre dessus :) .

C'est un sujet qu'on pourra aborder en réunion de dév, il faudra juste voir quelles ressources on a avant mais les comptes rendus financiers de l'a réunion du CA doivent être encore OK.

philippemilink commented 3 years ago

Je plussoie l'idée d'avoir un serveur qui appartienne à l'assoc sur lequel on aurait tous nos éléments de supervision (munin, sentry et matomo), si les finances de l'asso nous le permettent.

Un point qui n'a pas été abordé (il me semble) c'est les changements nécessaires dans le code de ZdS pour passer de Google Analytics à Matomo. (mais je ne connais pas le code actuellement en place pour gérer Google Analytics, donc cette question n'est peut-être pas vraiment pertinente)

AmauryCarrade commented 3 years ago

Si on passe de GA côté client à Matomo côté serveur, c'est a priori très simple : i lfaudra

  1. supprimer le code de suivi de GA ;
  2. supprimer la bannière de consentement car on n'aura plus rien le demandant ;
  3. supprimer les cookies GA de la page des cookies ;
  4. ajouter le suivi côté serveur de Matomo dans un middleware, via piwik-python-api par exemple, idéalement en s'arrangeant pour ne pas attendre la réponse des requêtes (histoire de ne pas avoir un délai inutile pour le visiteur), assorti de la configuration qui va bien dans settings.ZDS_APP.

En plus, bien sûr, d'installer Matomo et de créer le sous-domaine qui va bien pour ça.

philippemilink commented 3 years ago

Je pensais au code qui récupère les données pour faire les graphiques qui sont affichés à l'auteur de contenus.

AmauryCarrade commented 3 years ago

Ah, pardon. Ça effectivement y'a moyen qu'il y ait un peu plus de travail, mais le côté front ne devrait pas bouger des masses. Il suffit d'adapter les vues pour utiliser les APIs de Matomo au lieu de celles de Google — elles ne doivent pas être si différentes, je suppose.

Mais ça peut se faire en deux temps : d'abord on passe sous Matomo ; ensuite on voit pour passer les stats dessus. Le premier est simple, le second un poil moins mais normalement ça va.

artragis commented 3 years ago

J'ajouterai qu'il faudra

AmauryCarrade commented 3 years ago

Sauf qu'on n'utiliserait pas de cookie Matomo, vu qu'on aurait une collecte côté serveur uniquement.

Si on parle de façon plus générale (déclaration CNIL etc.) il faudra aussi importer les données Google Analytics dans Matomo.

artragis commented 3 years ago

Du coup on perdrait certaines info, non? (taux de rebond, mots clefs, temps de lecture...)

AmauryCarrade commented 3 years ago

Les stats côté serveur on l'avantage de la fiabilité… Limite, on peut voir si on peut cumuler les deux. Mais même en mode respectieux sans bandeau cookies, le script de Matomo côté client sera bloqué par beaucoup de monde, car c'est un modèle classique.

artragis commented 3 years ago

il est bloqué même si on n'est pas en mode "service tiers"?

AmauryCarrade commented 3 years ago

Beaucoup de bloqueurs bloquent à vue tout script ressemblant oui, sans se poser la question de si c'est le même domaine, ou de si Matomo est configuré en mode respectueux. Il me semble même que c'est le cas de Firefox par défaut depuis quelques version, au moins en mode strict. En tout cas j'ai déjà vu mon bloqueur bloquer des instances Matomo auto-hébergées, y compris une que je venais d'installer et qu'il ne pouvais donc pas connaître.

Ce serait certainement moins bloqué que Google Analytics, mais tout de même pas mal, a priori.

artragis commented 3 years ago

Ok, donc on abandonne ces métriques. De toute façon je ne suis pas sûr qu'elles aidaient les auteurs.

AmauryCarrade commented 3 years ago

Il semblerait que Matomo soit capable de faire du suivi côté client et serveur en combinant les données sans rien faire de particulier de notre côté (ref, autre ref), donc on peut aussi tenter ça. Mais en effet, à voir à quel point ces informations sont utiles.

Certaines peuvent l'être je pense, notamment le temps de lecture.

firm1 commented 3 years ago

ça c'est fait.