ZEP-11 : Interface de statistiques sur les tutoriels

Des chiffres, des graphes, du kikimeter !

a marqué ce sujet comme résolu.

Ok, donc on s'oriente donc vers une solution à base d'analyse de logs dans un premier temps. En regardant rapidement les logs existantes, sur 40 Mo de logs (~160 000 lignes) en une journée, les lignes qui nous intéressent sont celles qui sont liées aux requêtes de type GET sur le contenu. Enlevant tout ce qui est /forums, /media/, /static/, /membres/ il ne nous reste au final qu'environs 40 000 lignes de logs à parser et à stocker.

Le bonus étant que ça tiendrait même dans une BDD MySQL vu la forme des données.

Si ça convient à tout le monde, je mettrais à jour le premier POST dans ce sens en précisant la nouvelle architecture ainsi que les 7 métriques qu'on doit obtenir.

Si jamais ça peut aider, le script de parsing de logs utilisé par Piwik semble fait en Python.

Coyote

C'est clairement le genre d'outil qui pourrait être utile s'il était compatible python3 (à garder sur le coude si jamais la migration n'est pas trop compliquée).

Previously on ZEP-11 :soleil:

Pour obtenir des statistiques sur des tutoriels, on a le choix entre 2 types de fournisseurs de données.

  1. Les logs du serveur web : dans le cas de ZdS il s'agit des logs nginx qui nous permettent d'obtenir 7 métriques sur les 10 demandées par la communauté.
  2. Les données de Google Analytics : disponibles au travers d'une API, il s'agit de données déjà calculées. On ne dispose donc pas de données de références.

Nous étions partis sur l'option 2 avec GA comme fournisseur, mais nous nous sommes rendu compte que la forme des données rendues par l'API impliquait une volumétrie non adaptée à la capacité de stockage de ZdS (~400 Go par an).

L'option 1 quant à elle nous prive de 3 métriques sur 10, mais nous permet de rester dans des volumétries de stockages acceptables (le calcul n'est pas précis, mais on est dans la fourchette de 10Go à 15Go par an).

D’où la conclusion de partir sur l'option 1 et si à l'utilisation, les 3 métriques restantes nous manquent, les intégrer dans la v2 de la ZEP.

Voilà un petit récap'

les 3 métriques manquantes représente un fort pourcentage des votants comme "données que j'aimerais voir" ?

Eskimon

Si on considère que "Pourquoi pas" signifie plutôt pour, pour les trois métriques restantes, on a respectivement 82%, 76% et 88% des votants qui la veulent.

Donc oui, ça me semble être un fort pourcentage.

De toute façon, peu importe la solution choisie : ÀMHA il n'y a pas besoin d'une précision à la journée et il n'y a pas non plus besoin d'une mémoire infinie.

Une vision à la semaine, sur six mois, avec la possibilité pour les potentiels clients de l'API de sauvegarder au fur et à mesure (ce qui n'est pas une problématique du serveur, du coup), ça divise par 14 la taille estimée avec GA ;o. Ça ne serait pas suffisant ?

+0 -0

[…] sur six mois […]

Moui. A titre d'exemple le tuto Arduino a mis près de 3 ans a arriver dans l’état ou il est aujourd'hui (et c'est pas fini), perso j'aimerais bien voir sur plus long que 6 mois histoire de voir si par exemple l'ajout de chapitres fait venir de nouveaux visiteurs ou au contraire si c'est toujours stable et sans impact.

+0 -0

Et si on considere un "pourquoi pas" comme un "pas grave si on a pas !" ca fait combien de "oui je veux cette info !" ?

Eskimon

On revient à 82% (métrique 2) , 58%(métrique 8) et 82%(métrique 10).

Donc il ne reste plus que les métrique 2 et 10 de vraiment importantes statistiquement parlant.

Une vision à la semaine, sur six mois, avec la possibilité pour les potentiels clients de l'API de sauvegarder au fur et à mesure (ce qui n'est pas une problématique du serveur, du coup), ça divise par 14 la taille estimée avec GA ;o. Ça ne serait pas suffisant ?

lethom

Ce n'est pas le rôle des client de l'API de sauvegarder de l'information, pour la simple et bonne raison que l'information de référence doit provenir de ZdS. Si on veut être capable de suivre l'évolution d'un tutoriel sur 1 an, 2 an (ce qui n'est pas rare), on a pas trop le choix.

Du coup, pour avancer, j'embraye sur la question de l'API REST. Je vous propose la spécification suivante (n'hésitez pas à donner votre avis) :

Premier jet de spec pour l'API des statistiques

Par souci d’homogénéité avec les autres API du site, les paramètres de restrictions (throttling) seront les mêmes que sur les autres modules. C'est à dire qu'un client disposant d'une clé pour l'API aura un nombre de requêtes autorisés largement supérieur à un client sans clé. Il sera donc possible d’accéder à l'API sans avoir de clé.

La différence sera au niveau de la durée du cache sur les requêtes. Étant donné que le traitement d'analyse/parsing/stockage de logs sera fait une fois par jour, nous devons avoir une taille de cache de 24h, invalidé à chaque lancement de la procédure d'analyse.

Les verbes de l'API

Tout client de l'API (y compris le site) ne doit accéder à l'API uniquement au travers de la méthode GET, il s'agit donc d'une API en lecture seule.

Les paramètres des requêtes

Les paramètres des requêtes sont les variables que l'on passent à une url de l'API sous la forme http://api_url/?v1=x&v2=yv3=z. Dans cet exemple, v1, v2, v3 sont les paramètres de la requête.

Les paramètres sont tous facultatifs, et en cas de non renseignement d'un paramètre, la valeur par défaut sera celle spécifiée dans le fichier de paramètre (le settings.py) de zds.

Le module des statistique devra donc autoriser les paramètres suivants :

  • start_date : AAAAMMJJ.
  • end_date : AAAAMMJJ.
  • start_time : HHMMSS.
  • end_time : HHMMSS.
  • depth: Int. il s'agit de la profondeur du json rendu (voir l'exemple)
  • page : Int

J'ai un doute sur les paramètres nommés en anglais, mais en Français c'est pas très beau. Dites moi ce que vous en pensez

Les URLs de l'API

L'API devra mettre à disposition des clients les URLs suivantes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
/api/contenus/:content_type/:content_id/stats/visites/
/api/contenus/:content_type/:content_id/stats/visites/sources/
/api/contenus/:content_type/:content_id/stats/visites/plateformes/
/api/contenus/:content_type/:content_id/stats/visites/plateformes/os
/api/contenus/:content_type/:content_id/stats/visites/plateformes/navigateur
/api/contenus/:content_type/:content_id/stats/visites/geo/
/api/contenus/:content_type/:content_id/stats/visites/geo/continents/
/api/contenus/:content_type/:content_id/stats/visites/geo/continents/pays/
/api/contenus/:content_type/:content_id/stats/visites/geo/continents/pays/villes
/api/contenus/:content_type/:content_id/stats/visites/geo/pays/
/api/contenus/:content_type/:content_id/stats/visites/geo/pays/villes
/api/contenus/:content_type/:content_id/stats/visites/geo/villes
/api/contenus/:content_type/:content_id/stats/visites/geo/continents/
/api/contenus/:content_type/:content_id/stats/clics_interne/
  • :content_type : représente le type de conteneur (article, tutoriel, chapitre, partie)
  • :content_id : représente l'identifiant du conteneur sur zds

J'hésite à mettre à disposition l'url /api/contenus/stats/visites/ censée renvoyer les stats globales de chaque tutoriel. ça me semble nécessaire mais je n'ai aucune idée de ce que ça demande comme puissance de calcul. Normalement le cache devrait aider, mais je n'en sais rien au moment ou j'écris ces lignes.

Un json d'exemple

Voici ce que je vise comme structure de json sur l'url /api/contenus/:content_type/:content_id/stats/visites/ pour vous donner une idée. On voit que là on a toutes les informations demandées dans la spec.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
{
  "id" : "",
  "type": "",
  "total_visits" : 189,
  "uniques_visits": 86,
  "new_visits": 8,
  "avg_load_speed": 457,
  "sources" :[
      {
          "dns": "google.fr",
          "total_visits" : 189,
          "uniques_visits": 86,
          "new_visits": 8,
          "avg_load_speed": 157
      },
      {
          "dns": "twitter.com",
          "total_visits" : 14,
          "uniques_visits": 5,
          "new_visits": 0,
          "avg_load_speed": 447
      },
      {
          "dns": "yahoo.fr",
          "total_visits" : 189,
          "uniques_visits": 86,
          "new_visits": 8,
          "avg_load_speed": 401
      }
  ],
  "plateformes" : {
      "os": [
          {
              "name": "Windows",
              "version": "7",
              "total_visits" : 189,
              "uniques_visits": 86,
              "new_visits": 8,
              "avg_load_speed": 401
          },
          {
              "name": "Unknow",
              "version": "Unknow",
              "total_visits" : 189,
              "uniques_visits": 86,
              "new_visits": 8,
              "avg_load_speed": 401
          }
      ],
      "navigateur": [
          {
              "name": "Firefox",
              "version": "7",
              "total_visits" : 189,
              "uniques_visits": 86,
              "new_visits": 8,
              "avg_load_speed": 401
          },
          {
              "name": "Google Chrome",
              "version": "32",
              "total_visits" : 189,
              "uniques_visits": 86,
              "new_visits": 8,
              "avg_load_speed": 401
          }
      ]
  }
  "geo" : {
      "continents": {
          "pays": {
              "villes" : [
                  
              ]
          }
      },
      "pays": {
          "villes" : [
              
          ]
      },
      "villes" : [
          
      ]
  }
}

La aussi, j'ai l'impression que le mélange Français/Anglais est pas top, si vous voyez un moyen sympa, je suis prenneur

Voilà pour un premier jet de spec de l'API.

@pierre_24 : Ah, ce n'est pas ce que j'avais compris moi :( . En regardant le nouveau modèle de la ZEP-12, de ce que j'ai lu des commentaires, on retrouve bien le fameux content_type et content_pk, pour les contenus publiés.

A quel moment je me suis perdu du coup :( ?

Je ne vois pas le problème de mettre les mots en français. Genre, en quoi total_visits est plus glamour que « total_visites » et start_date plus sexy que « date_debut » ?

Sinon, si vous décidez quand même de le laisser en anglais, il faut mettre depth et non deep. ;)

Dominus Carnufex

ça me fait bizarre en français, mais c'est peut être moi. Sinon deep est corrigé (Eskimon l'avais déjà signalé :) )

@pierre_24 : Ah, ce n'est pas ce que j'avais compris moi :( . En regardant le nouveau modèle de la ZEP-12, de ce que j'ai lu des commentaires, on retrouve bien le fameux content_type et content_pk, pour les contenus publiés.

A quel moment je me suis perdu du coup :( ?

Tu ne t'es pas perdu, ils existent toujours. Ce que je veux dire par là, c'est qu'ils n'ont plus qu'un sens "sémantique" et non plus "physique", comme avant. Autrement dit, dans ce genre d'application, on pourrait s'en passer, et c'est pour ça que je soulève la question, en fait, si oui ou non c'est nécessaire de le préciser.

Ce que je veux dire par là, c'est qu'ils n'ont plus qu'un sens "sémantique" et non plus "physique", comme avant. Autrement dit, dans ce genre d'application, on pourrait s'en passer, et c'est pour ça que je soulève la question, en fait, si oui ou non c'est nécessaire de le préciser.

pierre_24

C'est bien le sens "sémantique" qui m'intéresse ici. Dans la logique REST, on va parler de ressource.

Le client de l'API qui voudra uniquement les statistiques des visites sur les articles n'aura qu'à requêter sur l'URL /api/contenus/article/stats/visites/. Si la notion de content_type n'existe pas, il devra se fader tous les types de contenu depuis l'url /api/contenus/, alors que le seul qui l’intéresse sont les articles.

Ce que je veux dire par là, c'est qu'ils n'ont plus qu'un sens "sémantique" et non plus "physique", comme avant. Autrement dit, dans ce genre d'application, on pourrait s'en passer, et c'est pour ça que je soulève la question, en fait, si oui ou non c'est nécessaire de le préciser.

pierre_24

C'est bien le sens "sémantique" qui m'intéresse ici. Dans la logique REST, on va parler de ressource.

Le client de l'API qui voudra uniquement les statistiques des visites sur les articles n'aura qu'à requêter sur l'URL /api/contenus/article/stats/visites/. Si la notion de content_type n'existe pas, il devra se fader tous les types de contenu depuis l'url /api/contenus/, alors que le seul qui l’intéresse sont les articles.

firm1

… Ou préciser ?type=machin. Mais ok, je vois la logique, donc j'ai rien dit ;)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte