LogService
libdadi: utility tools for distributed applications
|
00001 /****************************************************************************/ 00002 /* Log debug utils header */ 00003 /* */ 00004 /* Author(s): */ 00005 /* - Philippe COMBES (Philippe.Combes@ens-lyon.fr) */ 00006 /* - Frederic LOMBARD (Frederic.Lombard@lifc.univ-fcomte.fr) */ 00007 /* */ 00008 /* This file is part of DIET . */ 00009 /* */ 00010 /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */ 00011 /* */ 00012 /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */ 00013 /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */ 00014 /* - Tech@sysfera.com (Maintainer and Technical Support) */ 00015 /* */ 00016 /* This software is a computer program whose purpose is to provide an */ 00017 /* distributed logging services. */ 00018 /* */ 00019 /* */ 00020 /* This software is governed by the CeCILL license under French law and */ 00021 /* abiding by the rules of distribution of free software. You can use, */ 00022 /* modify and/ or redistribute the software under the terms of the CeCILL */ 00023 /* license as circulated by CEA, CNRS and INRIA at the following URL */ 00024 /* "http://www.cecill.info". */ 00025 /* */ 00026 /* As a counterpart to the access to the source code and rights to copy, */ 00027 /* modify and redistribute granted by the license, users are provided */ 00028 /* only with a limited warranty and the software's author, the holder */ 00029 /* of the economic rights, and the successive licensors have only */ 00030 /* limited liability. */ 00031 /* */ 00032 /* In this respect, the user's attention is drawn to the risks */ 00033 /* associated with loading, using, modifying and/or developing or */ 00034 /* reproducing the software by the user in light of its specific status */ 00035 /* of free software, that may mean that it is complicated to */ 00036 /* manipulate, and that also therefore means that it is reserved for */ 00037 /* developers and experienced professionals having in-depth computer */ 00038 /* knowledge. Users are therefore encouraged to load and test the */ 00039 /* software's suitability as regards their requirements in conditions */ 00040 /* enabling the security of their systems and/or data to be ensured and, */ 00041 /* more generally, to use and operate it in the same conditions as */ 00042 /* regards security. */ 00043 /* */ 00044 /* The fact that you are presently reading this means that you have had */ 00045 /* knowledge of the CeCILL license and that you accept its terms. */ 00046 /* */ 00047 /****************************************************************************/ 00048 00049 #ifndef _DEBUG_HH_ 00050 #define _DEBUG_HH_ 00051 00052 #include <cmath> /* include used for the definition of HUGE_VAL*/ 00053 #include <cstdio> 00054 #include <cstdlib> 00055 #include <ctime> 00056 #include <iostream> 00057 #include <sys/time.h> 00058 #include <unistd.h> 00059 #include <omniconfig.h> 00060 #include <omnithread.h> 00061 00062 00064 extern unsigned int TRACE_LEVEL; 00066 extern omni_mutex debug_log_mutex; 00067 00071 #define NO_TRACE 0 00072 #define TRACE_ERR_AND_WARN 1 00073 #define TRACE_MAIN_STEPS 2 00074 #define TRACE_ALL_STEPS 5 00075 #define TRACE_STRUCTURES 10 00076 #define TRACE_MAX_VALUE TRACE_STRUCTURES 00077 #define TRACE_DEFAULT TRACE_MAIN_STEPS 00078 00084 #ifndef EXIT_FUNCTION 00085 #define EXIT_FUNCTION \ 00086 std::cout << "DEBUG WARNING: EXIT_FUNCTION undeclared !\n" 00087 #endif 00088 00089 00093 #ifndef MIN 00094 #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 00095 #endif /* MIN */ 00096 #ifndef MAX 00097 #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 00098 #endif /* MAX */ 00099 00104 #define BIP printf("bip - " __FILE__ " %i\n", __LINE__) 00105 00109 #define ERROR(formatted_msg, return_value) { \ 00110 if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \ 00111 debug_log_mutex.lock(); \ 00112 std::cerr << "LOG ERROR: " << formatted_msg << ".\n"; \ 00113 debug_log_mutex.unlock(); \ 00114 } \ 00115 return return_value; } 00116 00117 #define ERROR_EXIT(formatted_msg) { \ 00118 if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \ 00119 debug_log_mutex.lock(); \ 00120 std::cerr << "LOG ERROR: " << formatted_msg << ".\n"; \ 00121 debug_log_mutex.unlock(); \ 00122 } \ 00123 exit(1); } 00124 00125 #define INTERNAL_ERROR_EXIT(formatted_msg) { \ 00126 if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \ 00127 debug_log_mutex.lock(); \ 00128 std::cerr << "LOG ERROR: " << formatted_msg << ".\n"; \ 00129 debug_log_mutex.unlock(); \ 00130 } \ 00131 exit(1); } 00132 00136 #define WARNING(formatted_msg) \ 00137 if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \ 00138 debug_log_mutex.lock(); \ 00139 std::cerr << "LOG WARNING: " << formatted_msg << ".\n"; \ 00140 debug_log_mutex.unlock(); } 00141 00142 00146 #define INTERNAL_ERROR(formatted_msg, exit_value) \ 00147 if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \ 00148 debug_log_mutex.lock(); \ 00149 std::cerr << "LOG INTERNAL ERROR: " << formatted_msg << ".\n" << \ 00150 "Please send bug report to diet-usr@ens-lyon.fr\n"; \ 00151 debug_log_mutex.unlock(); } \ 00152 EXIT_FUNCTION; \ 00153 exit(exit_value) 00154 00158 #define INTERNAL_WARNING(formatted_msg) \ 00159 if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \ 00160 debug_log_mutex.lock(); \ 00161 std::cerr << "LOG INTERNAL WARNING: " << formatted_msg << ".\n" \ 00162 << "This is not a fatal bug, but please send a report " \ 00163 "to diet-dev@ens-lyon.fr\n"; \ 00164 debug_log_mutex.unlock(); } 00165 00166 00167 // DEBUG pause: insert a pause of duration <s>+<us>E-6 seconds 00168 #define PAUSE(s, us) \ 00169 { \ 00170 struct timeval tv; \ 00171 tv.tv_sec = s; \ 00172 tv.tv_usec = us; \ 00173 select(0, NULL, NULL, NULL, &tv); \ 00174 } 00175 00176 00177 // DEBUG trace: print "function(formatted_text)\n", following the iostream 00178 // format. First argument is the minimum TRACE_LEVEL for the line to be printed. 00179 #define TRACE_FUNCTION(level, formatted_text) \ 00180 if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(level)) { \ 00181 debug_log_mutex.lock(); \ 00182 std::cout << __FUNCTION__ << '(' << formatted_text << ")\n"; \ 00183 debug_log_mutex.unlock(); } 00184 00185 // DEBUG trace: print formatted_text following the iostream format (no '\n' 00186 // added). First argument is the minimum TRACE_LEVEL for the line to be printed. 00187 #define TRACE_TEXT(level, formatted_text) \ 00188 if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(level)) { \ 00189 debug_log_mutex.lock(); \ 00190 std::cout << formatted_text; \ 00191 debug_log_mutex.unlock(); } 00192 00193 // DEBUG trace: print "file:line: formatted_text", following the iostream format 00194 // (no '\n' added). First argument is the minimum TRACE_LEVEL for the line to be 00195 // printed. 00196 #define TRACE_TEXT_POS(level, formatted_text) \ 00197 if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(level)) { \ 00198 debug_log_mutex.lock(); \ 00199 std::cout << __FILE__ << ':' << __LINE__ << ": " << formatted_text; \ 00200 debug_log_mutex.unlock(); } 00201 00202 // DEBUG trace: print "time: formatted_text", following the iostream format (no 00203 // '\n' added). First argument is the minimum TRACE_LEVEL for the line to be 00204 // printed. 00205 #define TRACE_TIME(level, formatted_text) \ 00206 if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(level)) { \ 00207 struct timeval tv; \ 00208 debug_log_mutex.lock(); \ 00209 gettimeofday(&tv, NULL); \ 00210 printf("%10ld.%06ld: ", \ 00211 (unsigned long)tv.tv_sec, (unsigned long)tv.tv_usec); \ 00212 std::cout << formatted_text; \ 00213 debug_log_mutex.unlock(); \ 00214 } 00215 00216 // DEBUG trace: print variable name and value 00217 #define TRACE_VAR(var) { \ 00218 debug_log_mutex.lock(); \ 00219 TRACE_TEXT_POS(NO_TRACE, #var << " = " << (var) << "\n"); \ 00220 debug_log_mutex.unlock(); } 00221 00222 00223 00224 #endif // _DEBUG_HH_