=== HKC Trafic ===
Contributors: hkabla
Plugin URI: https://plugins.hervekabla.com/hkc-trafic/
Tags: analytics, access log, bots, crawlers, statistics
Requires at least: 6.2
Tested up to: 6.9
Requires PHP: 7.4
Stable tag: 0.4.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Trafic dans l'administration : vue d'ensemble des visites humaines, statistiques, robots, journal des accès filtrable, URLs suspectes, conservation taillée au trafic constaté.

== Description ==

L'extension ajoute un menu « Trafic » (interface en anglais) qui tient le journal des accès du
site : une ligne par requête, écrite en fin de requête, avec le code de réponse, le temps de
traitement, la langue de la page, l'appareil, le navigateur, le système, et le nom du robot
lorsque c'en est un.

**Cinq écrans**

*Vue d'ensemble* : pages vues, visites (un visiteur compté une fois par jour) et pages par visite,
sur aujourd'hui, 7, 30, 90 jours ou 12 mois, avec des filtres qui se cumulent — appareil, système,
navigateur, langue, et pays et ville si la localisation est en service. Chaque liste déroulante
montre les valeurs présentes avec leur effectif et leur part, calculés avec les *autres* filtres
appliqués. Le graphique empile les visites et les pages vues en plus : la hauteur totale vaut les
pages vues, la partie foncée les visites.

*Statistiques* : pages les plus lues, sites référents, pages précédentes d'une navigation interne,
appareils, navigateurs, systèmes, langue consultée, pays, villes, et adresses introuvables.

Chaque ligne de chaque classement se déplie sur place, entre les lignes. Sur une adresse, le
dépliage sort de la définition de l'écran et montre *tout* ce qui l'a demandée : humains, robots,
machines, codes de réponse, temps de traitement, provenance, robots nommés. De là, « Ligne par
ligne » ouvre en superposition chaque passage un par un, paginé, filtrable par nature de visiteur,
chaque ligne se dépliant à son tour sur son code HTTP, son temps de réponse, son adresse, son
opérateur et son référent. Sur les autres classements — un navigateur, un pays, un référent — le
dépliage montre les pages lues avec cette valeur.

*Robots* : les quinze plus actifs, leurs erreurs, les adresses qu'ils demandent — et un tableau à
part pour les robots des IA génératives, regroupés par maison. Avec la localisation, les robots
déguisés (une page demandée depuis un centre de données avec un agent de navigateur ordinaire)
sont comptés à part et écartés des visites.

Un user-agent se recopie ; une adresse appartient à quelqu'un. Google, Bing et Apple publient les
plages d'où leurs robots travaillent : l'extension les relit une fois par semaine et rapproche
chaque ligne de son adresse. Googlebot figure donc dans son propre tableau même s'il est loin du
classement par volume, une adresse en 34.x ou 35.x est nommée « Google Cloud » et non « Googlebot »,
et un robot qui emprunte le nom d'une maison sans venir de chez elle est signalé comme tel.

*Journal des accès* : une ligne par requête, un entonnoir sur chacune des seize colonnes
filtrables — vingt avec la localisation, qui ajoute pays, ville, opérateur et numéro d'AS — qui
montre ses cinquante valeurs les plus fréquentes avec leur effectif. Un filtre qu'on refait
souvent se nomme et devient une **vue enregistrée**, rangée au-dessus du tableau.

La période choisie suit d'un écran à l'autre : regarder les robots sur quatre-vingt-dix jours
puis passer au journal garde ces quatre-vingt-dix jours.

*URLs suspectes* : ce que les sondes cherchent, les adresses essayées avec les codes de réponse
reçus, et d'où elles viennent. Une sonde à laquelle le site a répondu 200 est signalée en tête :
c'est la seule ligne de cet écran qui demande une vérification le jour même.

**Ce qui la distingue d'un outil de mesure d'audience**

Un outil d'audience compte les visiteurs humains et ignore le reste. Un journal d'accès voit
tout : les robots, les sondes qui cherchent une faille, les erreurs 500, les requêtes lentes.
Les deux lectures sont là, mais elles ne sont jamais mélangées : « page vue par un humain »
veut dire une page du site rendue avec un 200, à un visiteur qui n'est ni un robot déclaré, ni
une sonde, ni un administrateur connecté — la même définition dans tous les écrans.

**La base de données ne doit pas exploser**

C'est le sujet principal, et il est traité par trois leviers plutôt que par un réglage unique :

* les chemins sont rangés dans leur propre table, et chaque passage ne porte que leur numéro :
  une ligne occupe environ 110 octets au lieu de 400 ;
* le user-agent n'est jamais stocké : appareil, navigateur, système et nom du robot en sont
  tirés à l'écriture, et la chaîne d'origine est jetée ;
* les durées de conservation sont séparées — robots, autres requêtes, pages vues par des
  humains — parce que ces lignes ne vieillissent pas à la même vitesse.

L'écran des réglages mesure ensuite ce que le journal coûte vraiment sur ce site : la taille
réelle d'une ligne (taille des tables divisée par le nombre de lignes), le débit réel des sept
derniers jours, et l'espace libre quand l'hébergeur le dit. Il annonce alors combien de jours
le budget que vous fixez peut tenir, et propose les durées correspondantes. Au-delà du budget,
les lignes les plus anciennes partent, et si le budget est trop petit pour que le journal
apprenne quoi que ce soit, l'écriture s'arrête en le disant plutôt que de donner des chiffres
faux.

**Les alertes : prévenir avant de gêner**

Les garde-fous ci-dessus agissent en silence. Le jour où le budget est atteint, des lignes
disparaissent sans que personne l'ait demandé — d'où des alertes qui se déclenchent avant, et
qui s'affichent dans toute l'administration, pas seulement sur l'écran de l'extension :

* moins de 512 Mo libres sur le disque, ou moins de 5 % de sa taille. Celle-là ne concerne pas
  le journal mais l'hébergement entier : un disque plein arrête le site ;
* le journal a consommé les quatre cinquièmes de son budget ;
* au débit constaté, le budget sera plein dans moins d'une semaine ;
* les requêtes des deux derniers jours valent trois fois le débit ordinaire — un robot
  déchaîné, ou une campagne de sondes, remplit un journal en quelques heures ;
* plus de vingt mille lignes attendent d'être versées : la tâche planifiée ne tourne plus,
  souvent parce que WP-Cron est désactivé sur le site ;
* l'écriture s'est arrêtée d'elle-même.

Chaque alerte part aussi une fois par e-mail, puis se tait deux jours tant que la situation
dure. Elle disparaît d'elle-même quand sa cause disparaît.

**Le coût sur le site public**

C'est la seule extension de la série qui travaille sur le site public, et elle le dit. Le
chemin d'écriture ajoute une ligne de texte à un fichier, sans lire la base, sans appel réseau
et sans rien ajouter à la page. Une tâche planifiée verse ensuite ces lignes en base par lots
de deux cents, où chaque ligne coûte dix fois moins qu'un INSERT isolé. Sur un disque réseau,
où verrouiller un fichier n'est pas fiable, un réglage fait écrire directement en base.

Le fichier d'attente contient des adresses IP : il est rangé dans un dossier au nom tiré au
hasard, protégé par un `.htaccess` et un `index.php`, et l'administration vérifie par une
requête HTTP qu'il ne répond pas. S'il répond — cas d'un serveur nginx, qui ne lit pas les
`.htaccess` — l'attente par fichier est abandonnée d'elle-même.

**Pays et ville : une décision, pas un réglage par défaut**

Localiser une adresse veut dire l'envoyer à un tiers. Tant qu'aucun jeton ipinfo n'est enregistré
dans les réglages, rien n'est envoyé nulle part et les filtres Pays et Ville n'apparaissent pas.
Avec un jeton, seules les adresses des visiteurs humains sont résolues, une fois chacune, et la
réponse est gardée dans une table du site : la même adresse n'est jamais envoyée deux fois. Le
plan gratuit d'ipinfo accorde cinquante mille requêtes par mois ; l'extension compte les siennes,
s'arrête au plafond que vous réglez, et se tait jusqu'au lendemain si le service refuse. Dix
adresses sont résolues toutes les cinq minutes, un bouton en fait soixante d'un coup.

**Vie privée**

Aucun cookie n'est posé. Un visiteur est compté par une empreinte salée valable la journée,
calculée à partir de son adresse et de son navigateur. L'adresse IP vit moins longtemps que la
ligne : passé le délai réglé (trente jours par défaut), elle perd sa dernière partie et il n'en
reste que le réseau ; réglée à zéro, elle est tronquée avant d'être écrite et l'adresse complète
n'existe nulle part. La conservation des pages vues par des humains est plafonnée à treize mois.

**Ce que l'extension ne sait pas faire**

Si le site est servi par un cache de page (LiteSpeed, WP Rocket, un CDN), PHP ne démarre pas
pour une page déjà en cache : ces visites-là n'apparaissent pas dans le journal. Le relevé
exhaustif est alors celui du serveur web. Mesurer les visites derrière un cache, le temps passé
sur une page et les événements de sortie demande une balise dans la page : c'est l'étape
suivante, et elle n'est pas dans cette version.

== Installation ==

1. Extensions › Ajouter › Téléverser une extension, choisir `hkc-trafic.zip`.
2. Activer : les tables et les tâches planifiées sont créées à l'activation.
3. Ouvrir le menu « Trafic ». Le journal se remplit à partir de la première visite.

Les mises à jour arrivent ensuite par l'écran habituel des mises à jour de WordPress.

== Frequently Asked Questions ==

= Combien de place le journal prend-il ? =

Cela dépend du trafic, et l'écran des réglages le mesure sur votre site plutôt que de le
supposer. Pour donner un ordre d'idée : mille pages vues et trois mille requêtes de robots par
jour occupent environ 440 ko par jour, soit 13 Mo par mois de détail complet.

= Le journal ralentit-il le site ? =

Le chemin d'écriture ajoute une ligne à un fichier après que la réponse est partie : quelques
dizaines de microsecondes, sans requête SQL. C'est le versement en base, planifié, qui porte le
coût — et il a lieu hors de toute visite.

= Les tâches planifiées apparaissent-elles dans le journal ? =

Non : une exécution de WP-Cron n'est pas du trafic, et l'extension ne charge même pas son
journal pendant une tâche planifiée. Les requêtes vers `wp-cron.php` n'y figurent donc pas.

= Pourquoi le nombre de visites ne correspond-il pas à Google Analytics ? =

Analytics compte les navigateurs qui exécutent son script ; ce journal compte les requêtes que
PHP a traitées. Un bloqueur de publicité fait disparaître les premières, un cache de page fait
disparaître les secondes. Les deux chiffres sont justes, ils ne mesurent pas la même chose.

== Changelog ==

= 0.4.0 =
* Les classements de l'écran « Statistiques » se déplient ligne par ligne, sur place : d'où vient le trafic d'une page (humains, robots, machines, codes de réponse, temps de traitement, provenance), et pour les autres classements, les pages lues avec cette valeur.
* « Ligne par ligne » ouvre en superposition chaque passage de l'adresse, paginé et filtrable par nature de visiteur, chaque ligne se dépliant sur son code HTTP, son temps de réponse, son adresse, son opérateur et son référent.
* Le dépliage d'une adresse montre volontairement tout le trafic, robots compris : le classement compte les pages vues par des humains, mais la question qu'on se pose en dépliant est justement « humain ou robot ? ». L'écran le dit.
* Toujours aucun JavaScript : le dépliage et la superposition sont des liens, et l'adresse les porte — un dépliage se partage et se recharge.

= 0.3.1 =
* Le journal ne qualifie plus d'« humaine » une requête venue d'un centre de données : la colonne « Visiteur » distingue maintenant trois natures — humain, robot, machine — et dit la même chose que les compteurs, qui écartaient déjà ces lignes. Une adresse louée chez un hébergeur, sous un nom de navigateur ordinaire, est une machine.
* Le raccourci « Machines » et le compteur « Robots déguisés » mènent aux lignes concernées.

= 0.3.0 =
* Les robots sont reconnus par les plages d'adresses que Google, Bing et Apple publient, et non plus seulement par ce que leur user-agent prétend : Googlebot apparaît même quand il est loin du classement par volume, une machine louée chez Google Cloud cesse d'être prise pour lui, et celui qui emprunte un nom sans venir de la bonne maison est signalé.
* Filtre par nature de contenu — accueil, article, page, catégorie, étiquette, auteur, archive, recherche — sur la vue d'ensemble et sur les statistiques, qui obéissent désormais toutes deux aux mêmes filtres.
* Le journal gagne les colonnes « Contenu » et « Réseau ».

= 0.2.1 =
* La période choisie suit d'un écran à l'autre : passer de la vue d'ensemble au journal ou aux robots garde les 30 ou 90 jours qu'on regardait. Un écran qui ne sait pas montrer douze mois ramène à la plus longue période qu'il accepte, au lieu de revenir à sa valeur par défaut.
* Le journal gagne quatre colonnes filtrables quand la localisation est en service : pays, ville, opérateur et numéro d'AS, avec une colonne « d'où » qui signale les adresses de centres de données.

= 0.2.0 =
* Deux écrans de synthèse : « Vue d'ensemble » (chiffres clés, filtres cumulés, graphique par heure, par jour ou par mois) et « Statistiques » (dix classements).
* Écran « URLs suspectes » : motifs cherchés, adresses essayées avec les codes reçus, adresses d'où viennent les sondes ; une sonde servie avec un 200 est signalée en tête.
* Vues enregistrées dans le journal : un filtre nommé se retrouve d'un clic.
* Localisation des adresses par ipinfo, en option et sur jeton : pays et ville, plafond mensuel, et détection des robots déguisés en navigateur depuis un centre de données.
* Les mises à jour apparaissent dans l'heure qui suit leur mise en ligne.

= 0.1.0 =
* Première version : journal des accès, écran Robots, conservation mesurée et budget d'espace.
* Écriture par fichier d'attente puis versement par lots ; écriture directe en base en secours.
* Filtres par colonne avec effectifs, raccourcis, suppression des lignes d'un filtre.
* Robots nommés d'après leur user-agent, et ceux des IA génératives étiquetés.
* Alertes : place disque, budget, échéance, croissance anormale, versement en panne.
