Annotations personnalisées, Observateurs et Logs

Annotations personnalisées, Observateurs et Logs - Java - Programmation

Marsh Posté le 16-07-2011 à 19:06:10    

Salut les gens !
 
Voilà, j'ai un projet pour lequel je dois programmer un logger pour enregistrer tout le déroulement d'un algo, au niveau de ses variables par exemple.
En gros, je veux enregistrer la variable et sa valeur dès qu'elle est créée et dès qu'elle est modifiée. Avec ça, je pourrais ensuite mieux voir ce qu'il se passe dans mon algo au fur et à mesure de ses appels successifs.
 
Pour le logger, je vais sûrement utiliser la lib log4j qui est quand même super pratique ! [:djmb]  Je reste néanmoins ouvert à toute autre suggestion !
 
Après, pour ne pas avoir à réécrire 35x la même chose à tous les endroits où mon algo va changer la moindre variable (j'ai quand même pas mal de calcul dedans... :o ), j'avais dans l'idée d'utiliser d'une part des annotations pour faciliter l'intégration du logger dans le code et d'autres part des observateurs (?) pour qu'une fois appelé pour une variable, le logger enregistre toute modification de cette variable.
Grâce à ça, je n'aurai plus qu'à écrire un truc genre @log(variable1) ou @logs(variable1, variable2, ...) pour que les variables citées soient suivies et enregistrées ! :D  Et tout le système serait géré dans un projet à part et importé via une archive jar !
 
Jusque là, ça me paraît une idée plutôt correcte et qui pourrait bien fonctionner ! Venons-en maintenant à mes problèmes... [:djmb]  
Déjà, j'ai du mal à créer des annotations : ça date du jdk 1.5 (avec apt), ça a été amélioré dans le 1.6 (où c'est intégré dans javac) mais c'est pas encore le top, genre c'est pas compatible avec Éclipse (et j'ai pas le choix, je dois travailler avec) ou en tout cas la structure est pas la même dans les deux cas, ... [:tim_coucou]  En plus, il n'y a presque aucun tuto sur le web qui traite de la création d'annotation avec le jdk 1.6...
Mon autre souci concerne les observateurs : j'ai trouvé un tuto qui m'a l'air pas mal sur le web (de mémoire, sur Developpez) mais je me pose un question à propos de l'initialisation du truc : l'annotation doit être appelée avant la méthode mais ne faut-il pas initialiser la variable avant d'initialiser l'observateur ? et comment je fais dans ce cas ? [:transparency]  
 
 
Voilà en gros mes problèmes !  Donc maintenant : est-ce que vous auriez des solutions , des conseils à me donner ? Est-ce que vous pensez que c'est infaisable  ou alors que c'est trivial et que c'est fournit dans une lib quelconque ? (on sait jamais [:ddr555] )
Je suis tout ouï et j'attends vos messages !  :bounce:  
 
Merci d'avance !
 
Bobby qui galère depuis 2 semaines dessus... [:d@emon_666:2]


---------------
Bobbyfrasier, Bobbyfrasier everywhere ! (Steam, Origin, ...)
Reply

Marsh Posté le 16-07-2011 à 19:06:10   

Reply

Marsh Posté le 16-07-2011 à 19:45:57    

bobbyfrasier a écrit :

Salut les gens !
 
Voilà, j'ai un projet pour lequel je dois programmer un logger pour enregistrer tout le déroulement d'un algo, au niveau de ses variables par exemple.
En gros, je veux enregistrer la variable et sa valeur dès qu'elle est créée et dès qu'elle est modifiée. Avec ça, je pourrais ensuite mieux voir ce qu'il se passe dans mon algo au fur et à mesure de ses appels successifs.
 
Pour le logger, je vais sûrement utiliser la lib log4j qui est quand même super pratique ! [:djmb]  Je reste néanmoins ouvert à toute autre suggestion !


 
Et pourquoi ne pas tout simplement utiliser java.util.logging ? [:dao]
 

Citation :

Après, pour ne pas avoir à réécrire 35x la même chose à tous les endroits où mon algo va changer la moindre variable (j'ai quand même pas mal de calcul dedans... :o ), j'avais dans l'idée d'utiliser d'une part des annotations pour faciliter l'intégration du logger dans le code et d'autres part des observateurs (?) pour qu'une fois appelé pour une variable, le logger enregistre toute modification de cette variable.
Grâce à ça, je n'aurai plus qu'à écrire un truc genre @log(variable1) ou @logs(variable1, variable2, ...) pour que les variables citées soient suivies et enregistrées ! :D  Et tout le système serait géré dans un projet à part et importé via une archive jar !
 
Jusque là, ça me paraît une idée plutôt correcte et qui pourrait bien fonctionner ! Venons-en maintenant à mes problèmes... [:djmb]  
Déjà, j'ai du mal à créer des annotations : ça date du jdk 1.5 (avec apt), ça a été amélioré dans le 1.6 (où c'est intégré dans javac) mais c'est pas encore le top, genre c'est pas compatible avec Éclipse (et j'ai pas le choix, je dois travailler avec) ou en tout cas la structure est pas la même dans les deux cas, ... [:tim_coucou]  En plus, il n'y a presque aucun tuto sur le web qui traite de la création d'annotation avec le jdk 1.6...
Mon autre souci concerne les observateurs : j'ai trouvé un tuto qui m'a l'air pas mal sur le web (de mémoire, sur Developpez) mais je me pose un question à propos de l'initialisation du truc : l'annotation doit être appelée avant la méthode mais ne faut-il pas initialiser la variable avant d'initialiser l'observateur ? et comment je fais dans ce cas ? [:transparency]


 
J'avoue ne pas avoir trifouillé les annotations depuis un beau paquet de temps, mais pourquoi n'utilises-tu tout simplement pas un schéma OO du type "Observateur" justement ? :??: C'est tout simple à faire et ça mange pas de pain :o.
 
Plus d'infos ici, T. 207.
 

Citation :

Voilà en gros mes problèmes !  Donc maintenant : est-ce que vous auriez des solutions , des conseils à me donner ? Est-ce que vous pensez que c'est infaisable  ou alors que c'est trivial et que c'est fournit dans une lib quelconque ? (on sait jamais [:ddr555] )
Je suis tout ouï et j'attends vos messages !  :bounce:


 
Bon, y a certainement des gens plus connaisseurs que moi de librairies extérieures, je suis objectivement parlant plutôt un intégriste du "pas besoin de sortir de l'API standard quand c'est pas nécessaire" à tout prix.
 
Ma conclusion en très peu de mot: tu te compliques trop la vie [:ddr555]. En utilisant quelques outils bien choisis dans le JDK et un bon schéma OO, je ne vois pas ce qu'il te faudrait de plus :??:.

Reply

Marsh Posté le 16-07-2011 à 19:49:47    

Si tu veux voir un bout d'implémentation du schéma observateur (C++), tu peux aussi consulter ceci.

Reply

Marsh Posté le 16-07-2011 à 20:21:51    

je plussoie la réponse de Geddeon, java.util.logging epicetout

Reply

Marsh Posté le 16-07-2011 à 20:24:10    

Ca a l'air bien les annotations :o pourquoi j'utilise 1.4 au boulot :cry:

Reply

Marsh Posté le 16-07-2011 à 20:30:15    

Mon souci est que le code du logger doit être super modulable : il ne restera dans le code que pendant certains tests, on doit pouvoir le modifier facilement et rapidement, ajouter des observateurs pour certaines autre variables (si on modifie le code), etc.
 
J'ai pas encore trop regardé le java.util.logging mais je pense que ça ne va pas être autant modulable que les annotations peuvent l'être, si ? :??:


---------------
Bobbyfrasier, Bobbyfrasier everywhere ! (Steam, Origin, ...)
Reply

Marsh Posté le 16-07-2011 à 20:36:18    

bobbyfrasier a écrit :

Mon souci est que le code du logger doit être super modulable : il ne restera dans le code que pendant certains tests, on doit pouvoir le modifier facilement et rapidement, ajouter des observateurs pour certaines autre variables (si on modifie le code), etc.


 
Si c'est pour en arriver à ce genre d’extrémité, alors pourquoi tu ne cherches directement du côté du profiling de tes applications ? :o
Grosso modo j'ai l'impression que c'est comme si tu cherchais un interpréteur de ton code java qui, à tout instant, peut te donner la valeur exacte de toutes les composantes de ton espace d'état :o.
 

Citation :

J'ai pas encore trop regardé le java.util.logging mais je pense que ça ne va pas être autant modulable que les annotations peuvent l'être, si ? :??:


 
Baah ça dépend comment tu fais le bousin aussi :d.

Reply

Marsh Posté le 16-07-2011 à 21:11:05    

Geddons a écrit :


 
Si c'est pour en arriver à ce genre d’extrémité, alors pourquoi tu ne cherches directement du côté du profiling de tes applications ? :o
Grosso modo j'ai l'impression que c'est comme si tu cherchais un interpréteur de ton code java qui, à tout instant, peut te donner la valeur exacte de toutes les composantes de ton espace d'état :o.


Pas tout compris :D  
Mais sinon, oui, il faut que j'arrive à récupérer ça (enfin, en partie parce qu'il y a un bon nombre de trucs dont je me balance  [:ddr555] )


---------------
Bobbyfrasier, Bobbyfrasier everywhere ! (Steam, Origin, ...)
Reply

Marsh Posté le 16-07-2011 à 21:18:07    

bobbyfrasier a écrit :


Pas tout compris :D

 

http://en.wikipedia.org/wiki/Profi [...] ogramming)

 

Exemple typique en C/C++: les incontournables "valgrind" & gdb (si code compilé en mode debug) ;). Ca existe aussi en java, y compris dans des outils standards Sun :o. Mais je te laisse googler pour ça :o.

 
Citation :

Mais sinon, oui, il faut que j'arrive à récupérer ça (enfin, en partie parce qu'il y a un bon nombre de trucs dont je me balance  [:ddr555] )

 

Ben regarde aussi de ce côté là alors :o. Mais ça peut être chiant à mettre en place la première fois :o. C'est à toi d'évaluer tes besoins et voir si l'investissement en vaut la peine.


Message édité par Geddons le 16-07-2011 à 21:18:40
Reply

Marsh Posté le 18-07-2011 à 09:51:41    

Après avoir regardé un peu toutes les pages indiquées + google sur ce que je connaissais pas du tout, j'en reviens un peu au problème du départ :
dans mon cas, je DOIS insérer le minimum de code dans mon algo donc c'est pour ça que passer par une annotation me parait le plus logique...
Après, c'est évident que je vais utiliser un observateur et java.util.logging (log4j fait la même chose mais on configure le truc dans un fichier de préférence ;) ) mais ça me dérange d'avoir à insérer tant de code directement dans l'algo...
Moi ce que je vois, c'est un truc comme ça :
 

  • on place une annotation prenant en argument une variable à observer
  • l'annotation va créer un observateur relatif à la variable en fonction de la configuration qu'on a fait
  • dès qu'il détecte une modification de la variable, l'observateur va enregistrer la nouvelle valeur dans le fichier de log


Je comprend bien que c'est lourd pour ce que c'est mais j'ai pas trop le choix, j'ai un certain cahier des charges à respecter  [:djmb]  
Il faudrait donc que j'arrive à trouver comment faire un truc qui marche comme ça !
 
Any idea ?


---------------
Bobbyfrasier, Bobbyfrasier everywhere ! (Steam, Origin, ...)
Reply

Marsh Posté le 18-07-2011 à 09:51:41   

Reply

Marsh Posté le 18-07-2011 à 10:49:49    

bobbyfrasier a écrit :


Je comprend bien que c'est lourd pour ce que c'est mais j'ai pas trop le choix, j'ai un certain cahier des charges à respecter  [:djmb]


 
Nan mais tu te rends compte que tu demandes ce qu'un interpréteur fait, sur du code compilé (bon ok du byte-code [:dao]) ? :heink:
 

Citation :

Il faudrait donc que j'arrive à trouver comment faire un truc qui marche comme ça !
Any idea ?


 
Si tu trouves un jour comment faire ça, en gardant la compilation normale, dis-le moi, parce que là ça défie toutes mes notions de structure des langages [:tinostar].
 
Tu devrais faire ça en Python, ça serait plus simple pour tout le monde [:ddr555].
 

Reply

Marsh Posté le 18-07-2011 à 11:18:41    

Geddons a écrit :


 
Nan mais tu te rends compte que tu demandes ce qu'un interpréteur fait, sur du code compilé (bon ok du byte-code [:dao]) ? :heink:
 


Sauf que j'arrive pas à comprendre le truc de l’interpréteur, ou en tout cas comment il marche [:tinostar]
J'ai compris que c'était par exemple dans le JVM Tools Interface (en C++) ou dans le JMX (en Java) mais pas moyen de comprendre comment ça fonctionne [:blessure]  
 
Si tu as un tuto quelque part là-dessus, ça m'arrangerai :D  


---------------
Bobbyfrasier, Bobbyfrasier everywhere ! (Steam, Origin, ...)
Reply

Marsh Posté le 18-07-2011 à 11:44:17    

bobbyfrasier a écrit :


Sauf que j'arrive pas à comprendre le truc de l’interpréteur, ou en tout cas comment il marche [:tinostar]

 

Nan mais ma "question" n'avait aucun sens. Que quelqu'un me corrige si je me trompe mais ce que tu demandes, tel que tu le demandes, est théoriquement infaisable (théorie des langages).

 
Citation :

J'ai compris que c'était par exemple dans le JVM Tools Interface (en C++) ou dans le JMX (en Java) mais pas moyen de comprendre comment ça fonctionne [:blessure]

 

Je ne sais pas t'en dire plus parce que je n'ai plus trifouillé dans ces machins-là depuis un certain temps mais un machin avec JVM dedans ne peut pas être C++ ou alors le nom est très mal choisi [:tinostar].
Pour le JMX, ça me parle plus c'est un peu ça que j'avais en tête, ouais. Mais ça reste assez lourd à mettre en place la première fois.

 
Citation :

Si tu as un tuto quelque part là-dessus, ça m'arrangerai :D

 

Tutos officiels Sun/Oracle [:prodigy]. Le reste: lire les bouts intéressants de l'API, faut mettre les mains dans le cambouis dans ce genre de trucs. Ca paye rarement en première lecture, mais une fois que t'as pigé tu peux revaloriser ton expérience plus tard.

 

Mais honnêtement, vu les contraintes que tu mets sur tes désirs, j'ai de très gros doutes sur la faisabilité de ton projet. Mais je n'ai certainement pas la parole absolue :jap:.

 

edit: Pour le logging de java.util.logging, si tu t'en sors pas, je peux te donner des bouts de code. Je travaille actuellement sur un projet où j'ai intégré ce genre de trucs, en version assez large (logging HDD, console et réseau simultanés, avec des niveaux différents etc.).

Message cité 1 fois
Message édité par Geddons le 18-07-2011 à 11:45:49
Reply

Marsh Posté le 18-07-2011 à 12:03:06    

Geddons a écrit :


 
Nan mais ma "question" n'avait aucun sens. Que quelqu'un me corrige si je me trompe mais ce que tu demandes, tel que tu le demandes, est théoriquement infaisable (théorie des langages).


ok bah je vais voir avec qui-de-droit pour discuter de comment je fais :jap:  
 
 

Geddons a écrit :

Je ne sais pas t'en dire plus parce que je n'ai plus trifouillé dans ces machins-là depuis un certain temps mais un machin avec JVM dedans ne peut pas être C++ ou alors le nom est très mal choisi [:tinostar].
Pour le JMX, ça me parle plus c'est un peu ça que j'avais en tête, ouais. Mais ça reste assez lourd à mettre en place la première fois.


En regardant ça, j'ai quand même l'impression de pas faire du java [:tinostar] : http://download.oracle.com/javase/ [...] tml#whatIs
 
 

Geddons a écrit :

Tutos officiels Sun/Oracle [:prodigy]. Le reste: lire les bouts intéressants de l'API, faut mettre les mains dans le cambouis dans ce genre de trucs. Ca paye rarement en première lecture, mais une fois que t'as pigé tu peux revaloriser ton expérience plus tard.
 
Mais honnêtement, vu les contraintes que tu mets sur tes désirs, j'ai de très gros doutes sur la faisabilité de ton projet. Mais je n'ai certainement pas la parole absolue :jap:.


Les tutos officiels sont peut-etre précis et tout mais ils sont souvent moins clairs que d'autres tutos :(  
 

Geddons a écrit :

edit: Pour le logging de java.util.logging, si tu t'en sors pas, je peux te donner des bouts de code. Je travaille actuellement sur un projet où j'ai intégré ce genre de trucs, en version assez large (logging HDD, console et réseau simultanés, avec des niveaux différents etc.).


le logging, ça va, c'est le truc le plus facile dans le tas  [:ddr555]  
Mais je veux bien quand même des bouts de codes histoire de comparer à ce que j'ai déjà ! :jap:


---------------
Bobbyfrasier, Bobbyfrasier everywhere ! (Steam, Origin, ...)
Reply

Marsh Posté le 19-07-2011 à 14:51:14    

Nouvelle idée qu'on a eu : utiliser AspectJ !
Apparemment ça a l'air de faire à peu près ce que je voulais... Mais faut que j'examine ça plus à fond ! :)


---------------
Bobbyfrasier, Bobbyfrasier everywhere ! (Steam, Origin, ...)
Reply

Marsh Posté le 19-07-2011 à 15:09:55    

Intéressant mais si tu regardes bien, c'est la mise en place simplifiée de techniques dont je te parlais précédemment :d. Et ça s'insère bien dans le code *avant* compilation ;).
 
Maintenant, que ça facilite la vie du programmeur, ça c'est autre chose :o.

Reply

Marsh Posté le 19-07-2011 à 15:30:19    

Geddons a écrit :

Intéressant mais si tu regardes bien, c'est la mise en place simplifiée de techniques dont je te parlais précédemment :d. Et ça s'insère bien dans le code *avant* compilation ;).
 
Maintenant, que ça facilite la vie du programmeur, ça c'est autre chose :o.


On s'est mal compris sur le coup de "avant la compilation" parce que c'est évident que ça va pas rajouter du code après [:ddr555]  
 
 
par contre, j'ai maintenant un souci quand j'essaie de coder un aspect pour récupérer une variable utilisée dans une méthode... genre :
 
Main.java

Code :
  1. package com.nicolas.tutoAspectJ;
  2. import com.nicolas.tutoAspectJ.banque.CompteBancaire;
  3. public class Main {
  4. public static void main(String[] args){
  5.  CompteBancaire monCompte = new CompteBancaire(1000);
  6.  monCompte.retrait(300);
  7.  monCompte.retrait(200);
  8. }
  9. }


 
 
CompteBancaire.java
 

Code :
  1. package com.nicolas.tutoAspectJ.banque;
  2. public class CompteBancaire {
  3. private int solde;
  4. private int variable1;
  5. public CompteBancaire(int solde) {
  6.  super();
  7.  this.solde = solde;
  8.  this.variable1 = 0;
  9. }
  10. public void depot (int sommeDepot){
  11.  this.variable1 = solde;
  12.  solde = solde + sommeDepot;
  13. }
  14. public void retrait (int sommeRetrait){
  15.  this.variable1 = solde;
  16.  solde = solde - sommeRetrait;
  17.  System.out.println("Retrait de : " + sommeRetrait);
  18. }
  19. public int getSolde(){
  20.  return solde;
  21. }
  22. public int getVariable1(){
  23.  return variable1;
  24. }
  25. public void setSolde(int solde){
  26.  this.solde = solde;
  27. }
  28. }


 
1er Aspect qui fonctionne (il écrit un truc avant et après l'exécution de la méthode CompteBancaire.retrait:

Code :
  1. package com.nicolas.tutoAspectJ.aspects;
  2. public aspect LogAspect {
  3. pointcut logRetrait(int variable1) : call(* com.nicolas.tutoAspectJ.banque.CompteBancaire.retrait(..))
  4. && args(variable1);
  5. before(int i) : logRetrait(i) {
  6.  System.out.println("AVANT le retrait : " + i);
  7. }
  8. after(int i) : logRetrait(i) {
  9.  System.out.println("APRES le retrait : " + i);
  10. }
  11. }


 
2e aspect qui marche (et fait presque pareil que le précédent sauf qu'en sortie on a la valeur de l'argument donné à retrait() et le nom du compte) :

Code :
  1. package com.nicolas.tutoAspectJ.aspects;
  2. import com.nicolas.tutoAspectJ.banque.CompteBancaire;
  3. public aspect LogAspect2 {
  4. pointcut logRetrait2(CompteBancaire compte, int sommeRetrait) : call(void com.nicolas.tutoAspectJ.banque.CompteBancaire.retrait(int))
  5. && target(compte)
  6. && args(sommeRetrait);
  7. before(CompteBancaire compte, int sommeRetrait) : logRetrait2(compte, sommeRetrait) {
  8.  System.out.println("Avant le retrait de " + sommeRetrait + " euros du compte "  + compte);
  9. }
  10. after(CompteBancaire compte, int sommeRetrait) : logRetrait2(compte, sommeRetrait) {
  11.  System.out.println("Après le retrait de " + sommeRetrait + " euros" );
  12. }
  13. }


 
Et maintenant celui qui ne fonctionne pas :

Code :
  1. package com.nicolas.tutoAspectJ.aspects;
  2. public aspect LogAspect3 {
  3. pointcut logVariable1(int variable1) : this(variable1);
  4. after(int variable1) : logVariable1(variable1) {
  5.  System.out.println(variable1);
  6. }
  7. }


En fait mon problème est que j'ai du mal à identifier le type de pattern que je dois utiliser pour les différents types de pointcut... J'ai essayé de remplacer le this() par target() (ça change rien) et par args() (j'ai alors une magnifique boucle infinie  :D )
 
Any idea ?
 
 
nb : et pourtant, je m'aide des pages officielles  [:haha fail] :
choix de pointcut : http://www.eclipse.org/aspectj/doc [...] tcuts.html (haut de la page)
pattern summary : la même page tout en bas


Message édité par bobbyfrasier le 19-07-2011 à 15:32:02

---------------
Bobbyfrasier, Bobbyfrasier everywhere ! (Steam, Origin, ...)
Reply

Marsh Posté le 19-07-2011 à 16:05:06    

Trouvé ! Enfin j'ai trouvé un truc qui me donne ce qu'il faut ^^
 

Code :
  1. package com.nicolas.tutoAspectJ.aspects;
  2. public aspect LogAspect3 {
  3. pointcut logVariable1() : call(* com.nicolas.tutoAspectJ.banque.CompteBancaire.*(..));
  4. after() : logVariable1() {
  5.  System.out.println("Le solde du compte est passé de " + com.nicolas.tutoAspectJ.banque.CompteBancaire.variable1 + " euros à " + com.nicolas.tutoAspectJ.banque.CompteBancaire.solde + " euros grâce au retrait \n" );
  6. }
  7. }


Et il faut définir les variables solde et variable1 en public static et non private
 
Maintenant, il ne reste plus qu'à tester ça avec du log et puis sur l'algo ! :D


Message édité par bobbyfrasier le 19-07-2011 à 16:05:58

---------------
Bobbyfrasier, Bobbyfrasier everywhere ! (Steam, Origin, ...)
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed