menu
  Home  ==>  articles  ==>  web  ==>  les_logs_http_bruts   

Les logs HTTP bruts - John COLIBRI.

  • mots clé:programmation web - utilitaire de gestion de site - log
  • logiciel utilisé: Windows 98, Delphi 5.0
  • matériel utilisé: Pentium 500Mhz, 128 M de mémoire
  • champ d'application: Delphi 1 à 6 sur Windows, Kylix
  • niveau: débutant en Pascal et Delphi
  • plan:


1 - Introduction: Analyse de Fréquentation

Pour analyser la fréquentation de son site, nous disposons de plusieurs outils:
  • des compteurs
  • des scripts
  • des logs (journaux) du serveur

1.1 Les Compteurs

De nombreuses pages comportent des compteurs. L'internaute stupéfait est ainsi informé qu'il est le 18 ième depuis le 7 Mars 1996, ou le 348.798 depuis ce matin. Soit. Quel intérêt pour l'internaute ? Aucun. Strictement aucun. L'auteur du site, en revanche y voit le même intérêt que les bistrots qui s'empressent de vous placer près de la fenêtre pour attirer les autres clients. Il est évident qu'une salle vide incite peu le consommateur à entrer. De la même façon, un site très fréquenté et un logiciel téléchargé des milliers de fois ne peuvent être que bons. Plus importante est la statistique, meilleur est le produit. Ben voyons. Ce type de statistique, facilement modifiable par le propriétaire du site, possède la même fiabilité que la publication par Apple du nombre d'appareils Apple vendus. Et exactement le même intérêt pour le visiteur.

Ces compteurs fonctionnent à partir d'un petit programme qui est exécuté sur le serveur chaque fois que quelqu'un charge la page. Le programme peut être un CGI (en Perl, Python ou autre PHP, JavaScript etc, ou en Pascal, Delphi).

Si le but est uniquement de connaître la fréquentation, il est possible de rendre le compteur invisible: le programme exécuté sur le serveur incrémente le nombre de visiteur dans un fichier du serveur, mais ne présente pas la valeur du compteur au visiteur.

C'est la solution que j'étais prêt à utiliser. Sauf que ce type de mécanique se met en branle systématiquement, y compris, et malheureusement pour les pages sauvegardées en local. Chaque fois que vous appelez une page stockée sur votre PC et que le dialogue de connection Windows s'ouvre, vous avez affaire à un script placé sur la page.

Comme je souhaitais être aussi transparent dans mon analyse que possible, cette solution fut rejetée. Mon souci est de fournir l'information avec le minimum de parasitage pour l'utilisateur. Si je publie c'est pour être lu, pas pour donner l'impression de fliquage aux lecteurs.

1.2 Les logs bruts

Il existe une autre solution pour analyser son audience: les logs bruts du serveur. Tous les serveurs industriels (et à fortiori sans doute les serveurs persos) peuvent créer des journaux documentant les appels effectués. Ces logs se trouvent en fait sur tous les types de serveur. Je me souviens d'avoir crapahuté jadis dans les logs d'Oracle, ou ceux de PerfMon sur Windows NT.

Le contenu et le format des logs varient naturellement avec le type de serveur et peuvent aussi éventuellemnt être désarmés ou paramétrés par l'administrateur du serveur. Trop de log dégrade la performance du serveur, pas assez rend la détection d'anomalies difficile, voire impossible.

Il se trouve qu'en ce qui concerne les logs de serveurs HTTP, il existe une norme, qui est celle d'Apache, légèrement modifiés par IIS (Internet Information Server de Microsoft). Nous présenterons le détail du log ci-dessous, mais il contient à l'évidence des informations:

  • de date et d'heure
  • sur le serveur (son adresse)
  • sur la requête (adresse du visiteur, type de requête, durée, page demandée)

1.3 Les critiques

De nombreux logiciels proposent des outils d'analyse des logs. Certains en domaine public, en source, d'autres commerciaux. Tout le spectre allant du gratuit au très cher. Et les plus chers vous expliquent naturellement pourquoi ces outils réaliseront des miracles pour analyser et régler votre site.

C'est pourquoi des personnes plus honnêtes ont écrit plusieurs articles critiquant plus ou moins vivement l'utilité des logs en tant qu'outils d'analyse de fréquentation.

Parmi les critiques, citons:

  • tout d'abord, l'utilisation par le Web de caches de pages à de multiples niveaux
    • au niveau du réseau:
      • les différents noeuds cachent les pages souvent appelées
      • des sites miroir peuvent aussi contenir des copies de vos pages, à la demande du propriétaire du site ou à son insu. Une fois qu'une page est publiée, nous ne la contrôlons plus: elle peut être stockée quelque part, et resurgir dans deux ou trois ans. Gênant pour les mises à jour, mais c'est comme cela
      Et naturellement lorsqu'un utilisateur appelle une page, si elle est trouvée dans un cache, c'est cette page qui est fournie, sans que votre serveur (ni son log par conséquent) ne le sache. C'est le but même d'un cache !
      De façon caricaturale, plus cela marche, moins vous en saurez:
      • si peu de personnes vous visitent, les caches automatiques du réseau ne contiendront pas vos pages, et vous saurez absolument tout sur les deux ou trois pingoins qui se sont égaré chez vous.
      • si votre site remporte un grand succès, la plupart de vos pages seront en plusieurs copies loin de votre serveur, et le log reflètera de moins en moins l'activité furieuse des foules en délire.
    • les navigateurs cachent aussi les pages en local. Lorsque le visiteur clique sur "back", c'est en général la copie locale qui est appelée
  • la seconde série de critique concerne l'identification du visiteur. Le log ne contient en général que l'URL du visiteur. "153.109.21.100" et pas "Casimir Dugenou des Galeries Farfouillettes". Et il n'est pas possible dans la majorité des cas de remonter de l'URL à l'internaute ou même à la société:
    • la plupart des internautes utilisent des fournisseurs d'accès qui attribuent dynamiquement les adresses IP (pooling). Donc:
      • Un même internaute se connectant à 10 minutes d'intervalle aura en général une adresse IP différente.
      • Laquelle URL peut être utilisée un jour plus tard par une personne différente.
    • et même si, par chance, il s'agit d'une société ayant un accès direct (un numéro IP fixe), la personne fera partie, par définition, de la société. Oui mais quelle personne ?

1.4 Alors Quelle Utilité ?

Les logs me semblent permettre plusieurs types d'analyses:
  • les indications de "tendance":
    • le niveau global est une première information: 100 par semaine ou 1000 par jour permettent d'évaluer l'efficacité du site
    • même si les caches masquent une partie du trafic réel, les variations restent significatives. Une baisse sur plusieurs mois révèle une désaffection qu'il convient sans doute de corriger
  • les statistiques par page:
    • elles peuvent indiquer un problème de navigation: une page que vous souhaitez voir utiliser (un bon de commande, par exemple) n'est pas assez visitée. Les statistiques fourniront une indication du problème mais pas la solution: faut-il changer la page de place, ou améliorer l'attrait du chemin qui y conduit. Un peu comme un super-marché: faut-il mettre le lait à l'entrée ou obliger le chaland à parcourir le magasin en espérant qu'il achètera autre chose
  • le cheminement dans les pages
    • certains articles indiquent que 35 % des internautes ne dépassent pas le second click. Il semble donc fondamental que la première page l'intéresse. Le log peut fournir ici une information précieuse.
    • le nombre de pages, le temps passé, le nombre d'octets téléchargés sont d'autre mesure de même nature. Un peu comme le remplissage moyen du caddy dans un super marché
    • il est même possible d'analyser des "profils type": ceux qui se précipitent sur les téléchargement, ceux qui regardent les blagues etc.
    Notez que les caches peuvent ici aussi fausser l'information. Si le visiteur clique sur "Back", le log ne le verra pas. Le suivi rigoureux du cheminement dans le site n'est donc pas possible avec le log seul.
    Et certaines analyses peuvent être poussées au niveau du mouvement de la souris; mais pas avec les logs, dont ce n'est pas du tout la vocation. Seuls la Redoute ou la Fnac peuvent être intéressés par ce type d'analyse. Et lorsque les enjeux sont de cette taille, je pense qu'il est plus efficace d'entasser une vingtaine d'utilisateurs dans une pièce avec des glaces sans tain et une solide équipe de psys derrière guettant leur moindre froncement de sourcil. Technique marketing grand public de base...

1.5 Les Autres Informations

Pour mon premier site sur Free, j'utilisais les statistiques fournies par Free:
  • par page, le nombre de visiteurs, le volume
  • des informations sur le type de navigateur, le type d'OS
La principale critique de leurs statistiques concerne le nombre de visiteurs et le volume: je n'ai aucune idée de ce qui est mesuré:
  • comment est mesuré le nombre de visiteurs:
    • les programmes d'analyse de logs utilisent en général une règle heuristique pour définir un visiteur. Comme les fournisseurs d'accès recyclent les URLs, le compte du nombre d'URLs différentes ne sert à rien: il minore le nombre réel de visiteur. La contiguité des URLs est aussi illusoire lorsque le volume augmente, car plusieurs visiteurs font des appels entrelacés. Et la même URL peut alors provenir d'une autre personne. Des règles du style "un visiteur reste connecté 5 minutes en moyenne, donc la même URL au bout de 5 minutes correspond à un autre visiteur". 5 minutes ? 2 peut-être ? Et pourquoi pas 30 secondes ? En fait le fournisseur souhaite le succès de votre site. Tout chiffre allant dans ce sens ne peut faire que plaisir au client. Il doit donc être examiné avec suspicion.
    • mi octobre, j'avais demandé le référencement de mon site par Alta Vista, Google etc. 4 à 6 semaines, sans garantie. Et brusquement le 3 Décembre j'ai eu 80 visiteurs en un jour. A l'évidence l'un de ceux-là était passé par là. Rien dans les statistiques Free ne me signale qu'il s'agit de référenceur ou d'outils d'analyse automatique et non pas de visiteurs normaux
  • le plus grave, et qui fut réellemnent un des éléments qui m'incita à quitter Free fut l'impossibilité de réconcilier "le jour", "les derniers 7 jours" et "le mois".
    • comme j'avais commencé le site le 10 octobre, "le mois" ne pouvait être que le total de toutes les visites. Que nenni: 3 visiteurs le mercredi, fournissant un total de 0 pour les sept derniers jours. J'imagine qu'ils font une moyenne glissante, Pour glisser, elle glisse, mais comment, ou sur quoi glisse-t-elle: mystère.
    • si certaines pages n'étaient pas visitées dans la journée ou la semaine, la ligne disparaît complètement. Il s'agirait donc d'une espèce de loupe sur les derniers jours, sans cumul de tout ce qui s'est réellement passé. Ce qui oblige donc pour récupérer les cumuls réels à télécharger les stats quotidiennes tous les jours et réaliser ses moyennes soi-même. Naturellement il faut alors se connecter tous les jours, retrouver le mot de passe, attendre la réponse, retaper le mot de passe erronnée etc. Bref, une mécanique Minitel Rose des plus classiques.
Quant aux statistiques sur la résolution d'écran, le type de navigateur ou d'OS, je n'y attache pas grande importance:
  • mes pages sont construites sans grand effort graphique actuellement. Le réglage au pixel près n'est donc pas utile. De plus je ne contrôle pas ce que le visiteur souhaite utiliser comme navigateur ou sa résolution
  • le type d'OS me laisse froid: je travaille avec Linux, mais je navigue sous Windows 95. Pour des raisons historiques. Peu d'espoir donc de savoir à partir de ces statistiques s'il vaut mieux écrire des articles pour Windows ou pour Linux. Et de toutes les façons les statistiques sont relativement stables: 98 % de Windows, 2 % de Linux ou autre, et pratiquement jamais de Mac. Et en gros 50 % d'Internet Explorer et 50 % de NetScape. Voilà, tout est dit. Les histogrammes sophistiqués et les camemberts coloriés n'y changeront rien. Et ceci pour les 3 ans à venir.
Mentionnons que ce type d'information (résolution, navigateur, OS) n'est PAS dans les logs: il est obtenu par des scripts qui interrogent le visiteur lorsqu'il appelle une page. Une raison de plus, à mes yeux, pour ne pas récupérer ces informations.

1.6 Le format des logs

Les logs existent sous deux format principaux:
  • IIS
  • Common Log Format (Unix / Apache)
Je ne présenterai que le format IIS, mon fournisseur étant sous NT. Ce format ne diffère du format Unix que par la présence du code d'erreur NT et l'ordre des paramètres.

Voici un exemple d'une ligne du log:

153.109.21.100, -, 09/05/2001, 17:40:33, W3SVC4, S3, 192.168.1.246, 0, 487, 3387, 404, 3, GET, /pfstats/stats.dll/add, idbase=talkMe&idSrv=12&id=125&IDelai=1&rs=1024x768&sc=16&pg=http%3A//www.talkme.net/&ref=,?

La syntaxe est une suite de paramètres séparés par des virgules. Cette ligne comporte actuellement 15 paramètres:

  • l'adresse IP de celui qui a effectué la requête
  • le nom de l'utilisateur. Ce champ n'est documenté que pour les sites exigeant que l'utilisateur s'identifie, ce qui n'est pas le cas de son site
  • la date
  • l'heure
  • le service
  • le nom du serveur (la machine de mon hébergeur)
  • l'url du serveur
  • le temps écoulé
  • les octets reçus
  • les octets envoyés
  • le code de status HTTP de la requête (200= ok, pas de problème)
  • le code de status NT
  • referrer: a cliqué sur une page "mes liens"
  • la méthode (GET par exemple)
  • la page visée
  • les paramètres
Auraient pu être ajoutés:
  • User Agent: permet de détecter si un Spider (programme de visite automatique) a été utilisé
  • Cookie
  • Referer: par quel biais la page a été atteinte (via une page "les liens de Dugenou" par exemple)

1.7 - Exemple de log brut

Pour avoir une idée de la différence entre les logs bruts et les logs filtrés,
Voici, à titre d'exemple, quelques lignes extraites du 6 Décembre 2001 (le second jour où le site était ouvert):

209.73.162.171, -, 06/12/2001, 04:49:12, W3SVC37, S3, 192.168.1.230, 481, 129, 3351, 200, 0, GET, /index.html, -,
209.73.162.171, -, 06/12/2001, 04:49:13, W3SVC37, S3, 192.168.1.230, 481, 151, 4121, 200, 0, GET, /articles/articles.html, -,
209.73.162.171, -, 06/12/2001, 05:08:37, W3SVC37, S3, 192.168.1.230, 260, 138, 2796, 200, 0, GET, /menu.html, -,
213.228.29.10, -, 06/12/2001, 06:08:42, W3SVC37, S3, 192.168.1.230, 961, 288, 3355, 200, 0, GET, /index.html, -,
213.228.29.10, -, 06/12/2001, 06:08:42, W3SVC37, S3, 192.168.1.230, 0, 336, 141, 304, 0, GET, /menu.html, -,
213.228.29.10, -, 06/12/2001, 06:08:42, W3SVC37, S3, 192.168.1.230, 10, 349, 141, 304, 0, GET, /edito/edito_frame.html, -,
213.228.29.10, -, 06/12/2001, 06:08:42, W3SVC37, S3, 192.168.1.230, 0, 339, 140, 304, 0, GET, /ip4.jpeg, -,
213.228.29.10, -, 06/12/2001, 06:08:42, W3SVC37, S3, 192.168.1.230, 0, 365, 141, 304, 0, GET, /edito/edito_top.html, -,
213.228.29.10, -, 06/12/2001, 06:08:43, W3SVC37, S3, 192.168.1.230, 11, 361, 141, 304, 0, GET, /edito/edito.html, -,
66.130.158.58, -, 06/12/2001, 08:12:04, W3SVC37, S3, 192.168.1.230, 361, 370, 3351, 200, 0, GET, /index.html, -,
66.130.158.58, -, 06/12/2001, 08:12:04, W3SVC37, S3, 192.168.1.230, 160, 369, 2796, 200, 0, GET, /menu.html, -,
66.130.158.58, -, 06/12/2001, 08:12:04, W3SVC37, S3, 192.168.1.230, 160, 382, 1982, 200, 0, GET, /edito/edito_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:12:04, W3SVC37, S3, 192.168.1.230, 160, 247, 3414, 200, 0, GET, /ip4.jpeg, -,
66.130.158.58, -, 06/12/2001, 08:12:04, W3SVC37, S3, 192.168.1.230, 180, 402, 1812, 200, 0, GET, /edito/edito_top.html, -,
66.130.158.58, -, 06/12/2001, 08:12:04, W3SVC37, S3, 192.168.1.230, 190, 398, 8459, 200, 0, GET, /edito/edito.html, -,
66.130.158.58, -, 06/12/2001, 08:12:21, W3SVC37, S3, 192.168.1.230, 10, 182, 0, 200, 0, GET, /404.asp, 404;http://www.jcolibri.com/favicon.ico,
66.130.158.58, -, 06/12/2001, 08:13:29, W3SVC37, S3, 192.168.1.230, 180, 456, 2022, 200, 0, GET, /entre_nous/entre_nous_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:13:29, W3SVC37, S3, 192.168.1.230, 170, 477, 1832, 200, 0, GET, /entre_nous/entre_nous_top.html, -,
66.130.158.58, -, 06/12/2001, 08:13:29, W3SVC37, S3, 192.168.1.230, 451, 473, 3358, 200, 0, GET, /entre_nous/entre_nous.html, -,
66.130.158.58, -, 06/12/2001, 08:13:37, W3SVC37, S3, 192.168.1.230, 170, 452, 2006, 200, 0, GET, /articles/articles_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:13:37, W3SVC37, S3, 192.168.1.230, 160, 469, 1824, 200, 0, GET, /articles/articles_top.html, -,
66.130.158.58, -, 06/12/2001, 08:13:37, W3SVC37, S3, 192.168.1.230, 360, 465, 4121, 200, 0, GET, /articles/articles.html, -,
66.130.158.58, -, 06/12/2001, 08:14:17, W3SVC37, S3, 192.168.1.230, 181, 486, 2081, 200, 0, GET, /articles/pascal_to_html/pascal_to_html_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:14:17, W3SVC37, S3, 192.168.1.230, 160, 511, 1953, 200, 0, GET, /articles/pascal_to_html/pascal_to_html_top.html, -,
66.130.158.58, -, 06/12/2001, 08:14:17, W3SVC37, S3, 192.168.1.230, 360, 507, 14557, 200, 0, GET, /articles/pascal_to_html/pascal_to_html.html, -,
66.130.158.58, -, 06/12/2001, 08:15:37, W3SVC37, S3, 192.168.1.230, 170, 488, 2089, 200, 0, GET, /articles/colibri_helpers/colibri_helpers_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:15:37, W3SVC37, S3, 192.168.1.230, 170, 515, 1957, 200, 0, GET, /articles/colibri_helpers/colibri_helpers_top.html, -,
66.130.158.58, -, 06/12/2001, 08:15:37, W3SVC37, S3, 192.168.1.230, 521, 511, 7282, 200, 0, GET, /articles/colibri_helpers/colibri_helpers.html, -,
66.130.158.58, -, 06/12/2001, 08:16:40, W3SVC37, S3, 192.168.1.230, 181, 462, 2046, 200, 0, GET, /presentations/presentations_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:16:40, W3SVC37, S3, 192.168.1.230, 160, 489, 1843, 200, 0, GET, /presentations/presentations_top.html, -,
66.130.158.58, -, 06/12/2001, 08:16:40, W3SVC37, S3, 192.168.1.230, 511, 485, 3096, 200, 0, GET, /presentations/presentations.html, -,
66.130.158.58, -, 06/12/2001, 08:16:52, W3SVC37, S3, 192.168.1.230, 180, 515, 2151, 200, 0, GET, /presentations/soap_et_midas_colibri/soap_et_midas_colibri_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:16:52, W3SVC37, S3, 192.168.1.230, 170, 549, 2001, 200, 0, GET, /presentations/soap_et_midas_colibri/soap_et_midas_colibri_top.html, -,
66.130.158.58, -, 06/12/2001, 08:16:52, W3SVC37, S3, 192.168.1.230, 190, 545, 5711, 200, 0, GET, /presentations/soap_et_midas_colibri/soap_et_midas_colibri.html, -,
66.130.158.58, -, 06/12/2001, 08:17:32, W3SVC37, S3, 192.168.1.230, 180, 460, 2038, 200, 0, GET, /pascalissime/pascalissime_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:17:32, W3SVC37, S3, 192.168.1.230, 160, 485, 1840, 200, 0, GET, /pascalissime/pascalissime_top.html, -,
66.130.158.58, -, 06/12/2001, 08:17:32, W3SVC37, S3, 192.168.1.230, 180, 481, 5286, 200, 0, GET, /pascalissime/pascalissime.html, -,
66.130.158.58, -, 06/12/2001, 08:18:00, W3SVC37, S3, 192.168.1.230, 171, 448, 1990, 200, 0, GET, /livres/livres_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:18:00, W3SVC37, S3, 192.168.1.230, 160, 461, 1816, 200, 0, GET, /livres/livres_top.html, -,
66.130.158.58, -, 06/12/2001, 08:18:00, W3SVC37, S3, 192.168.1.230, 500, 457, 9738, 200, 0, GET, /livres/livres.html, -,
66.130.158.58, -, 06/12/2001, 08:18:07, W3SVC37, S3, 192.168.1.230, 170, 458, 2029, 200, 0, GET, /telecharger/telecharger_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:18:07, W3SVC37, S3, 192.168.1.230, 170, 481, 1835, 200, 0, GET, /telecharger/telecharger_top.html, -,
66.130.158.58, -, 06/12/2001, 08:18:07, W3SVC37, S3, 192.168.1.230, 201, 477, 8620, 200, 0, GET, /telecharger/telecharger.html, -,
66.130.158.58, -, 06/12/2001, 08:18:35, W3SVC37, S3, 192.168.1.230, 190, 486, 2059, 200, 0, GET, /stages/transparents/transparents_frame.html, -,
66.130.158.58, -, 06/12/2001, 08:18:35, W3SVC37, S3, 192.168.1.230, 170, 499, 1936, 200, 0, GET, /stages/transparents/transparents_top.html, -,
66.130.158.58, -, 06/12/2001, 08:18:35, W3SVC37, S3, 192.168.1.230, 371, 495, 5855, 200, 0, GET, /stages/transparents/transparents.html, -,

Vous constaterez que:

  • certaines zones sont sans aucun intérêt:
    • le nom utilisateur est toujours "-"
    • le service NT est W3SVC37 et ne change jamais (dans mon cas)
    • idem pour la machine qui est S3. Soit.
    • idem pour l'URL du serveur 192.168.1.230
  • les pages visitées, quasiment la partie la plus utile, comportent tout le chemin de la page demandée

1.8 - Exemple de log filtré

En débarrassant ce log d'information sans intérêt pour nous, nous obtenons:

209.73.162.171 06 04:49: 481 129 3351 GET index.html
209.73.162.171 06 04:49: 481 151 4121 GET articles.html
209.73.162.171 06 05:08: 260 138 2796 GET menu.html
213.228.29.10 06 06:08: 961 288 3355 GET index.html
213.228.29.10 06 06:08: 0 336 141 GET menu.html
213.228.29.10 06 06:08: 10 349 141 GET edito_frame.html
213.228.29.10 06 06:08: 0 339 140 GET ip4.jpeg
213.228.29.10 06 06:08: 0 365 141 GET edito_top.html
213.228.29.10 06 06:08: 11 361 141 GET edito.html
66.130.158.58 06 08:12: 361 370 3351 GET index.html
66.130.158.58 06 08:12: 160 369 2796 GET menu.html
66.130.158.58 06 08:12: 160 382 1982 GET edito_frame.html
66.130.158.58 06 08:12: 160 247 3414 GET ip4.jpeg
66.130.158.58 06 08:12: 180 402 1812 GET edito_top.html
66.130.158.58 06 08:12: 190 398 8459 GET edito.html
66.130.158.58 06 08:12: 10 182 0 GET *** /404.asp 404;http://www.jcolibri.com/favicon.ico
66.130.158.58 06 08:13: 180 456 2022 GET entre_nous_frame.html
66.130.158.58 06 08:13: 170 477 1832 GET entre_nous_top.html
66.130.158.58 06 08:13: 451 473 3358 GET entre_nous.html
66.130.158.58 06 08:13: 170 452 2006 GET articles_frame.html
66.130.158.58 06 08:13: 160 469 1824 GET articles_top.html
66.130.158.58 06 08:13: 360 465 4121 GET articles.html
66.130.158.58 06 08:14: 181 486 2081 GET pascal_to_html_frame.html
66.130.158.58 06 08:14: 160 511 1953 GET pascal_to_html_top.html
66.130.158.58 06 08:14: 360 507 14557 GET pascal_to_html.html
66.130.158.58 06 08:15: 170 488 2089 GET colibri_helpers_frame.html
66.130.158.58 06 08:15: 170 515 1957 GET colibri_helpers_top.html
66.130.158.58 06 08:15: 521 511 7282 GET colibri_helpers.html
66.130.158.58 06 08:16: 181 462 2046 GET presentations_frame.html
66.130.158.58 06 08:16: 160 489 1843 GET presentations_top.html
66.130.158.58 06 08:16: 511 485 3096 GET presentations.html
66.130.158.58 06 08:16: 180 515 2151 GET soap_et_midas_colibri_frame.html
66.130.158.58 06 08:16: 170 549 2001 GET soap_et_midas_colibri_top.html
66.130.158.58 06 08:16: 190 545 5711 GET soap_et_midas_colibri.html
66.130.158.58 06 08:17: 180 460 2038 GET pascalissime_frame.html
66.130.158.58 06 08:17: 160 485 1840 GET pascalissime_top.html
66.130.158.58 06 08:17: 180 481 5286 GET pascalissime.html
66.130.158.58 06 08:18: 171 448 1990 GET livres_frame.html
66.130.158.58 06 08:18: 160 461 1816 GET livres_top.html
66.130.158.58 06 08:18: 500 457 9738 GET livres.html
66.130.158.58 06 08:18: 170 458 2029 GET telecharger_frame.html
66.130.158.58 06 08:18: 170 481 1835 GET telecharger_top.html
66.130.158.58 06 08:18: 201 477 8620 GET telecharger.html
66.130.158.58 06 08:18: 190 486 2059 GET transparents_frame.html
66.130.158.58 06 08:18: 170 499 1936 GET transparents_top.html
66.130.158.58 06 08:18: 371 495 5855 GET transparents.html

En examinant ces lignes, vous imaginez sans aucune peine ce que nous pouvons ou non en tirer. Juste quelques commentaires:

  • les nouveaux arrivants démarrent en "index.html". Cela ne sera pas toujours le cas si les utilisateurs conservent des liens vers d'autres pages.
  • une erreur 404 est survenue. Il traîne donc encore des liens erronnés. A examiner lorsque l'article sera terminé
  • certaines pages sont sans intérêt (le jpeg du logo, les frames xxx_frame.html et xxx_top.html)

Exemple de log analysé

A titre d'exemple, voici un exemple simple d'analyse de pages effectué sur le même échantillon:

Users:  
  count: 3
  time_by_user: 3498
  pages_by_user: 7,3

pages:    
  edito.html 2 (  201)
  articles.html 2 (  841)
    colibri_helpers.html 1 (  521)
    pascal_to_html.html 1 (  360)
  stages.html    
    transparents.html 1 (  371)
  presentations.html 1 (  511)
    soap_et_midas_colibri.html 1 (  190)
  pascalissime.html 1 (  180)
  livres.html 1 ( 500)
  entre_nous.html 1 ( 451)
  telecharger.html 1 ( 201)
       
  total_html 13  

Other pages:  
  *** /404.asp 404;http://www.jcolibri.com/favicon.ico 1
  index.html 3
  ip4.jpeg 2
  menu.html 3

Il y a quelques incohérences dans cette présentation car Index.html et les erreurs ne sont pas traitées de la même façon par les différents cumuls. Là n'est pas le plus important: ces statistiques nous permettent de détecter plusieurs informations:

  • notre site comporte des erreurs
  • "35 % des utilisateurs" à moi ne sont pas partis, eux, au bout d'un clic. Non mais...
  • "transparents" a été cliqué sans passer par "stages". L'examen du log séquentiel montre le saut de "télécharger" à "télécharger les transparents des stages". Ce que nous avions prévu, mais qui est confirmé au bout de deux jours...
Etc, etc, etc. La "logologie" s'acquiert avec le temps, et n'est qu'une question de vieilles casseroles et de bonnes soupes. Allez, encore un exemple:
  • j'ai été surpris du nombre de visiteurs consultant mon CV. Celui-ci avait été rédigé car Becker Avionics (le Dassault allemand) envisageait d'utiliser nos services en programmation Delphi. A tout hasard j'ai donc inclus le CV au site, au cas où les Suédois, les Italiens...
  • 9 personnes ont consulté mon CV en trois jours. A n'en pas douter, plusieurs chasseurs de tête sortant tout droit du bureau de Lagardère ou Arnault allaient me téléphoner dans l'heure.
  • en attendant, oui, en attendant, j'ai continué à ecrire le présent article. J'ai ajouté le cumul de millisecondes par page. Cette valeur devenant trop importante, je l'ai converti en secondes, et divisé par le nombre d'accès. Pour le CV, le résultat fut de 0.7 secondes. Essayez de lire un CV en 0.7 secondes. Chez Compétences, j'ai appris à évaluer professionellement les gens rapidement. Mais en 0.7 secondes non. Adieu veau, vache, cochon, couvée...
  • quoique. Quoique ! 0.7 ne veut rien dire du tout: peut-être 8 zigs sont entrées et sortis sur le champ, et UNE personne, la bonne, a lu, ou récupéré le CV sur son PC pour le lire à tête reposée. Rien n'est donc perdu: ce site s'auto-détruira lorsque le téléphone sonnera enfin. D'ici là, et en attendant, la moralité est que les statistiques sont fort utiles, mais leur interprétation exige un peu de bon sens, et encore plus, sans doute, quelques grains d'humour.

2 - Utilisation

2.1 Mise en oeuvre

Une fois que vous avez vu les logs réels et le type de simplification puis d'analyse, il est enfantin de créer un projet Delphi qui triturera ces logs ad nauseam.

Nous allons simplement présenter ici notre mécanique, fort conscient qu'elle peut être enjolivée sans grande difficulté.

p_http_raw_logs a pour but de permettre:

  • la création d'un fichier binaire de stockage de fichiers de log au format IIS
  • l'ajout de fichiers ASCII ayant le des logs IIS
  • la création de statistiques telles que celles présentées ci-dessus
Pour utiliser ce programme:
  • placez le fichier de log de IIS dans le répertoire data
  • modifiez le nom du fichier dans p_http_raw_logs et compilez
  • si le fichier binaire n'existe pas encore, cliquez "create"
  • ajoutez le fichier en cliquant "append"
  • listez le log appuré en cliquant "list"
  • présentez quelques statistiques en cliquant "stats"

2.2 - Répertoires et Directives de Compilation

L'unité est prévue pour être placée dans:

C:
  programs
    colibri_utilities
      web
       http_raw_logs
         data

Vous pouvez naturellement changer cette organisation par Projet | Options | Directories

Les directives de compilation sont:

  • R+ (vérification des intervalles)
  • S+ (vérification de la pile)
  • pas d'optimisation

3 - Programmation

3.1 Organisation générale

Fondamentalement le programme ne fait qu'analyser un fichier ASCII dont les champs sont délimités par des virgules. Ce format a été adopté par Microsoft pour rendre l'importation par de nombreux outils facile. J'imagine que Word ou Excel savent faire cela très bien.

Personnellement Word me donne des boutons et je n'ai jamais touché à Excel. Et Delphi fait cela encore mieux.

Notre programme analyse donc chaque ligne du Log et place les informations dans des fichiers disques.

Pour les fichiers, deux options s'ouvraient:

  • soit des fichier FILE ayant le format approprié
  • soit mécanique de base de données telle qu'Interbase
Pour le moment et pour faciliter la mise au point, j'ai opté pour les FILE. L'organisation est la suivante:

3.2 La classe c_http_raw_logs

Cette classe gère le fichier des logs. Elle contient un enregistrement pour chaque ligne de log.

Dans la version simplifiée actuelle, nous avons traité tous les enregistrement de la même façon en plaçant tout dans le fichier variable. L'enregistrement est donc simplement un tableau des numéros de fiches dans le fichier d'accès direct aux données de taille variable.

Les types de chaque champ sont définis par un énuméré:

    type t_field_type= (e_client_ip,
                        e_user_namee_datee_timee_servicee_computer_name,
                        e_server_ipe_elapsed_timee_bytes_receivede_bytes_sent,
                        e_status_codee_windows_status_codee_GET_or_POST,
                        e_targete_paramse_end);

La classe elle-même a la définition suivante:

    type c_http_raw_logsclass(c_basic_file)
                            public
                              // -- the positions in the direct access variable file
                              m_log_recordarray[e_client_ip..e_paramsof Integer;

                              m_c_direct_access_variable_filec_direct_access_variable_file;

                              constructor create_http_raw_logs(p_namep_file_nameString); Virtual;

                              function f_force_createBooleanOverride;
                              function f_openBooleanOverride;
                              procedure close_fileOverride;

                              procedure append_log(p_ascii_file_nameString);

                              procedure read_record;

                                function f_read_field(p_field_typet_field_type): String;
                              function f_client_ipString;
                              function f_dateString;
                              function f_timeString;
                              function f_elapsed_timeString;
                              function f_bytes_receivedString;
                              function f_bytes_sentString;
                              function f_status_codestring;
                              function f_GET_or_POSTString;
                              function f_targetString;
                              function f_paramsString;

                              function f_the_day_and_timeString;
                              function f_target_and_paramsString;

                              function f_elapsed_time_valueInteger;

                              procedure display_record;

                              destructor DestroyOverride;
                          end;

Les attributs sont les suivants:

  • m_log_record: le tableau contenant les positions dans le fichier d'accès direct de chaque champ du log
  • m_c_direct_access_variable_file: le fichier d'accès direct (qui contiendra une entrée pour chaque champ)
Les méthodes sont les suivantes:
  • create_http_raw_logs: construit la classe
  • les méthodes de gestion globales du fichier: f_force_create, f_open, close_file
  • append_log: ajoute au fichier binaire toutes les lignes d'un log NT ASCII
  • read_record: lit un enregistrement dans la fiche courante en mémoire
  • les fonctions qui retournent les chaînes correspondant aux champs qui nous intéressaient:
    • f_read_field: fonction générique de lecture de champ
    • f_client_ip, f_date, f_time, f_elapsed_time, f_bytes_received, f_bytes_sent, f_status_code, f_GET_or_POST, f_target, f_params: les champs qui nous intéressent
    • f_the_day_and_time: calcul d'une date simplifiée (jour heure minute)
    • f_target_and_params: la page demandée
    • f_elapsed_time_value: la valeur numérique de temps passé dans une page
  • display_record: affichage de la ligne simplifiée
Parmi les défauts actuels les plus flagrants figure l'utilisation du fichier variable pour TOUS les champs. Il est évident que c_http_raw_logs devrait stocker les champs Integer, date et heure directement (et non pas en ASCII de taille variable, avec en plus les redondances de notre format variable). Mon principal objectif était d'obtenir au départ quelques informations sur "mes" logs. L'optimisation sera faite ultérieurement en cas de besoin.

3.3 La classe c_http_raw_log_pages

Cette unité gère les statistiques par page web. Pour chaque page, elle contient le nombre de visiteurs, le temps passé à scruter la page etc.

Pour cumuler les informations il suffit de balayer le fichier binaire c_http_raw_logs en appelant add_or_increment.

Techniquement la mécanique de statistique elle est organisée sous forme d'une tStringList encapsulée:

  • c_http_raw_log_pages contient une tStringList avec le nom de la page ('initiation_delphi.html' par exemple)
  • chaque Item de la tStringList contient un pointeur vers un objet de type c_http_raw_log_page qui contient les informations qui nous intéressent pour chaque page: nombre de visites etc.
La programmation ce cette unité a donc démarré par le squelette u_c_tstringlist, qui a été adapté au traitement à l'analyse du log.

3.3.1 - c_http_raw_log_page

La définition de la classe c_http_raw_log_page est la suivante:

         c_http_raw_log_pageClass(c_basic_object)
                                public
                                  m_c_http_raw_log_pagesc_http_raw_log_pages;
                                  m_http_raw_log_page_nameString;
                                  m_http_raw_log_page_countInteger;
                                  m_elapsed_timeInteger;
                                  m_usedBoolean;

                                  Constructor create_http_raw_log_page(p_namep_http_raw_log_page_nameString;
                                      p_c_http_raw_log_pagesc_http_raw_log_pagesp_elapsed_timeInteger); Virtual;
                                  function f_display_http_raw_log_pageString;
                                  Destructor DestroyOverride;
                              end;

Les attributs sont:

  • m_c_http_raw_log_pages: pointeur de la page vers la liste des pages (pourrait être utilisé pour calculer des pourcentages)
  • m_http_raw_log_page_name: le nom de la page
  • m_http_raw_log_page_count: le cumul des accès
  • m_elapsed_time: le cumul du temps passé dans la page
  • m_used: permet de récupérer les pages non analysées
Et pour les méthodes:
  • create_http_raw_log_page: construit l'objet et initialise les attributs
  • f_display_http_raw_log_page: une chaîne d'affichage typique

3.3.2 - c_http_raw_log_pages

La définition de la classe c_http_raw_log_pages est la suivante:

         c_http_raw_log_pagesClass(c_basic_object)
                                 public
                                   m_c_http_raw_log_page_listtStringList;
                                   m_max_http_raw_log_page_lengthInteger;

                                   Constructor create_http_raw_log_pages(p_nameString); Virtual;

                                   function f_http_raw_log_page_countInteger;
                                   function f_c_http_raw_log_page(p_http_raw_log_pageInteger): c_http_raw_log_page;
                                   procedure add_http_raw_log_page(p_c_http_raw_log_pagec_http_raw_log_page);
                                   procedure add_or_increment(p_http_raw_log_page_nameStringp_elapsed_timeInteger);

                                   procedure display_http_raw_log_pages;
                                   procedure display_zip_ppt;
                                   procedure display_non_zip_ppt_http_raw_log_pages;

                                   procedure display_indented_zip_and_ppt(p_site_map_nameString);
                                   procedure display_indented_html(p_site_map_nameString);
                                   procedure display_unused;

                                   Destructor DestroyOverride;
                               end;

Les attributs sont:

  • m_c_http_raw_log_page_list: la tStringList
  • m_max_http_raw_log_page_length: calcule la taille maximale des noms de page (pour aligner les valeurs numériques à droite des noms)
Et pour les méthodes:
  • pour la partie standard de gestion de tStringList:
    • create_http_raw_log_pages: crée l'objet
    • f_http_raw_log_page_count: encapsule le nombre d'éléments
    • f_c_http_raw_log_page: encapsule l'accès par indice à un élément
    • add_http_raw_log_page: encapsule l'ajout d'un élément
    • add_or_increment: crée un nouvel élément ou incrémente les statistiques d'une page ayant déjà été ajoutée
  • et finalement la récupération des résultats:
    • display_http_raw_log_pages: la liste sans fioritures
    • display_zip_ppt et display_non_zip_ppt_http_raw_log_pages: liste séparée en fichiers téléchargés et pages HTML pures.
    • display_indented_zip_and_ppt, display_indented_html et display_unused: affichage des tables présentées ci-dessus
Seules les trois dernières procédures méritent quelques explications.
  • parmi les reproches que je faisais aux logs Free figure l'absence d'ordre de présentation. Les pages étaient en vrac. Or mon site est organisé en répertoires (les stages, les articles etc). Je souhaitais une présentation des statistiques correspondant à cette organisation
  • pour cela je place sur disque un fichier ASCII indenté contenant la structure des répertoires. Un simple balayage des répertoires par FindFirst ou l'utilisation d'un tDirectoryListBox ne font pas l'affaire car DOS présente les répertoires dans l'ordre qui lui fait plaisir. Et qui ne me fait en général pas plaisir à moi. Un utilitaire place l'arborescence dans un fichier ASCII que je réorganise à la main.
    C'est même un peu plus compliqué que cela:
    • site_editor, mon outil de construction de site, utilise un tTreeView pour créer ou gérer les répertoires. L'arborescence est sauvegardée dans un fichier ASCII
    • un utilitaire relit ce fichier de répertoires, et construit un fichier ASCII de pages .HTML. En effet certains répertoires contiennent plusieurs pages (les Index Pascalissime, par exemple)
    Quoi qu'il en soit, l'ordre dans lequel je souhaite voir mes statistiques est défini par le fichier site_map_html.txt, qui a été placé dans le .ZIP du projet pour vous permettre de faire fonctionner notre exemple.
  • la procédure display_indented_html charge ce fichier ASCII dans une tStringList locale, et pour chaque nom récupère de m_c_http_raw_log_page_list les statistiques qui nous intéressent.
  • idem pour display_indented_zip_and_ppt, qui récupère les statistiques des fichiers téléchargés.
  • pour chaque page "normale" analysée, la propriété m_used est basculée à True. Pour récupérer les pages que nous n'avions pas anticipées (essentiellement les erreur 404), il suffit de parcourir m_c_http_raw_log_page_list à la recherche de pages pour lesquelles m_used est False

3.4 - u_strings_html

Cette unité contient quelques primitives de traitement de chaînes (tester si le nom d'un fichier se termine par ".hml" etc)


4 Améliorations

4.1 Quelques suggestions

Citons en vrac:
  • incorporer les informations "User-Agent": qui permettrait de detecter les moteurs automatiques de visite de pages
  • effectuer le même type d'analyse pour les logs FTP: pour le moment mon hébergeur ne me les fournit pas, car ils sont sur une machine séparée et qui regroupe le FTP de tous les sites. Je finirai peut être par les obtenir un jour
  • l'utilisation d'Interbase (ou toute autre base de donnée) au lieu des fichiers binaires utilisés ici

4.2 L'hébergeur

Lorsque je me suis finalement décidé à monter un site, la première difficulté a été le choix de l'hébergeur.
  • Plusieurs personnes m'avait déjà proposé d'héberger Pascalissime, mais je ne suis pas arrivé à me décider.
  • En espérant trouver une aide "personnalisée", je me suis tourné vers Lolo qui fréquentait les "Mercredis de l'Institut Pascal". Ancien programmeur émérite, administrateur en tant qu'étudiant du site de Jussieu, il travaille actuellement chez un hébergeur professionel. Il m'a fait comprendre qu'ils ne pouvaient pas laisser leur client gambader en CGI dans leurs systèmes, à moins d'allouer une machine dédiée à ce client chez eux. Et les machines sont des systèmes spécialisés en racks: rien à voir avec un PC de chez Carrefour ou Conforama. Je n'ai même pas demandé le prix qui n'a certainement non plus rien à voir. Alors, dégoûté, je suis retourné hiberner deux ans de plus.
  • Alain Guérin m'avait présenté Free. Enfin un truc gratis à ma portée. J'ai été TRES satisfait de leur prestation. Le mail a fort bien marché, et fonctionne encore à ce jour. Alain avait par la suite insisté qu'il était possible, ainsi que chez d'autres hébergeurs style Club Internet, d'avoir des pages web "perso". J'ai commencé à regarder, et suis tombé sur des tutoriaux PHP. Boudigras, encore un langage de plus à la syntaxe approximative et fluctuante. J'ai plus que donné à ce niveau, et j'ai donc refermé la page.
  • lorsque je me suis réellement décidé à enfin faire quelque chose, j'ai commencé par analyser les pages des autres programmeurs. Pas beaucoup de PHP, JavaScript ou autre Python me semblait-il. C'est là que j'ai basculé. Le site fut monté en un mois en écrivant le texte HTML avec Notepad. Pas réellement, mais enfin presque. Et au bout de 15 jours les limitations de Free apparurent:
    • des statistiques difficilement exploitables
    • pas de CGI. Du Perl ou PHP si j'ai bien compris, mais cela je le refuse
    • un statut juridique peu clair: peut-on mentionner des prix, des bons de commande ? Sans doute compte tenu de leur volume ils ne vérifient pas tout, et peut-être même ferment-ils les yeux. Mais cette ambiguité aurait été, pour le moins, inconfortable
    • un service, malgré tout minimal. Gratuit certes, mais minimal:
      • pour les réponses au téléphone, 7 jours sur 7 et 24 heures sur 24, une mécanique du style "pour avoir les tarifs, tapez sur 1" etc. Et après avoir tapé comme un malade au point d'en attraper un furoncle au doigt (j'imaginent qu'ils touchent des sous des PTT comme le Minitel Rose), le message classique "tous nos techniciens sont occupés, veuillez appeler ultérieurement"
      • patience et tenacité font plus que force et rage: au bout de plusieurs appels je tombe enfin sur quelqu'un. Très aimable et courtois, je dois dire. Mais plutôt commercial ou "grand public". Trouver le fichier correspondant à un compteur invisible que j'avais placé sur une de mes pages n'était pas dans son domaine de compétence. Il est évident que ce n'est pas le genre de question posée par "la ménagère de plus de 50 ans". Il m'aiguille vers un mail technique
      • mail fut envoyé. Réponse fut obtenue: 9 jours plus tard, et "veuillez nous dire sur quelle page est le compteur". La réponse n'est pas idiote: il allait vérifier mon bout de script, et regarder s'il trouvait le fichier .DAT quelque part j'imagine.
      A ce moment j'avais tout de même un peu perdu patience, et commencé à regarder ailleurs
  • c'est là que je suis tombé sur www.plusfacile.com. Plusieurs anciens lecteurs rencontrés lors de la conférence Borland 2000 m'avaient chaudement recommandé VienneInfo, Développez, Delphinautes etc. Et sur ce site j'ai trouvé les coordonnées de PlusFacile. La proposition semblait alléchante: avec des CGI. Et Interbase. Et en Delphi. Oui monsieur. Quelques coups de fil. Comme je bataillais avec les stats Free, j'ai posé la question des logs bruts. Un peu d'étonnement. Apparemment j'étais le premier à avoir ce type de besoin saugrenu. Mais c'était possible: les logs étaient générés par IIS pour gérer le site, et il suffisait de créer un alias pour me permettre de récupérer "mes" logs. J'ai craqué au bout de deux jours et envoyé la commande et le chèque. A titre d'information, je paie de l'ordre de 3000 francs par an pour deux sites avec réservation du nom de domaine. Moins que ma facture de téléphone. Mais voyez le détail de l'offre par vous-mêmes: il y a des offres "personnelles", "gold" etc. Depuis, j'ai appelé PlusFacile quatre ou cinq fois. J'ai toujours eu JJM au téléphone au bout de trois ou quatre sonneries, y compris le samedi matin ou dimanche après midi. Les mails sont répondus dans la journée. Des exemples de programmation Web en source Delphi dans le quart d'heure suivant le coup de fil...
Le plus drôle est que si cet article est convainquant, PlusFacile sera inondé de demandes d'autres clients pour obtenir leurs logs bruts. PlusFacile et surtout les autres j'espère. Lesquels n'en auront pas toujours envie. En général pas envie du tout même. Parlez-leur alors de CGI. Et en Delphi. Si, si, parfaitement: de CGI en Delphi. Et écoutez la réponse. Ensuite, il vous suffira de cliquer sur http://www.plusfacile.com.


5 - Télécharger le source

Pour télécharger, vous pouvez:
  • soit récupérer les unités qui vous intéressent:
  • soit récupérer le ZIP du projet de démonstration (40 K).
    Ce zip contient:
    • les unités précédentes
    • les unités qu'elles importent
    • le petit fichier d'exemple de log brut présenté dans cet article
    • le fichier ASCII qui définit l'ordre dans lequel je souhaite voir les pages présentées
    • le projet de démonstration lui-même


Comme d'habitude:
  • nous vous remercions de nous signaler toute erreur, inexactitude ou problème de téléchargement en envoyant un e-mail à jcolibri@jcolibri.com. Les corrections qui en résulteront pourront aider les prochains lecteurs
  • tous vos commentaires, remarques, questions, critiques, suggestion d'article, ou mentions d'autres sources sur le même sujet seront de même les bienvenus à jcolibri@jcolibri.com.
  • plus simplement, vous pouvez taper (anonymement ou en fournissant votre e-mail pour une réponse) vos commentaires ci-dessus et nous les envoyer en cliquant "envoyer" :
    Nom :
    E-mail :
    Commentaires * :
     

  • et si vous avez apprécié cet article, faites connaître notre site, ajoutez un lien dans vos listes de liens ou citez-nous dans vos blogs ou réponses sur les messageries. C'est très simple: plus nous aurons de visiteurs et de références Google, plus nous écrirons d'articles.

Bibliographie et Liens


L'auteur

John COLIBRI est passionné par le développement Delphi et les applications de Bases de Données. Il a écrit de nombreux livres et articles, et partage son temps entre le développement de projets (nouveaux projets, maintenance, audit, migration BDE, migration Xe_n, refactoring) pour ses clients, le conseil (composants, architecture, test) et la formation. Son site contient des articles avec code source, ainsi que le programme et le calendrier des stages de formation Delphi, base de données, programmation objet, Services Web, Tcp/Ip et UML qu'il anime personellement tous les mois, à Paris, en province ou sur site client.
Created: jan-04. Last updated: mar-2020 - 250 articles, 620 .ZIP sources, 3303 figures
Contact : John COLIBRI - Tel: 01.42.83.69.36 / 06.87.88.23.91 - email:jcolibri@jcolibri.com
Copyright © J.Colibri   http://www.jcolibri.com - 2001 - 2020
Retour:  Home  Articles  Formations  Développement Delphi  Livres  Pascalissime  Liens  Download
l'Institut Pascal

John COLIBRI

+ Home
  + articles_avec_sources
    + bases_de_donnees
    + web_internet_sockets
      – http_client
      – moteur_de_recherche
      – javascript_debugger
      + asp_net
      – client_serveur_tcp
      – site_editor
      – pascal_to_html
      – cgi_form
      – les_logs_http_bruts
        – u_strings_html
      + les_blogs
      – intraweb_tutorial
      + services_web
      – serveur_web_iis
      – client_serveur_pop3
      – lecteur_mails_free
    + services_web_
    + prog_objet_composants
    + office_com_automation
    + colibri_utilities
    + uml_design_patterns
    + graphique
    + delphi
    + outils
    + firemonkey
    + vcl_rtl
    + colibri_helpers
    + colibri_skelettons
    + admin
  + formations
  + developpement_delphi
  + présentations
  + pascalissime
  + livres
  + entre_nous
  – télécharger

contacts
plan_du_site
– chercher :

RSS feed  
Blog

Formation Delphi 7 complete L'outil de développpement, le langage de programmation, les composants, les bases de données et la programmation Internet - 5 jours
Formation Bases de Données Delphi Gestion de bases de données : connexion, accès aux tables, édition d'états - 3 jours