Prise en main d'Incanter

IncanteR peut s'utiliser dans le REPL comme un DSL. Dans un premier temps nous allons explorer nos données interactivement.

IncanteR lit nativement les fichiers .csv. Les fichier de log est en texte. Dans un premier temps nous allons supposer que vous avez transformé le fichier de log texte en un fichier .csv avec un autre outil.

Les fichiers de log en csv apparaissent sous le nom TIME_MONITOR_.csv dans le répertoire logs.

1 - Installation d'IncanteR


Commencez par créer un projet leiningen et allez dans le répertoire créé. Il nous permettra de déclarer la dépendance Incanter et nous en aurons besoin plus tard.

$ leiningen new hoincanter
$ cd hoincanter

Editez le project.clj pour ajouter la librairie Incanter [incanter "1.5.4"] dans les :dependancies

  :dependencies [[org.clojure/clojure "1.5.1"][incanter "1.5.4"]])

Mettez à jour les dépendances de leiningen

$ lein deps

2 - Chargement du fichier


Copiez un fichier CSV dans le répertoire du projet pour qu'il soit accessible plus facilement.

$ cp ../logs/TIME_MONITOR_2013-12-20.csv .

Ouvrez un REPL

$ lein repl

Vous aurez besoin d'importer les modules core, io, stats, et charts de la librairie incanter

user=> (use '(incanter core io stats charts))

Chargez le fichier CSV

user=> (def ds (read-dataset  "TIME_MONITOR_2013-12-20.csv" :header true :delim \;) )

3 - Quelques statistiques


Consultez les valeurs et relevez les noms de colonnes, le nombre de ligne et le summary du dataset

user=> (view ds)
user=> (nrow ds)
user=> (summary ds)

Sélectionnez la colonne des temps de réponse (duration) et calculez sa moyenne, son écart type, son maximum et le quantile 95%

Il n'y a aps de min et max. Les deux sont obtenus par les quantiles.

Les quantiles d'un échantillon statistique sont des valeurs remarquables permettant de diviser le jeu de ces données ordonnées (en général triées) en intervalles consécutifs contenant le même nombre de données (source Wikipedia).

Un cas particulier est la médiane ou quantile 50% qui est la valeur qui divise l'échantillon en 2. Un relevé à une probabilité de 50% d'être en dessous de cette valeur.

On peut aussi considérer que c'est la valeur maximale qu'atteignent 50% des relevés. Dans les SLA on est souvent intéressé par des probabilités de 90% ou 95%.

Aux limites, le maximum est la valeur maximale qu'atteignent 100% des relevés et le minimum est la valeur maximale attiente par 0% des relevés.

user=> (view ($ :duration ds))
user=> (mean ($ :duration ds))
user=> (sd ($ :duration ds))
user=> (quantile ($ :duration ds) :probs[1]) 
user=> (quantile ($ :duration ds) :probs[0.95]) 

Pour faciliter l'écriture des quantiles, nous allons écrire une fonction utilitaire q qui prend deux paramètres, le seuil de probabilité et la série. Vérifiez ensuite que la fonction est correcte en calculant le maximum.

user=> (defn q [p serie] (quantile serie :probs [p]))
user=> (q 1 ($ :duration ds))

Lorsque vous avez plusieurs agrégats à calculer, pouvez alléger l'écriture en utilisant with-data. Construisez un vecteur contenant le nombre, la moyenne, l'écart-type, le minimum, le maximum, et le quantile 95% de la colonne duration.

user=> (with-data ($ :duration ds)
  #_=> [ (count $data) (mean $data) (sd $data) (q 0 $data) (q 1 $data) (q 0.95 $data) ] )

4 - Filtrer et catégoriser


Les données qui nous préoccupent sont les temps de réponse supérieurs à 40 ms. Nous allons extraire un dataset contenant seulement ces relevés sous le nom dslong.

Vous pouvez utiliser $where. Le langage de requêtes est le même que celui de MongoDB [Langage de requêtes] (http://docs.mongodb.org/manual/tutorial/query-documents/)

user=> (def dslong  ($where {:duration {:gt 40}} ds))

Jetons un coup d'oeil à la répartiion.

Summary vous permet de voir les différentes valeurs de services. Nous pouvons filtrer sur un service et calculer la moyenne des temps par exemple

user=> (mean  ($ :duration  ($where {:servicename "RS_OW_AgencyDataSupplierService"} dslong)))
1556.1666666666667

Il y a un moyen plus facile de les obtenir par $group-by sur une colonne.

Une entrée est crée pour chaque valeur distincte de la colonne et elle contient la partie du dataset qui correspond.

Cette fonction crée une map de datasets.

Essayez $group-by par :servicename sur dslong.

user=> ($group-by :servicename dslong)

Vous pouvez ainsi obtenir le dataset correspondant à service particulier. et l'utiliser pour calculer des statistiques

user=> (def dslongADS (get  ($group-by :servicename dslong) {:servicename "RS_OW_AgencyDataSupplierService"} ))

user=> (mean  ($ :duration  dslongADS ))

Pour finir, nous allons afficher la moyenne des temps de réponse pour chaque service.

La fonction $rollup fait un $group-by et applique une fonction sur chaque groupe. Certains agrégats (mean, count …) ont un racourci syntaxique.

user=> ($rollup mean :duration :servicename dslong)

5 - Les charts


Pour le moment, nous ne pouvons pas afficher les données sous une forme chronologique car la date n'a pas un format connu.

Nous pouvons cependant afficher l'histogramme des temps de réponse. L'histogramme affiche les quantiles et permet de voir la distribution des temps de réponse.

user=> (histogram  :duration :data dslong)

Le diagramme est bien crée mais il faut utiliser view pour l'afficher.

user=> (view (histogram  :duration :data dslong))

Les couleurs et le rendu peuvent être modifiés. Nous ferons celà dans une fonction plus tard.

Nous pouvons aussi afficher les relevés par catégorie sous forme de diagramme en barre ou de camembert.

user=> (view (bar-chart :servicename :duration :vertical false :data  ($rollup count :duration :servicename dslong)))

user=> (view (pie-chart :servicename  :duration   :data  ($rollup count :duration :servicename dslong)))

Dans les steps suivants, nous allons écrire une fonction qui parse le fichier d'origine qui n'est pas un csv et construit le dataset.

Nous allons aussi écrire une fonction qui fabrique une date correcte pour que l'on puisse visualiser la série temporelle.

Nous utiliserons ensuite ces deux fonctions dans le REPL, mais pour le moment, sortons du REPL en tapant exit.