/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
+
#include <stdarg.h>
#include <ctype.h>
+#include <stdio.h> /* snprintf */
+#include <stdlib.h> /* snprintf */
+#include "gras_config.h" /* to get a working stdarg.h */
#include "xbt_modinter.h"
#include "xbt/misc.h"
+#include "xbt/ex.h"
#include "xbt/sysdep.h"
#include "xbt/log.h"
-#include "xbt/error.h"
#include "xbt/dynar.h"
-
-/** \defgroup XBT_log Logging support.
- * \brief A generic logging facility in the spirit of log4j
+/** \addtogroup XBT_log
*
* This section describes the API to the log functions used
* everywhere in this project.
/*
FAIRE DES ZOLIS LOGS
--------------------
-Dans gras, tu ne te contente pas d'écrire des choses à l'écran, mais tu
-écris sur un sujet particulier (notion de canal) des choses d'une gravité
-particulière. Il y a 7 niveaux de gravité.
- trace: tracer les entrées dans une fonction, retour de fonction
- (famille de macros XBT_IN/XBT_OUT)
- debug: pour t'aider à mettre au point le module, potentiellement tres bavard
- verbose: quelques infos succintes sur les internals du module
- info: niveau normal, ton de la conversation
- warning: problème potentiel, mais auquel on a su faire face
- error: problème qui t'as empêché de faire ton job
- critical: juste avant de mourir
-
-Quand on compile avec -DNDEBUG (par défaut dans le paquet Debian), tout ce
-qui est '>= verbose' est supprimé au moment de la compilation. Retiré du
-binaire, killé.
-
-Ensuite, tu écris dans un canal particulier. Tous les canaux sont rangés en
-arbre. Il faudrait faire un ptit script qui fouille les sources à la
-recherche des macros XBT_LOG_NEW_* utilisées pour créer des canaux. Le
-dernier argument de ces macros est ignoré dans le source. Il est destiné à
-être la documentation de la chose en une ligne. En gros, ca fait:
-root
- +--xbt
- | +--config
- | +--dict
- | | +--dict_cursor
- | | +--dict_elm
- | | ...
- | +--dynar
- | +--set
- | +--log
- | +--module
- +--gras
- +--datadesc
- | +--ddt_cbps
- | +--ddt_convert
- | +--ddt_exchange
- | +--ddt_parse
- | +--lexer
- +--msg
- +--transport
- +--raw_trp (Je devrais tuer ce module, un jour)
- +--trp_buf
- +--trp_sg
- +--trp_file
- +--trp_tcp
-
-Et ensuite les utilisateurs peuvent choisir le niveau de gravité qui les
-interresse sur tel ou tel sujet.
-
-Toute la mécanique de logging repose sur des variables statiques dont le nom
-dépend du nom du canal.
- => attention aux conflits de nom de canal
- => il faut une macro XBT_LOG dans chaque fichier où tu fais des logs.
-
-XBT_LOG_NEW_CATEGORY: nouveau canal sous "root". Rare, donc.
-XBT_LOG_NEW_SUBCATEGORY: nouveau canal dont on précise le père.
-XBT_LOG_DEFAULT_CATEGORY: indique quel est le canal par défaut dans ce fichier
-XBT_LOG_NEW_DEFAULT_CATEGORY: Crèe un canal et l'utilise par défaut
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY: devine
-XBT_LOG_EXTERNAL_CATEGORY: quand tu veux utiliser par défaut un canal créé
- dans un autre fichier.
-
-Une fois que ton canal est créé, tu l'utilise avec les macros LOG, DEBUG,
-VERB, WARN, ERROR et CRITICAL. Il faut que tu donne le nombre d'arguments
-après le nom de macro. Exemple: LOG2("My name is %s %s","Martin","Quinson")
-Si tu veux préciser explicitement le canal où écrire, ajoute un C devant le
-nom de la macro. Exemple: CCRITICAL0(module, "Cannot initialize GRAS")
-
-Toutes ces macros (enfin, ce en quoi elles se réécrivent) vérifient leurs
-arguments comme printf le fait lorsqu'on compile avec gcc.
-LOG1("name: %d","toto"); donne un warning, et donc une erreur en mode
-mainteneur.
-
-Enfin, tu peux tester si un canal est ouvert à une priorité donnée (pour
-préparer plus de débug, par exemple. Dans le parseur, je fais du pretty
-printing sur ce qu'il faut parser dans ce cas).
-XBT_LOG_ISENABLED(catName, priority) Le second argument doit être une valeur
-de e_xbt_log_priority_t (log.h). Par exemple: xbt_log_priority_verbose
-
-Voila sur comment mettre des logs dans ton code. N'hesite pas à faire pleins
-de canaux différents pour des aspects différents de ton code. En
-particulier, dans les dict, j'ai un canal pour l'ajout, le retrait, le
-netoyage du code après suppression et ainsi de suite. De cette façon, je
-peux choisir qui m'interresse.
-
-
Pour utiliser les logs, tu déjà faire, non ? Tu colle sur la ligne de
commande un ou plusieurs arguments de la forme
--gras-log="<réglage> [<reglage>+]" (ou sans " si t'as pas d'espace)
static void _free_setting(void *s) {
xbt_log_setting_t set=(xbt_log_setting_t)s;
if (set) {
- xbt_free(set->catname);
-/* xbt_free(set); FIXME: uncommenting this leads to segfault when more than one chunk is passed as gras-log */
+ free(set->catname);
+/* free(set); FIXME: uncommenting this leads to segfault when more than one chunk is passed as gras-log */
}
}
XBT_LOG_NEW_CATEGORY(xbt,"All XBT categories (simgrid toolbox)");
XBT_LOG_NEW_CATEGORY(surf,"All SURF categories");
XBT_LOG_NEW_CATEGORY(msg,"All MSG categories");
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(log,xbt,"Loggings from the logging mecanism itself");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(log,xbt,"Loggings from the logging mechanism itself");
-void xbt_log_init(int *argc,char **argv, const char *defaultlog) {
+void xbt_log_init(int *argc,char **argv) {
int i,j;
char *opt;
- int found=0;
/* Set logs and init log submodule */
for (i=1; i<*argc; i++) {
!strncmp(argv[i],"--surf-log=",strlen("--surf-log=")) ||
!strncmp(argv[i],"--msg-log=",strlen("--msg-log=")) ||
!strncmp(argv[i],"--xbt-log=",strlen("--xbt-log="))) {
- found = 1;
opt=strchr(argv[i],'=');
opt++;
xbt_log_control_set(opt);
i--; /* compensate effect of next loop incrementation */
}
}
- if (!found && defaultlog) {
- xbt_log_control_set(defaultlog);
- }
}
void xbt_log_exit(void) {
xbt_log_threshold_set(cat, setting->thresh);
xbt_dynar_cursor_rm(xbt_log_settings,&cursor);
- if (cat->threshold <= xbt_log_priority_verbose) {
+ if (cat->threshold <= xbt_log_priority_debug) {
s_xbt_log_event_t _log_ev =
- {cat,xbt_log_priority_verbose,__FILE__,_XBT_GNUC_FUNCTION,__LINE__};
+ {cat,xbt_log_priority_debug,__FILE__,_XBT_FUNCTION,__LINE__};
_xbt_log_event_log(&_log_ev,
"Apply settings for category '%s': set threshold to %s (=%d)",
cat->name,
}
if (!found && cat->threshold <= xbt_log_priority_verbose) {
s_xbt_log_event_t _log_ev =
- {cat,xbt_log_priority_verbose,__FILE__,_XBT_GNUC_FUNCTION,__LINE__};
+ {cat,xbt_log_priority_verbose,__FILE__,_XBT_FUNCTION,__LINE__};
_xbt_log_event_log(&_log_ev,
"Category '%s': inherited threshold = %s (=%d)",
cat->name,
} else {
xbt_assert1(FALSE,"Unknown priority name: %s",eq+1);
}
- xbt_free(neweq);
+ free(neweq);
} else {
char buff[512];
snprintf(buff,min(512,eq - dot - 1),"%s",dot+1);
DEBUG1("This is for cat '%s'", set->catname);
}
-static xbt_error_t _xbt_log_cat_searchsub(xbt_log_category_t cat,char *name,
- /*OUT*/xbt_log_category_t*whereto) {
- xbt_error_t errcode;
+static xbt_log_category_t _xbt_log_cat_searchsub(xbt_log_category_t cat,char *name) {
xbt_log_category_t child;
if (!strcmp(cat->name,name)) {
- *whereto=cat;
- return no_error;
+ return cat;
}
for(child=cat->firstChild ; child != NULL; child = child->nextSibling) {
- errcode=_xbt_log_cat_searchsub(child,name,whereto);
- if (errcode==no_error)
- return no_error;
+ return _xbt_log_cat_searchsub(child,name);
}
- return mismatch_error;
+ THROW0(not_found_error,0,"No such category");
}
static void _cleanup_double_spaces(char *s) {
* where [category] is one the category names and keyword is one of the
* following:
*
- * thresh value is an integer priority level. Sets the category's
+ * thres value is an integer priority level. Sets the category's
* threshold priority.
*
* \warning
* logging command! Typically, this is done from main().
*/
void xbt_log_control_set(const char* control_string) {
- xbt_error_t errcode;
xbt_log_setting_t set;
char *cs;
char *p;
while (!done) {
xbt_log_category_t cat;
+ int found;
+ xbt_ex_t e;
p=strrchr(cs,' ');
if (p) {
done = 1;
}
_xbt_log_parse_setting(p,set);
-
- errcode = _xbt_log_cat_searchsub(&_XBT_LOGV(root),set->catname,&cat);
- if (errcode == mismatch_error) {
+
+ TRY {
+ cat = _xbt_log_cat_searchsub(&_XBT_LOGV(root),set->catname);
+ found = 1;
+ } CATCH(e) {
+ if (e.category != not_found_error)
+ RETHROW;
+ xbt_ex_free(e);
+ found = 0;
+
DEBUG0("Store for further application");
DEBUG1("push %p to the settings",(void*)set);
xbt_dynar_push(xbt_log_settings,&set);
/* malloc in advance the next slot */
set = xbt_new(s_xbt_log_setting_t,1);
- } else {
+ }
+
+ if (found) {
DEBUG0("Apply directly");
- xbt_free(set->catname);
+ free(set->catname);
xbt_log_threshold_set(cat,set->thresh);
}
}
- xbt_free(set);
- xbt_free(cs);
+ free(set);
+ free(cs);
}
void xbt_log_appender_set(xbt_log_category_t cat, xbt_log_appender_t app) {