27
Jul/09
0

Traces

Avant de pouvoir commencer les développements Erlang, il est intéressant de savoir comment « débuguer » (!!! pfff) et générer des traces.

Comme pour les autres fonctions Erlang, il peut être consommateur de temps de trouver les informations nécessaires.

Pour les traces, un système « simple » et immédiat sera de tracer les informations dans la console, via le shell.

Débuguer

Pour cela, Erlang fournit le module dbg. Ce dernier permet de définir déclarativement les fonctions qui seront prises en charge par le serveur de trace.

Démarrez le serveur :

rake start

Appuyez sur Entrée, afin d’afficher le prompt du shell Erlang. Démarrez un serveur de debugage sur le nœud local.

> dbg:tracer().
{ok,<0.57.0>}

Pour un peu d’aide, on peut taper :

> dbg:h().

Il est nécessaire alors de modifier les options permettant d’indiquer ce qui sera tracé ou non, grâce à la méthode p() (oui, ils sont forts pour trouver des noms compréhensibles) :

> dbg:p(all, c).

Ici, on demarre la trace pour tous les appels (call) de tous les processus (all), Différentes options sont disponibles, comme :

  • s (send)
  • r (receive)
  • c (call)
  • p (process)
  • all
  • clear

Ces options peuvent être combinées dans une liste.

Enfin, il faut définir les expressions que l’on veut tracer :

> dbg:tpl(ercm_web, loop, []).

Ici, on affiche les appels à la méthode loop() du module web. Donc, Tout accès à une URL sera tracé, comme ci dessous :

> (<0.56.0>) call ercm_web:loop({mochiweb_request,#Port<0.928>,'GET',"/test",
                  {1,1},
                  {8,
                   {"host",
                    {'Host',"localhost:8000"},
                    {"accept",
                     {'Accept',"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"},
                     nil,
                     {"accept-language",
                      {'Accept-Language',"en-us,en;q=0.5"},
                      {"accept-encoding",
                       {'Accept-Encoding',"gzip,deflate"},
                       {"accept-charset",
                        {'Accept-Charset',"ISO-8859-1,utf-8;q=0.7,*;q=0.7"},
                        nil,nil},
                       nil},
                      {"connection",{'Connection',"keep-alive"},nil,nil}}},
                    {"user-agent",
                     {'User-Agent',"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.1) Gecko/20090718 Shiretoko/3.5.1"},
                     {"keep-alive",{'Keep-Alive',"300"},nil,nil},
                     nil}}}},"/d/apps/ercm/priv/www")

Codes retour

Si l’on ne veut que le code retour, cela se complique encore un peu :) .

Il faut toujours utiliser la méthode de template vue précédemment, mais en ajoutant une fonction de « matching ».

Le code retour de la méthode loop/2 est défini ainsi :

dbg:tpl(ercm_web, loop, dbg:fun2ms(fun(_) -> return_trace() end)).

Je n’affiche pas le résultat d’une telle commande ici, car c’est beaucoupp trop long.

La méthode return_trace() n’existe pas dans le module dbg, et elle ne peut être utilisée que dans la fonction fun2ms et uniquement dans le shell !!!

En fait, il s’agit d’un alias pour les spécifications de correspondance (match_spec) suivantes :

[{'_', [], [{return_trace}]}]

Je n’ai pas encore assimilé complètement le concept, mais d’après la doc, il s’agit d’un équivalent à une fonction, mais compilé et interprété par le runtime de façon beaucoup plus efficace (et plus limitée).

Les 3 parties du code précédent correspondent aux termes « HEAD », « CONDITION » et « BODY ».

  • HEAD = ‘_’ : matche tous les éléments
  • CONDITION = [] : Aucune condition particulière
  • BODY = return_trace : une des fonctions d’action possible, voir la doc pour les autres

Donc ici - si on résume en français - pour tous les appels a loop(), on exécute le message return_from vers la fonction.

On peut donc définir des éléments de trace automatiques, de la façon suivante (dans la méthode loop/2 du module ercm_web) :

"/" ++ Path = Req:get(path),
    case Path of
      "trace" -> 
        dbg:tracer(),
	dbg:p(all, c),
	dbg:tpl(?MODULE, loop, [{'_', [], [{return_trace}]}]),
	Req:ok({"text/plain", [], ["trace on"]});
      _ ->
        true
    end,

Ceci permet de déclencher les traces vues précédemment grâce à l’url http://localhost:8000/trace.

Pas vraiment utile comme fonctionnement, mais c’est pour l’exemple. Ces informations seront réexploitées ultérieurement.

Filed under: Erlang
Comments (0) Trackbacks (0)

No comments yet.

Leave a comment

No trackbacks yet.