Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Crash with message when trying to use a log level that is not allowed (without enable...
[simgrid.git] / src / xbt / log.c
index fac60e0..c966b11 100644 (file)
@@ -1,6 +1,6 @@
 /* log - a generic logging facility in the spirit of log4j                  */
 
-/* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
+/* Copyright (c) 2004-2011. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
 #include "xbt/sysdep.h"
 #include "xbt/log_private.h"
 #include "xbt/dynar.h"
+#include "xbt/xbt_os_thread.h"
 
-XBT_PUBLIC_DATA(int) (*xbt_pid) ();
 int xbt_log_no_loc = 0;         /* if set to true (with --log=no_loc), file localization will be omitted (for tesh tests) */
+static xbt_os_rmutex_t log_cat_init_mutex = NULL;
 
 /** \addtogroup XBT_log
  *
@@ -98,7 +99,7 @@ controlled by the <i>priority</i> concept (which should maybe be renamed to
 <i>severity</i>).
 
 Empirically, the user can specify that he wants to see every debugging message
-of GRAS while only being interested into the messages at level "error" or
+of MSG while only being interested into the messages at level "error" or
 higher about the XBT internals.
 
 \subsection log_app 1.3 Message appenders
@@ -185,7 +186,7 @@ format. This is usually a good idea.
 Here is an example of the most basic type of macro. This is a logging
 request with priority <i>warning</i>.
 
-<code>XBT_CLOG(MyCat, gras_log_priority_warning, "Values are: %d and '%s'", 5,
+<code>XBT_CLOG(MyCat, xbt_log_priority_warning, "Values are: %d and '%s'", 5,
 "oops");</code>
 
 A logging request is said to be enabled if its priority is higher than or
@@ -254,7 +255,7 @@ XBT_LOG_NEW_CATEGORY(VSS);
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(SA, VSS);
 
 int main() {
-       / * Now set the parent's priority.  (the string would typcially be a runtime option) * /
+       / * Now set the parent's priority.  (the string would typically be a runtime option) * /
        xbt_log_control_set("SA.thresh:3");
 
        / * This request is enabled, because WARNING >= INFO. * /
@@ -272,9 +273,6 @@ int main() {
 }
 \endverbatim
 
-Another example can be found in the relevant part of the GRAS tutorial:
-\ref GRAS_tut_tour_logs.
-
 \section log_user 3. User interface
 
 \section log_use_conf 3.1 Configuration
@@ -282,24 +280,45 @@ Another example can be found in the relevant part of the GRAS tutorial:
 Although rarely done, it is possible to configure the logs during
 program initialization by invoking the xbt_log_control_set() method
 manually. A more conventional way is to use the --log command line
-argument. xbt_init() (called by MSG_init(), gras_init() and friends)
+argument. xbt_init() (called by MSG_init() and friends)
 checks and deals properly with such arguments.
 
-The following command line arguments exist, but are deprecated and
-may disappear in the future: --xbt-log, --gras-log, --msg-log and
---surf-log.
-
 \subsection log_use_conf_thres 3.1.1 Threshold configuration
 
 The most common setting is to control which logging event will get
 displayed by setting a threshold to each category through the
-<tt>thres</tt> keyword.
+<tt>threshold</tt> keyword.
 
-For example, \verbatim --log=root.thres:debug\endverbatim will make
+For example, \verbatim --log=root.threshold:debug\endverbatim will make
 SimGrid <b>extremely</b> verbose while \verbatim
 --log=root.thres:critical\endverbatim should shut it almost
 completely off.
 
+Note that the <tt>threshold</tt> keyword can be abbreviated here. For example,
+all the following notations have the same result.
+\verbatim
+--log=root.threshold:debug
+--log=root.threshol:debug
+--log=root.thresho:debug
+--log=root.thresh:debug
+--log=root.thres:debug
+--log=root.thre:debug
+--log=root.thr:debug
+--log=root.th:debug
+--log=root.t:debug
+--log=root.:debug     <--- That's obviously really ugly, but it actually works.
+\endverbatim
+
+The full list of recognized thresholds is the following:
+
+ - trace: enter and return of some functions
+ - debug: crufty output
+ - verbose: verbose output for the user wanting more
+ - info: output about the regular functionning
+ - warning: minor issue encountered
+ - error: issue encountered
+ - critical: major issue encountered 
+
 \subsection log_use_conf_multi 3.1.2 Passing several settings
 
 You can provide several of those arguments to change the setting of several
@@ -332,7 +351,7 @@ Here are the existing format directives:
  - %%p: Priority name (LOG4J compatible)
 
  - %%h: Hostname (SimGrid extension)
- - %%P: Process name (SimGrid extension)
+ - %%P: Process name (SimGrid extension -- note that with SMPI this is the integer value of the process rank)
  - %%t: Thread "name" (LOG4J compatible -- actually the address of the thread in memory)
  - %%i: Process PID (SimGrid extension -- this is a 'i' as in 'i'dea)
 
@@ -419,10 +438,10 @@ requires an a single comparison of a static variable to a constant.
 
 There is also compile time constant, \ref XBT_LOG_STATIC_THRESHOLD, which
 causes all logging requests with a lower priority to be optimized to 0 cost
-by the compiler. By setting it to gras_log_priority_infinite, all logging
+by the compiler. By setting it to xbt_log_priority_infinite, all logging
 requests are statically disabled at compile time and cost nothing. Released executables
 <i>might</i>  be compiled with (note that it will prevent users to debug their problems)
-\verbatim-DXBT_LOG_STATIC_THRESHOLD=gras_log_priority_infinite\endverbatim
+\verbatim-DXBT_LOG_STATIC_THRESHOLD=xbt_log_priority_infinite\endverbatim
 
 Compiling with the \verbatim-DNLOG\endverbatim option disables all logging
 requests at compilation time while the \verbatim-DNDEBUG\endverbatim disables
@@ -456,19 +475,15 @@ The default appender function currently prints to stderr, and the only other
 existing one writes to the specified file. More would be needed, like the one
 able to send the logs to a remote dedicated server.
 This is on our TODO list for quite a while now, but your help would be
-welcome here, too.
-
-
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              *//*' */
-
+welcome here, too. */
 
 xbt_log_appender_t xbt_log_default_appender = NULL;     /* set in log_init */
 xbt_log_layout_t xbt_log_default_layout = NULL; /* set in log_init */
 
 typedef struct {
   char *catname;
-  e_xbt_log_priority_t thresh;
   char *fmt;
+  e_xbt_log_priority_t thresh;
   int additivity;
   xbt_log_appender_t appender;
 } s_xbt_log_setting_t, *xbt_log_setting_t;
@@ -480,8 +495,7 @@ static void _free_setting(void *s)
   xbt_log_setting_t set = *(xbt_log_setting_t *) s;
   if (set) {
     free(set->catname);
-    if (set->fmt)
-      free(set->fmt);
+    free(set->fmt);
     free(set);
   }
 }
@@ -502,19 +516,13 @@ const char *xbt_log_priority_names[8] = {
 
 s_xbt_log_category_t _XBT_LOGV(XBT_LOG_ROOT_CAT) = {
   NULL /*parent */ , NULL /* firstChild */ , NULL /* nextSibling */ ,
-      "root", xbt_log_priority_uninitialized /* threshold */ ,
+      "root", "The common ancestor for all categories",
+      0 /*initialized */, xbt_log_priority_uninitialized /* threshold */ ,
       0 /* isThreshInherited */ ,
       NULL /* appender */ , NULL /* layout */ ,
       0                         /* additivity */
 };
 
-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_CATEGORY(simix, "All SIMIX categories");
-XBT_LOG_NEW_CATEGORY(mc, "All MC categories");
-XBT_LOG_NEW_CATEGORY(bindings, "All bindings categories");
-
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(log, xbt,
                                 "Loggings from the logging mechanism itself");
 
@@ -526,48 +534,225 @@ void xbt_log_preinit(void)
   xbt_log_default_layout = xbt_log_layout_simple_new(NULL);
   _XBT_LOGV(XBT_LOG_ROOT_CAT).appender = xbt_log_default_appender;
   _XBT_LOGV(XBT_LOG_ROOT_CAT).layout = xbt_log_default_layout;
+  log_cat_init_mutex = xbt_os_rmutex_init();
 }
 
+static void xbt_log_connect_categories(void)
+{
+  /* Connect our log channels: that must be done manually under windows */
+  /* Also permit that they are correctly listed by xbt_log_help_categories() */
+
+  /* xbt */
+  XBT_LOG_CONNECT(xbt);
+  XBT_LOG_CONNECT(graphxml_parse);
+  XBT_LOG_CONNECT(log);
+#if HAVE_MMAP
+  XBT_LOG_CONNECT(mm_diff);
+#endif
+  XBT_LOG_CONNECT(module);
+  XBT_LOG_CONNECT(peer);
+  XBT_LOG_CONNECT(replay);
+  XBT_LOG_CONNECT(strbuff);
+  XBT_LOG_CONNECT(xbt_cfg);
+  XBT_LOG_CONNECT(xbt_dict);
+  XBT_LOG_CONNECT(xbt_dict_cursor);
+  XBT_LOG_CONNECT(xbt_dict_elm);
+#ifdef XBT_USE_DEPRECATED
+  XBT_LOG_CONNECT(xbt_dict_multi);
+#endif
+  XBT_LOG_CONNECT(xbt_dyn);
+  XBT_LOG_CONNECT(xbt_ex);
+  XBT_LOG_CONNECT(xbt_fifo);
+  XBT_LOG_CONNECT(xbt_graph);
+  XBT_LOG_CONNECT(xbt_heap);
+  XBT_LOG_CONNECT(xbt_lib);
+  XBT_LOG_CONNECT(xbt_mallocator);
+  XBT_LOG_CONNECT(xbt_matrix);
+  XBT_LOG_CONNECT(xbt_parmap);
+  XBT_LOG_CONNECT(xbt_queue);
+  XBT_LOG_CONNECT(xbt_set);
+  XBT_LOG_CONNECT(xbt_sync);
+  XBT_LOG_CONNECT(xbt_sync_os);
+
+#ifdef simgrid_EXPORTS
+  /* The following categories are only defined in libsimgrid */
+
+  /* bindings */
+#ifdef HAVE_LUA
+  XBT_LOG_CONNECT(bindings);
+  XBT_LOG_CONNECT(lua);
+  XBT_LOG_CONNECT(lua_comm);
+  XBT_LOG_CONNECT(lua_host);
+  XBT_LOG_CONNECT(lua_platf);
+  XBT_LOG_CONNECT(lua_process);
+  XBT_LOG_CONNECT(lua_state_cloner);
+  XBT_LOG_CONNECT(lua_task);
+  XBT_LOG_CONNECT(lua_utils);
+#endif
+
+  /* instr */
+#ifdef HAVE_TRACING
+  XBT_LOG_CONNECT(instr);
+  XBT_LOG_CONNECT(instr_api);
+  XBT_LOG_CONNECT(instr_config);
+  XBT_LOG_CONNECT(instr_msg);
+  XBT_LOG_CONNECT(instr_msg_process);
+  XBT_LOG_CONNECT(instr_msg_vm);
+  XBT_LOG_CONNECT(instr_paje_containers);
+  XBT_LOG_CONNECT(instr_paje_header);
+  XBT_LOG_CONNECT(instr_paje_trace);
+  XBT_LOG_CONNECT(instr_paje_types);
+  XBT_LOG_CONNECT(instr_paje_values);
+  XBT_LOG_CONNECT(instr_resource);
+  XBT_LOG_CONNECT(instr_routing);
+  XBT_LOG_CONNECT(instr_sd);
+  XBT_LOG_CONNECT(instr_surf);
+#endif
+
+  /* jedule */
+#ifdef HAVE_JEDULE
+  XBT_LOG_CONNECT(jedule);
+  XBT_LOG_CONNECT(jed_out);
+  XBT_LOG_CONNECT(jed_sd);
+#endif
+
+  /* mc */
+#ifdef HAVE_MC
+  XBT_LOG_CONNECT(mc);
+  XBT_LOG_CONNECT(mc_checkpoint);
+  XBT_LOG_CONNECT(mc_compare);
+  XBT_LOG_CONNECT(mc_dpor);
+  XBT_LOG_CONNECT(mc_global);
+  XBT_LOG_CONNECT(mc_liveness);
+  XBT_LOG_CONNECT(mc_memory);
+  XBT_LOG_CONNECT(mc_memory_map);
+  XBT_LOG_CONNECT(mc_request);
+#endif
+
+  /* msg */
+  XBT_LOG_CONNECT(msg);
+  XBT_LOG_CONNECT(msg_action);
+  XBT_LOG_CONNECT(msg_gos);
+  XBT_LOG_CONNECT(msg_io);
+  XBT_LOG_CONNECT(msg_kernel);
+  XBT_LOG_CONNECT(msg_mailbox);
+  XBT_LOG_CONNECT(msg_new_API);
+  XBT_LOG_CONNECT(msg_process);
+  XBT_LOG_CONNECT(msg_synchro);
+  XBT_LOG_CONNECT(msg_task);
+  XBT_LOG_CONNECT(msg_vm);
+   
+  /* simdag */
+  XBT_LOG_CONNECT(sd);
+  XBT_LOG_CONNECT(sd_daxparse);
+#ifdef HAVE_GRAPHVIZ
+  XBT_LOG_CONNECT(sd_dotparse);
+#endif
+  XBT_LOG_CONNECT(sd_kernel);
+  XBT_LOG_CONNECT(sd_task);
+  XBT_LOG_CONNECT(sd_workstation);
+
+  /* simix */
+  XBT_LOG_CONNECT(simix);
+  XBT_LOG_CONNECT(simix_context);
+  XBT_LOG_CONNECT(simix_deployment);
+  XBT_LOG_CONNECT(simix_environment);
+  XBT_LOG_CONNECT(simix_host);
+  XBT_LOG_CONNECT(simix_io);
+  XBT_LOG_CONNECT(simix_kernel);
+  XBT_LOG_CONNECT(simix_network);
+  XBT_LOG_CONNECT(simix_new_api);
+  XBT_LOG_CONNECT(simix_process);
+  XBT_LOG_CONNECT(simix_smurf);
+  XBT_LOG_CONNECT(simix_synchro);
+
+  /* smpi */
+  /* SMPI categories are connected in smpi_global.c */
+
+  /* surf */
+  XBT_LOG_CONNECT(surf);
+  XBT_LOG_CONNECT(platf_generator);
+  XBT_LOG_CONNECT(random);
+  XBT_LOG_CONNECT(surf_config);
+  XBT_LOG_CONNECT(surf_cpu);
+  XBT_LOG_CONNECT(surf_cpu_ti);
+  XBT_LOG_CONNECT(surf_kernel);
+  XBT_LOG_CONNECT(surf_lagrange);
+  XBT_LOG_CONNECT(surf_lagrange_dichotomy);
+  XBT_LOG_CONNECT(surf_maxmin);
+  XBT_LOG_CONNECT(surf_network);
+  XBT_LOG_CONNECT(surf_new_model);
+#ifdef HAVE_GTNETS
+  XBT_LOG_CONNECT(surf_network_gtnets);
+  XBT_LOG_CONNECT(surf_network_gtnets_interface);
+  XBT_LOG_CONNECT(surf_network_gtnets_simulator);
+  XBT_LOG_CONNECT(surf_network_gtnets_topology);
+#endif
+#ifdef HAVE_NS3
+  XBT_LOG_CONNECT(surf_network_ns3);
+  XBT_LOG_CONNECT(interface_ns3);
+  XBT_LOG_CONNECT(simulator_ns3);
+#endif
+  XBT_LOG_CONNECT(surf_parse);
+  XBT_LOG_CONNECT(surf_route);
+  XBT_LOG_CONNECT(surf_routing_generic);
+  XBT_LOG_CONNECT(surf_route_cluster);
+  XBT_LOG_CONNECT(surf_route_dijkstra);
+  XBT_LOG_CONNECT(surf_route_floyd);
+  XBT_LOG_CONNECT(surf_route_full);
+  XBT_LOG_CONNECT(surf_route_none);
+  XBT_LOG_CONNECT(surf_route_vivaldi);
+  XBT_LOG_CONNECT(surf_storage);
+  XBT_LOG_CONNECT(surf_trace);
+  XBT_LOG_CONNECT(surf_workstation);
+
+#endif /* simgrid_EXPORTS */
+}
+
+static void xbt_log_help(void);
+static void xbt_log_help_categories(void);
+
 /** @brief Get all logging settings from the command line
  *
  * xbt_log_control_set() is called on each string we got from cmd line
  */
 void xbt_log_init(int *argc, char **argv)
 {
+  unsigned help_requested = 0;  /* 1: logs; 2: categories */
   int i, j;
   char *opt;
 
   //    _XBT_LOGV(log).threshold = xbt_log_priority_debug; /* uncomment to set the LOG category to debug directly */
 
-  /* Set logs and init log submodule */
-  for (i = 1; i < *argc; i++) {
-    if (!strncmp(argv[i], "--log=", strlen("--log=")) ||
-        !strncmp(argv[i], "--gras-log=", strlen("--gras-log=")) ||
-        !strncmp(argv[i], "--surf-log=", strlen("--surf-log=")) ||
-        !strncmp(argv[i], "--msg-log=", strlen("--msg-log=")) ||
-        !strncmp(argv[i], "--simix-log=", strlen("--simix-log=")) ||
-        !strncmp(argv[i], "--xbt-log=", strlen("--xbt-log="))) {
-
-      if (strncmp(argv[i], "--log=", strlen("--log=")))
-        XBT_WARN
-            ("Option %.*s is deprecated and will disapear in the future. Use --log instead.",
-             (int) (strchr(argv[i], '=') - argv[i]), argv[i]);
+  xbt_log_connect_categories();
 
+  /* Set logs and init log submodule */
+  for (j = i = 1; i < *argc; i++) {
+    if (!strncmp(argv[i], "--log=", strlen("--log="))) {
       opt = strchr(argv[i], '=');
       opt++;
       xbt_log_control_set(opt);
       XBT_DEBUG("Did apply '%s' as log setting", opt);
-      /*remove this from argv */
-
-      for (j = i + 1; j < *argc; j++) {
-        argv[j - 1] = argv[j];
-      }
-
-      argv[j - 1] = NULL;
-      (*argc)--;
-      i--;                      /* compensate effect of next loop incrementation */
+    } else if (!strcmp(argv[i], "--help-logs")) {
+      help_requested |= 1;
+    } else if (!strcmp(argv[i], "--help-log-categories")) {
+      help_requested |= 2;
+    } else {
+      argv[j++] = argv[i];
     }
   }
+  if (j < *argc) {
+    argv[j] = NULL;
+    *argc = j;
+  }
+
+  if (help_requested) {
+    if (help_requested & 1)
+      xbt_log_help();
+    if (help_requested & 2)
+      xbt_log_help_categories();
+    exit(0);
+  }
 }
 
 static void log_cat_exit(xbt_log_category_t cat)
@@ -592,38 +777,73 @@ static void log_cat_exit(xbt_log_category_t cat)
 void xbt_log_postexit(void)
 {
   XBT_VERB("Exiting log");
+  xbt_os_rmutex_destroy(log_cat_init_mutex);
   xbt_dynar_free(&xbt_log_settings);
   log_cat_exit(&_XBT_LOGV(XBT_LOG_ROOT_CAT));
 }
 
+ /* Size of the static string in which we  build the log string */
+#define XBT_LOG_STATIC_BUFFER_SIZE 2048
+/* Minimum size of the dynamic string in which we build the log string
+   (should be greater than XBT_LOG_STATIC_BUFFER_SIZE) */
+#define XBT_LOG_DYNAMIC_BUFFER_SIZE 4096
+
 void _xbt_log_event_log(xbt_log_event_t ev, const char *fmt, ...)
 {
-
   xbt_log_category_t cat = ev->cat;
 
-  va_start(ev->ap, fmt);
-  va_start(ev->ap_copy, fmt);
-  while (1) {
+  xbt_assert(ev->priority >= 0,
+             "Negative logging priority naturally forbidden");
+  xbt_assert(ev->priority < sizeof(xbt_log_priority_names),
+             "Priority %d is greater than the biggest allowed value",
+             ev->priority);
+
+  do {
     xbt_log_appender_t appender = cat->appender;
-    if (appender != NULL) {
-      xbt_assert(cat->layout,
-                  "No valid layout for the appender of category %s",
-                  cat->name);
-      cat->layout->do_layout(cat->layout, ev, fmt, appender);
+
+    if (!appender)
+      continue;                 /* No appender, try next */
+
+    xbt_assert(cat->layout,
+               "No valid layout for the appender of category %s", cat->name);
+
+    /* First, try with a static buffer */
+    if (XBT_LOG_STATIC_BUFFER_SIZE) {
+      char buff[XBT_LOG_STATIC_BUFFER_SIZE];
+      int done;
+      ev->buffer = buff;
+      ev->buffer_size = sizeof buff;
+      va_start(ev->ap, fmt);
+      done = cat->layout->do_layout(cat->layout, ev, fmt);
+      va_end(ev->ap);
+      if (done) {
+        appender->do_append(appender, buff);
+        continue;               /* Ok, that worked: go next */
+      }
     }
-    if (!cat->additivity)
-      break;
 
-    cat = cat->parent;
-  }
-  va_end(ev->ap);
-  va_end(ev->ap_copy);
+    /* The static buffer was too small, use a dynamically expanded one */
+    ev->buffer_size = XBT_LOG_DYNAMIC_BUFFER_SIZE;
+    ev->buffer = xbt_malloc(ev->buffer_size);
+    while (1) {
+      int done;
+      va_start(ev->ap, fmt);
+      done = cat->layout->do_layout(cat->layout, ev, fmt);
+      va_end(ev->ap);
+      if (done)
+        break;                  /* Got it */
+      ev->buffer_size *= 2;
+      ev->buffer = xbt_realloc(ev->buffer, ev->buffer_size);
+    }
+    appender->do_append(appender, ev->buffer);
+    xbt_free(ev->buffer);
 
-#ifdef _XBT_WIN32
-  free(ev->buffer);
-#endif
+  } while (cat->additivity && (cat = cat->parent, 1));
 }
 
+#undef XBT_LOG_DYNAMIC_BUFFER_SIZE
+#undef XBT_LOG_STATIC_BUFFER_SIZE
+
 /* NOTE:
  *
  * The standard logging macros use _XBT_LOG_ISENABLED, which calls
@@ -683,6 +903,17 @@ int _xbt_log_cat_init(xbt_log_category_t category,
 {
 #define _xbt_log_cat_init(a, b) (0)
 
+  if (log_cat_init_mutex != NULL) {
+    xbt_os_rmutex_acquire(log_cat_init_mutex);
+  }
+
+  if (category->initialized) {
+    if (log_cat_init_mutex != NULL) {
+      xbt_os_rmutex_release(log_cat_init_mutex);
+    }
+    return priority >= category->threshold;
+  }
+
   unsigned int cursor;
   xbt_log_setting_t setting = NULL;
   int found = 0;
@@ -694,7 +925,6 @@ int _xbt_log_cat_init(xbt_log_category_t category,
 
   if (category == &_XBT_LOGV(XBT_LOG_ROOT_CAT)) {
     category->threshold = xbt_log_priority_info;
-    /* xbt_log_priority_debug */ ;
     category->appender = xbt_log_default_appender;
     category->layout = xbt_log_default_layout;
   } else {
@@ -704,9 +934,8 @@ int _xbt_log_cat_init(xbt_log_category_t category,
 
     XBT_DEBUG("Set %s (%s) as father of %s ",
            category->parent->name,
-           (category->parent->threshold == xbt_log_priority_uninitialized ?
-            "uninited" : xbt_log_priority_names[category->
-                                                parent->threshold]),
+           (category->parent->initialized ?
+            xbt_log_priority_names[category->parent->threshold] : "uninited"),
            category->name);
     xbt_log_parent_set(category, category->parent);
 
@@ -724,7 +953,7 @@ int _xbt_log_cat_init(xbt_log_category_t category,
         cpp = cpp->nextSibling;
       }
 
-      XBT_DEBUG("Childs of %s: %s; nextSibling: %s",
+      XBT_DEBUG("Children of %s: %s; nextSibling: %s",
              category->parent->name, res,
              (category->parent->nextSibling ?
               category->parent->nextSibling->name : "none"));
@@ -735,32 +964,32 @@ int _xbt_log_cat_init(xbt_log_category_t category,
   }
 
   /* Apply the control */
-  if (!xbt_log_settings)
-    return priority >= category->threshold;
-
-  xbt_assert(category, "NULL category");
-  xbt_assert(category->name);
-
-  xbt_dynar_foreach(xbt_log_settings, cursor, setting) {
-    xbt_assert(setting, "Damnit, NULL cat in the list");
-    xbt_assert(setting->catname, "NULL setting(=%p)->catname",
-                (void *) setting);
-
-    if (!strcmp(setting->catname, category->name)) {
-
-      found = 1;
-
-      _xbt_log_cat_apply_set(category, setting);
-
-      xbt_dynar_cursor_rm(xbt_log_settings, &cursor);
+  if (xbt_log_settings) {
+    xbt_assert(category, "NULL category");
+    xbt_assert(category->name);
+
+    xbt_dynar_foreach(xbt_log_settings, cursor, setting) {
+      xbt_assert(setting, "Damnit, NULL cat in the list");
+      xbt_assert(setting->catname, "NULL setting(=%p)->catname",
+                 (void *) setting);
+
+      if (!strcmp(setting->catname, category->name)) {
+        found = 1;
+        _xbt_log_cat_apply_set(category, setting);
+        xbt_dynar_cursor_rm(xbt_log_settings, &cursor);
+      }
     }
-  }
 
-  if (!found)
-    XBT_DEBUG("Category '%s': inherited threshold = %s (=%d)",
-           category->name, xbt_log_priority_names[category->threshold],
-           category->threshold);
+    if (!found)
+      XBT_DEBUG("Category '%s': inherited threshold = %s (=%d)",
+                category->name, xbt_log_priority_names[category->threshold],
+                category->threshold);
+  }
 
+  category->initialized = 1;
+  if (log_cat_init_mutex != NULL) {
+    xbt_os_rmutex_release(log_cat_init_mutex);
+  }
   return priority >= category->threshold;
 
 #undef _xbt_log_cat_init
@@ -768,17 +997,13 @@ int _xbt_log_cat_init(xbt_log_category_t category,
 
 void xbt_log_parent_set(xbt_log_category_t cat, xbt_log_category_t parent)
 {
-
   xbt_assert(cat, "NULL category to be given a parent");
   xbt_assert(parent, "The parent category of %s is NULL", cat->name);
 
-  /*
-   * if the threshold is initialized
-   * unlink from current parent
-   */
-  if (cat->threshold != xbt_log_priority_uninitialized) {
+  /* if the category is initialized, unlink from current parent */
+  if (cat->initialized) {
 
-    xbt_log_category_t *cpp = &parent->firstChild;
+    xbt_log_category_t *cpp = &cat->parent->firstChild;
 
     while (*cpp != cat && *cpp != NULL) {
       cpp = &(*cpp)->nextSibling;
@@ -793,16 +1018,12 @@ void xbt_log_parent_set(xbt_log_category_t cat, xbt_log_category_t parent)
 
   parent->firstChild = cat;
 
-  if (parent->threshold == xbt_log_priority_uninitialized) {
-
-    _xbt_log_cat_init(parent,
-                      xbt_log_priority_uninitialized /* ignored */ );
-  }
+  if (!parent->initialized)
+    _xbt_log_cat_init(parent, xbt_log_priority_uninitialized /* ignored */ );
 
   cat->threshold = parent->threshold;
 
   cat->isThreshInherited = 1;
-
 }
 
 static void _set_inherited_thresholds(xbt_log_category_t cat)
@@ -861,7 +1082,7 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
   xbt_assert(*dot == '.' && (*eq == '=' || *eq == ':'),
               "Invalid control string '%s'", control_string);
 
-  if (!strncmp(dot + 1, "thresh", (size_t) (eq - dot - 1))) {
+  if (!strncmp(dot + 1, "threshold", (size_t) (eq - dot - 1))) {
     int i;
     char *neweq = xbt_strdup(eq + 1);
     char *p = neweq - 1;
@@ -879,7 +1100,12 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
         break;
       }
     }
-    if (i < xbt_log_priority_infinite) {
+
+    if(i<XBT_LOG_STATIC_THRESHOLD){
+     THROWF(arg_error, 0,
+             "Priority: %s is above allowed priority : %s (for debug and trace levels, recompile SimGrid with -Denable_debug=ON)",
+             eq + 1, xbt_log_priority_names[XBT_LOG_STATIC_THRESHOLD]);
+    }else if (i < xbt_log_priority_infinite) {
       set->thresh = (e_xbt_log_priority_t) i;
     } else {
       THROWF(arg_error, 0,
@@ -1003,7 +1229,7 @@ void xbt_log_control_set(const char *control_string)
   /* split the string, and remove empty entries */
   set_strings = xbt_str_split_quoted(control_string);
 
-  if (xbt_dynar_length(set_strings) == 0) {     /* vicious user! */
+  if (xbt_dynar_is_empty(set_strings)) {     /* vicious user! */
     xbt_dynar_free(&set_strings);
     return;
   }
@@ -1065,3 +1291,108 @@ void xbt_log_additivity_set(xbt_log_category_t cat, int additivity)
 {
   cat->additivity = additivity;
 }
+
+static void xbt_log_help(void)
+{
+  printf(
+"Description of the logging output:\n"
+"\n"
+"   Threshold configuration: --log=CATEGORY_NAME.thres:PRIORITY_LEVEL\n"
+"      CATEGORY_NAME: defined in code with function 'XBT_LOG_NEW_CATEGORY'\n"
+"      PRIORITY_LEVEL: the level to print (trace,debug,verbose,info,warning,error,critical)\n"
+"         -> trace: enter and return of some functions\n"
+"         -> debug: crufty output\n"
+"         -> verbose: verbose output for the user wanting more\n"
+"         -> info: output about the regular functionning\n"
+"         -> warning: minor issue encountered\n"
+"         -> error: issue encountered\n"
+"         -> critical: major issue encountered\n"
+"\n"
+"   Format configuration: --log=CATEGORY_NAME.fmt:OPTIONS\n"
+"      OPTIONS may be:\n"
+"         -> %%%%: the %% char\n"
+"         -> %%n: platform-dependent line separator (LOG4J compatible)\n"
+"         -> %%e: plain old space (SimGrid extension)\n"
+"\n"
+"         -> %%m: user-provided message\n"
+"\n"
+"         -> %%c: Category name (LOG4J compatible)\n"
+"         -> %%p: Priority name (LOG4J compatible)\n"
+"\n"
+"         -> %%h: Hostname (SimGrid extension)\n"
+"         -> %%P: Process name (SimGrid extension)\n"
+"         -> %%t: Thread \"name\" (LOG4J compatible -- actually the address of the thread in memory)\n"
+"         -> %%i: Process PID (SimGrid extension -- this is a 'i' as in 'i'dea)\n"
+"\n"
+"         -> %%F: file name where the log event was raised (LOG4J compatible)\n"
+"         -> %%l: location where the log event was raised (LOG4J compatible, like '%%F:%%L' -- this is a l as in 'l'etter)\n"
+"         -> %%L: line number where the log event was raised (LOG4J compatible)\n"
+"         -> %%M: function name (LOG4J compatible -- called method name here of course).\n"
+"                 Defined only when using gcc because there is no __FUNCTION__ elsewhere.\n"
+"\n"
+"         -> %%b: full backtrace (Called %%throwable in LOG4J). Defined only under windows or when using the GNU libc because\n"
+"                 backtrace() is not defined elsewhere, and we only have a fallback for windows boxes, not mac ones for example.\n"
+"         -> %%B: short backtrace (only the first line of the %%b). Called %%throwable{short} in LOG4J; defined where %%b is.\n"
+"\n"
+"         -> %%d: date (UNIX-like epoch)\n"
+"         -> %%r: application age (time elapsed since the beginning of the application)\n"
+"\n"
+"   Miscellaneous:\n"
+"      --help-log-categories    Display the current hierarchy of log categories.\n"
+"      --log=no_loc             Don't print file names in messages (for tesh tests).\n"
+"\n"
+    );
+}
+
+static int xbt_log_cat_cmp(const void *pa, const void *pb)
+{
+  xbt_log_category_t a = *(xbt_log_category_t *)pa;
+  xbt_log_category_t b = *(xbt_log_category_t *)pb;
+  return strcmp(a->name, b->name);
+}
+
+static void xbt_log_help_categories_rec(xbt_log_category_t category,
+                                        const char *prefix)
+{
+  char *this_prefix;
+  char *child_prefix;
+  xbt_dynar_t dynar;
+  unsigned i;
+  xbt_log_category_t cat;
+
+  if (!category)
+    return;
+
+  if (category->parent) {
+    this_prefix = bprintf("%s \\_ ", prefix);
+    child_prefix = bprintf("%s |  ", prefix);
+  } else {
+    this_prefix = xbt_strdup(prefix);
+    child_prefix = xbt_strdup(prefix);
+  }
+
+  dynar = xbt_dynar_new(sizeof(xbt_log_category_t), NULL);
+  for (cat = category ; cat != NULL; cat = cat->nextSibling)
+    xbt_dynar_push_as(dynar, xbt_log_category_t, cat);
+
+  xbt_dynar_sort(dynar, xbt_log_cat_cmp);
+
+  for (i = 0; i < xbt_dynar_length(dynar); i++) {
+    if (i == xbt_dynar_length(dynar) - 1 && category->parent)
+      *strrchr(child_prefix, '|') = ' ';
+    cat = xbt_dynar_get_as(dynar, i, xbt_log_category_t);
+    printf("%s%s: %s\n", this_prefix, cat->name, cat->description);
+    xbt_log_help_categories_rec(cat->firstChild, child_prefix);
+  }
+
+  xbt_dynar_free(&dynar);
+  xbt_free(this_prefix);
+  xbt_free(child_prefix);
+}
+
+static void xbt_log_help_categories(void)
+{
+  printf("Current log category hierarchy:\n");
+  xbt_log_help_categories_rec(&_XBT_LOGV(XBT_LOG_ROOT_CAT), "   ");
+  printf("\n");
+}