/* log - a generic logging facility in the spirit of log4j */
-/* Copyright (c) 2003, 2004 Martin Quinson. All rights reserved. */
+/* Copyright (c) 2003-2007 Martin Quinson. All rights reserved. */
/* 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 "xbt/misc.h"
#include "xbt/ex.h"
+#include "xbt/str.h"
#include "xbt/sysdep.h"
-#include "xbt/log.h"
+#include "xbt/log_private.h"
#include "xbt/dynar.h"
XBT_PUBLIC_DATA(int) (*xbt_pid)();
- %%p: Priority name (LOG4J compliant)
- %%h: Hostname (SimGrid extension)
- - %%t: Process name (LOG4J compliant -- thread name in LOG4J)
- - %%I: Process PID (SimGrid extension)
+ - %%P: Process name (SimGrid extension)
+ - %%t: Thread "name" (LOG4J compliant -- actually the address of the thread in memory)
+ - %%i: Process PID (SimGrid extension -- this is a 'i' as in 'i'dea)
- %%F: file name where the log event was raised (LOG4J compliant)
- - %%l: location where the log event was raised (LOG4J compliant, like '%%F:%%L')
+ - %%l: location where the log event was raised (LOG4J compliant, like '%%F:%%L' -- this is a l as in 'l'etter)
- %%L: line number where the log event was raised (LOG4J compliant)
- %%M: function name (LOG4J compliant -- called method name here of course).
Defined only when using gcc because there is no __FUNCTION__ elsewhere.
The <tt>add</tt> keyword allows to specify the additivity of a
category (see \ref log_in_app). This is rarely useful since you
cannot specify an alternative appender. Anyway, '0', '1', 'no',
-'ye's, 'on' and 'off' are all valid values, with 'yes' as default.
+'yes', 'on' and 'off' are all valid values, with 'yes' as default.
\section log_use_misc 3.2 Misc and Caveats
"CRITICAL"
};
-XBT_PUBLIC_DATA(s_xbt_log_category_t) _XBT_LOGV(XBT_LOG_ROOT_CAT) = {
- 0, 0, 0,
- "root", xbt_log_priority_uninitialized, 0,
- NULL, 0
+s_xbt_log_category_t _XBT_LOGV(XBT_LOG_ROOT_CAT) = {
+ NULL /*parent*/, NULL /* firstChild */, NULL /* nextSibling */,
+ "root", 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_DEFAULT_SUBCATEGORY(log,xbt,"Loggings from the logging mechanism itself");
/** @brief Get all logging settings from the command line
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_usable = 1;
+ _log_usable = 1;
+
+// _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++){
xbt_log_category_t cat = ev->cat;
if (!_log_usable) {
- fprintf(stderr,"XXXXXXXXXXXXXXXXXXX\nXXX Warning, logs not usable here. Either before xbt_init() or after xbt_exit().\nXXXXXXXXXXXXXXXXXXX\n");
- va_start(ev->ap, fmt);
- vfprintf(stderr,fmt,ev->ap);
- va_end(ev->ap);
- xbt_backtrace_display();
- return;
+ /* Make sure that the layouts have been malloced */
+ xbt_log_default_appender = xbt_log_appender_file_new(NULL);
+ 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_usable = 1;
}
va_start(ev->ap, fmt);
+ va_start(ev->ap_copy, fmt);
while(1) {
xbt_log_appender_t appender = cat->appender;
if (appender != NULL) {
xbt_assert1(cat->layout,"No valid layout for the appender of category %s",cat->name);
- char *str= cat->layout->do_layout(cat->layout, ev, fmt);
- appender->do_append(appender, str);
+ cat->layout->do_layout(cat->layout, ev, fmt, appender);
}
if (!cat->additivity)
break;
cat = cat->parent;
}
va_end(ev->ap);
+ va_end(ev->ap_copy);
}
static void _xbt_log_cat_apply_set(xbt_log_category_t category,
*/
int _xbt_log_cat_init(xbt_log_category_t category,
e_xbt_log_priority_t priority) {
- int cursor;
+ unsigned int cursor;
xbt_log_setting_t setting=NULL;
int found = 0;
s_xbt_log_event_t _log_ev;
-
+
+ if (_XBT_LOGV(log).threshold <= xbt_log_priority_debug
+ && _XBT_LOGV(log).threshold != xbt_log_priority_uninitialized) {
+ _log_ev.cat = &_XBT_LOGV(log);
+ _log_ev.priority = xbt_log_priority_debug;
+ _log_ev.fileName = __FILE__ ;
+ _log_ev.functionName = _XBT_FUNCTION ;
+ _log_ev.lineNum = __LINE__ ;
+ _xbt_log_event_log(&_log_ev, "Initializing category '%s' (firstChild=%s, nextSibling=%s)",
+ category->name,
+ (category->firstChild ?category->firstChild->name :"none"),
+ (category->nextSibling?category->nextSibling->name:"none"));
+ }
+
if(category == &_XBT_LOGV(XBT_LOG_ROOT_CAT)){
category->threshold = xbt_log_priority_info;/* xbt_log_priority_debug*/;
category->appender = xbt_log_default_appender;
if (!category->parent)
category->parent = &_XBT_LOGV(XBT_LOG_ROOT_CAT);
+ if (_XBT_LOGV(log).threshold <= xbt_log_priority_debug
+ && _XBT_LOGV(log).threshold != xbt_log_priority_uninitialized) {
+ _log_ev.lineNum = __LINE__ ;
+ _xbt_log_event_log(&_log_ev, "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->name);
+ }
xbt_log_parent_set(category, category->parent);
+
+ if (_XBT_LOGV(log).threshold < xbt_log_priority_info
+ && _XBT_LOGV(log).threshold != xbt_log_priority_uninitialized) {
+ char *buf,*res=NULL;
+ xbt_log_category_t cpp = category->parent->firstChild;
+ while (cpp) {
+ if (res) {
+ buf = bprintf("%s %s",res,cpp->name);
+ free(res);
+ res = buf;
+ } else {
+ res = xbt_strdup(cpp->name);
+ }
+ cpp = cpp->nextSibling;
+ }
+
+ _log_ev.lineNum = __LINE__ ;
+ _xbt_log_event_log(&_log_ev,
+ "Childs of %s: %s; nextSibling: %s", category->parent->name,res,
+ (category->parent->nextSibling?category->parent->nextSibling->name:"none"));
+
+ free(res);
+ }
+
}
/* Apply the control */
if (!found && category->threshold <= xbt_log_priority_verbose) {
- _log_ev.cat = category;
+ _log_ev.cat = &_XBT_LOGV(log);
_log_ev.priority = xbt_log_priority_verbose;
_log_ev.fileName = __FILE__ ;
_log_ev.functionName = _XBT_FUNCTION ;
return priority >= category->threshold;
}
-void xbt_log_parent_set(xbt_log_category_t cat,xbt_log_category_t parent)
-{
+void xbt_log_parent_set(xbt_log_category_t cat,xbt_log_category_t parent) {
xbt_assert0(cat,"NULL category to be given a parent");
xbt_assert1(parent,"The parent category of %s is NULL",cat->name);
}
static xbt_log_category_t _xbt_log_cat_searchsub(xbt_log_category_t cat,char *name) {
- xbt_log_category_t child;
+ xbt_log_category_t child,res;
+ DEBUG4("Search '%s' into '%s' (firstChild='%s'; nextSibling='%s')",name,cat->name,
+ (cat->firstChild ? cat->firstChild->name :"none"),
+ (cat->nextSibling ? cat->nextSibling->name:"none"));
if (!strcmp(cat->name,name))
return cat;
- for(child=cat->firstChild ; child != NULL; child = child->nextSibling)
- return _xbt_log_cat_searchsub(child,name);
-
- THROW1(not_found_error,0,"No such category: %s", name);
+ for (child=cat->firstChild ; child != NULL; child = child->nextSibling) {
+ DEBUG1("Dig into %s",child->name);
+ res = _xbt_log_cat_searchsub(child,name);
+ if (res)
+ return res;
+ }
+
+ return NULL;
}
/**
/* To split the string in commands, and the cursors */
xbt_dynar_t set_strings;
char *str;
- int cpt;
+ unsigned int cpt;
if (!control_string)
return;
created), or store it for further use */
xbt_dynar_foreach(set_strings,cpt,str) {
xbt_log_category_t cat=NULL;
- int found=0;
- xbt_ex_t e;
set = _xbt_log_parse_setting(str);
+ cat = _xbt_log_cat_searchsub(&_XBT_LOGV(XBT_LOG_ROOT_CAT),set->catname);
- 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;
- }
-
- if (found) {
+ if (cat) {
DEBUG0("Apply directly");
_xbt_log_cat_apply_set(cat,set);
_free_setting((void*)&set);