log.H

Go to the documentation of this file.
00001 // //////////////////////////////////////////////////////////////////// //
00002 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00003 // University of Southern California (USC) and the iLab at USC.         //
00004 // See http://iLab.usc.edu for information about this project.          //
00005 // //////////////////////////////////////////////////////////////////// //
00006 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00007 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00008 // in Visual Environments, and Applications'' by Christof Koch and      //
00009 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00010 // pending; application number 09/912,225 filed July 23, 2001; see      //
00011 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00012 // //////////////////////////////////////////////////////////////////// //
00013 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00014 //                                                                      //
00015 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00016 // redistribute it and/or modify it under the terms of the GNU General  //
00017 // Public License as published by the Free Software Foundation; either  //
00018 // version 2 of the License, or (at your option) any later version.     //
00019 //                                                                      //
00020 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00021 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00022 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00023 // PURPOSE.  See the GNU General Public License for more details.       //
00024 //                                                                      //
00025 // You should have received a copy of the GNU General Public License    //
00026 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00027 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00028 // Boston, MA 02111-1307 USA.                                           //
00029 // //////////////////////////////////////////////////////////////////// //
00030 //
00031 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00032 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/log.H $
00033 // $Id: log.H 11019 2009-03-11 20:57:11Z itti $
00034 //
00035 
00036 #ifndef LOG_H_DEFINED
00037 #define LOG_H_DEFINED
00038 
00039 #include <exception>
00040 #include <syslog.h>
00041 #include <string.h>
00042 
00043 /*! \file Util/log.H
00044     \brief Logging facility
00045 
00046     This is a comprehensive logging facility.  Use the functions
00047     provided below to display messages to the user and/or syslog.
00048     Never use printf() or std::cout<< in your code, use the functions
00049     provided here instead.
00050 
00051     Basic function call is [ID | C][P]L<LOGLEV>("format", args, ...)
00052 
00053     - Log levels are: DEBUG, INFO, ERROR, FATAL.
00054     - Prepend 'L' to call the function for a given level.
00055     - Prepend 'P' to have strerror(errno) appended to msg.
00056     - Prepend 'ID' to have integer value MYLOGID inserted at start of
00057       msg (see examples), OR, prepend 'C' to have the ModelComponent
00058       descriptive name used instead of the file name (see below), if
00059       you are inside a ModelComponent. The 'C' version will not work
00060       in any place where a descriptiveName() function is not
00061       available. To minimize confusion, the 'C' version will put the
00062       descriptive name in square brackets, so that it may be easily
00063       distinguished from a file name.
00064     - '#define DEBUG' in 'log.C' to get line numbers with function name.
00065 
00066     Although macros, all functions are atomic, so 'if (bad)
00067     LERROR(bad);' is ok; also arguments that span several lines of
00068     source code are ok too. Using these functions in macros however is
00069     probably bogus: MACRO(LERROR("xx")). CAUTION: message size is
00070     limited to LBS chars (including final '\0'); longer messages will
00071     be cleanly truncated.
00072 
00073     All log functions act like printf, so be careful when passing
00074     strings from outside directly as the format string for these
00075     functions, as outside strings may contain '%' signs which could
00076     segfault your program!  so, use LERROR("%s", unknown_string)
00077     rather than LERROR(unknown_string).
00078 
00079     DEBUG, INFO and ERROR simply report an error. FATAL also throws an
00080     exception of class "bug" (or exits; see implementation).
00081 
00082 Log entries will look like:
00083 
00084 \verbatim
00085 
00086 >>>>>>>>>>>>>>>>>>>> LERROR("success! %d %s", 10, "bozo")
00087 Jan 11 07:21:26 jukebox dntwebcfgd: SockServ::check: success! 10 bozo
00088 ^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^  ^^^^^^^^  ^^^^^  ^^^^^^^^^^^^^^^^
00089    date/time    machine   program    class    funct     message
00090 
00091 >>>>>>>>>>>>>>>>>>>> PLERROR("Cannot open");
00092 Jan 11 07:21:26 jukebox dntwebcfg: Cool::check: Cannot open (Bad descriptor)
00093 ^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^  ^^^^  ^^^^^  ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
00094   date/time    machine   program   class funct    message    errno in clear
00095 
00096 >>>>>>>>>>>>>>>>>>>> IDLINFO("Connected");
00097 with '#define MYLOGID fd' and current value of fd being 10
00098 Jan 11 07:21:26 jukebox dntwebcfgd: Cool::check:(10) Connected
00099 ^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^  ^^^^  ^^^^^  ^^  ^^^^^^^^^
00100    date/time    machine   program   class funct  ID   message
00101 
00102 >>>>>>>>>>>>>>>>>>>> IDPLFATAL("Abort");
00103 with '#define MYLOGID fd' and current value of fd being 10
00104 Jan 11 07:21:26 jukebox dntwebcfgd: Cool::check:(10) Abort (Out of memory)
00105 ^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^  ^^^^  ^^^^^  ^^  ^^^^^  ^^^^^^^^^^^^^
00106    date/time    machine   program   class funct  ID   mes   errno in clear
00107 
00108 >>>>>>>>>>>>>>>>>>>> CLERROR("success! %d %s", 10, "bozo")
00109 Jan 11 07:21:26 jukebox dntwebcfgd: [Gabor(45)]::check: success! 10 bozo
00110 ^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^  ^^^^^^^^^^^  ^^^^^  ^^^^^^^^^^^^^^^^
00111    date/time    machine   program ModelComponent funct     message
00112 
00113 \endverbatim
00114 
00115 If the message starts with a '(', '[' or '{' char, no space is written
00116 between the colon following function name and the message
00117 
00118 A last macro is provided, SHOWMEMORY(format, ...) which will display
00119 your message via LERROR, and append the total memory usage for the
00120 current process (as per the VmSize field in /proc/<pid>/status; this
00121 is useful to check for possible memory leaks). It only works under
00122 Linux and hence we have only defined it in the GNU C section here.
00123 */
00124 
00125 
00126 /// Make LFATAL() throw a std::exception rather than abort()ing.
00127 /** This flag is on by default. */
00128 const int LFATAL_THROWS       = (1 << 0);
00129 /// Make LFATAL() print " -- ABORT" after each message.
00130 /** This flag is on by default. */
00131 const int LFATAL_PRINTS_ABORT = (1 << 1);
00132 /// Make LFATAL() print its msg to stderr/syslog AND put it in the std::exception.
00133 /** This flag is on by default. Without it, LFATAL will only print its
00134     message to stderr or syslog if it will NOT be throwing a
00135     std::exception with that same message in
00136     std::exception::what(). */
00137 const int LFATAL_XTRA_NOISY   = (1 << 2);
00138 /// Whether to send log messages to stderr or to syslog.
00139 /*! Messages are sent to stderr if the LOG_FULLTRACE flag is set in
00140     LOG_FLAGS (this is the default), or are sent to syslog if the
00141     LOG_FULLTRACE flag is not set. Executables don't need to do
00142     anything special unless they need a non-default value. */
00143 const int LOG_FULLTRACE       = (1 << 3);
00144 
00145 /// Bitwise-or'ed combination of above flags.
00146 extern int LOG_FLAGS;
00147 
00148 
00149 /*! Log verbosity (see <syslog.h> for possible values). Default value is
00150   LOG_DEBUG. Executables don't need to do anything special unless they need
00151   a non-default value. */
00152 extern int MYLOGVERB;
00153 
00154 /// Null by default, but if set to non-null this string will be prefixed to every log message.
00155 /*! This can be useful if you have multiple threads or multiple
00156     processes all writing to stdout, and you want to have some way to
00157     distinguish their log messages. */
00158 extern const char* MYLOGPREFIX;
00159 
00160 /// Type of exception that is thrown from LFATAL if (LOG_FLAGS&LFATAL_THROWS)
00161 /** The real type of the exception is a derived type that is hidden
00162     from this header file -- that's so that we can hide potentially
00163     expensive things in the real implementation, like using
00164     std::string or doing some other fancy message formatting. */
00165 class lfatal_exception : public std::exception
00166 {
00167 protected:
00168   lfatal_exception() throw();
00169   virtual ~lfatal_exception() throw();
00170 
00171 public:
00172   virtual const char* what() const throw() = 0;
00173 };
00174 
00175 // ######################################################################
00176 // If using GNU C, these vararg macros provide a thread-safe facility
00177 // ######################################################################
00178 #ifdef __GNUC__
00179 
00180 #define LDEBUG(f, x...) sendlog(LOG_DEBUG,__LINE__,__FILE__,__FUNCTION__,\
00181                         0,false,false, f , ## x)
00182 #define LINFO(f, x...)  sendlog(LOG_INFO,__LINE__,__FILE__,__FUNCTION__,\
00183                         0,false,false, f , ## x)
00184 #define LERROR(f, x...) sendlog(LOG_ERR,__LINE__,__FILE__,__FUNCTION__,\
00185                         0,false,false,f ,## x)
00186 #define LFATAL(f, x...) sendlog(LOG_CRIT,__LINE__,__FILE__,__FUNCTION__,\
00187                         0,false,false, f , ## x)
00188 
00189 #define PLDEBUG(f, x...) sendlog(LOG_DEBUG,__LINE__,__FILE__,__FUNCTION__,\
00190                          0,false,true, f , ## x)
00191 #define PLINFO(f, x...)  sendlog(LOG_INFO,__LINE__,__FILE__,__FUNCTION__,\
00192                          0,false,true, f , ## x)
00193 #define PLERROR(f, x...) sendlog(LOG_ERR,__LINE__,__FILE__,__FUNCTION__,\
00194                          0,false,true, f , ## x)
00195 #define PLFATAL(f, x...) sendlog(LOG_CRIT,__LINE__,__FILE__,__FUNCTION__,\
00196                          0,false,true, f , ## x)
00197 
00198 #define IDLDEBUG(f, x...) sendlog(LOG_DEBUG,__LINE__,__FILE__,__FUNCTION__,\
00199                           MYLOGID,true,false, f , ## x)
00200 #define IDLINFO(f, x...)  sendlog(LOG_INFO,__LINE__,__FILE__,__FUNCTION__,\
00201                           MYLOGID,true,false, f , ## x)
00202 #define IDLERROR(f, x...) sendlog(LOG_ERR,__LINE__,__FILE__,__FUNCTION__,\
00203                           MYLOGID,true,false, f , ## x)
00204 #define IDLFATAL(f, x...) sendlog(LOG_CRIT,__LINE__,__FILE__,__FUNCTION__,\
00205                           MYLOGID,true,false, f , ## x)
00206 
00207 #define IDPLDEBUG(f, x...) sendlog(LOG_DEBUG,__LINE__,__FILE__,__FUNCTION__,\
00208                            MYLOGID,true,true, f , ## x)
00209 #define IDPLINFO(f, x...)  sendlog(LOG_INFO,__LINE__,__FILE__,__FUNCTION__,\
00210                            MYLOGID,true,true, f , ## x)
00211 #define IDPLERROR(f, x...) sendlog(LOG_ERR,__LINE__,__FILE__,__FUNCTION__,\
00212                            MYLOGID,true,true, f , ## x)
00213 #define IDPLFATAL(f, x...) sendlog(LOG_CRIT,__LINE__,__FILE__,__FUNCTION__,\
00214                            MYLOGID,true,true, f , ## x)
00215 
00216 #define CLOGFILE ("[" + realm() + ":" + descriptiveName() + "]").c_str()
00217 
00218 #define CLDEBUG(f, x...) sendlog(LOG_DEBUG,__LINE__,CLOGFILE,__FUNCTION__,\
00219                         0,false,false, f , ## x)
00220 #define CLINFO(f, x...)  sendlog(LOG_INFO,__LINE__,CLOGFILE,__FUNCTION__,\
00221                         0,false,false, f , ## x)
00222 #define CLERROR(f, x...) sendlog(LOG_ERR,__LINE__,CLOGFILE,__FUNCTION__,\
00223                         0,false,false,f ,## x)
00224 #define CLFATAL(f, x...) sendlog(LOG_CRIT,__LINE__,CLOGFILE,__FUNCTION__,\
00225                         0,false,false, f , ## x)
00226 
00227 #define CPLDEBUG(f, x...) sendlog(LOG_DEBUG,__LINE__,CLOGFILE,__FUNCTION__,\
00228                          0,false,true, f , ## x)
00229 #define CPLINFO(f, x...)  sendlog(LOG_INFO,__LINE__,CLOGFILE,__FUNCTION__,\
00230                          0,false,true, f , ## x)
00231 #define CPLERROR(f, x...) sendlog(LOG_ERR,__LINE__,CLOGFILE,__FUNCTION__,\
00232                          0,false,true, f , ## x)
00233 #define CPLFATAL(f, x...) sendlog(LOG_CRIT,__LINE__,CLOGFILE,__FUNCTION__,\
00234                          0,false,true, f , ## x)
00235 
00236 #define SHOWMEMORY(f, x...) showmemory(LOG_ERR,__LINE__,__FILE__,__FUNCTION__,\
00237                         0,false,false,f ,## x)
00238 
00239 // NOTE: the __attribute__ tells gcc that it should issue printf-style
00240 // warnings when compiling calls to sendlog(), treating the 8th
00241 // argument (msg) as the format string, and the 9th and subsequent
00242 // arguments as the printf-style parameters
00243 
00244 void sendlog(const int lev, const int line, const char *file,
00245              const char *func, const int idval, const bool useid,
00246              const bool usep, const char *msg, ...)
00247   __attribute__((format(__printf__,8,9)));
00248 
00249 // NOTE: the __attribute__ tells gcc that it should issue printf-style
00250 // warnings when compiling calls to sendlog(), treating the 8th
00251 // argument (msg) as the format string, and the 9th and subsequent
00252 // arguments as the printf-style parameters
00253 
00254 void showmemory(const int lev, const int line, const char *file,
00255                 const char *func, const int idval, const bool useid,
00256                 const bool usep, const char *msg, ...)
00257   __attribute__((format(__printf__,8,9)));
00258 
00259 #else
00260 // ######################################################################
00261 // If not using GNU C, these functions provide a thread-unsafe facility
00262 // ######################################################################
00263 
00264 //! max size of function or file name
00265 #define LBS2 64
00266 
00267 // log functions
00268 #define SENDLOG      MYLOG_USEID=false, MYLOG_USEP=false, sendlog
00269 #define SENDPLOG     MYLOG_USEID=false, MYLOG_USEP=true,  sendlog
00270 #define SENDIDLOG    MYLOG_USEID=true,  MYLOG_USEP=false, sendlog
00271 #define SENDIDPLOG   MYLOG_USEID=true,  MYLOG_USEP=true,  sendlog
00272 
00273 #define LDEBUG MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00274 strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_DEBUG,SENDLOG
00275 #define LINFO MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00276 strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_INFO,SENDLOG
00277 #define LERROR MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00278 strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_ERR,SENDLOG
00279 #define LFATAL MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00280 strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_CRIT,SENDLOG
00281 
00282 #define PLDEBUG MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00283 strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_DEBUG,SENDPLOG
00284 #define PLINFO MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00285 strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_INFO,SENDPLOG
00286 #define PLERROR MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00287 strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_ERR,SENDPLOG
00288 #define PLFATAL MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00289 strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_CRIT,SENDPLOG
00290 
00291 #define IDLDEBUG MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00292 MYLOGIDVAL=MYLOGID,strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_DEBUG,\
00293 SENDIDLOG
00294 #define IDLINFO MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00295 MYLOGIDVAL=MYLOGID,strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_INFO,\
00296 SENDIDLOG
00297 #define IDLERROR MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00298 MYLOGIDVAL=MYLOGID,strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_ERR,\
00299 SENDIDLOG
00300 #define IDLFATAL MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00301 MYLOGIDVAL=MYLOGID,strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_CRIT,\
00302 SENDIDLOG
00303 
00304 #define IDPLDEBUG MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00305 MYLOGIDVAL=MYLOGID,strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_DEBUG,\
00306 SENDIDPLOG
00307 #define IDPLINFO MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00308 MYLOGIDVAL=MYLOGID,strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_INFO,\
00309 SENDIDPLOG
00310 #define IDPLERROR MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00311 MYLOGIDVAL=MYLOGID,strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_ERR,\
00312 SENDIDPLOG
00313 #define IDPLFATAL MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00314 MYLOGIDVAL=MYLOGID,strncpy(MYLOGFIL, __FILE__, LBS2-1),MYLOGLEV=LOG_CRIT,\
00315 SENDIDPLOG
00316 
00317 #define CLOGFILE ("[" + descriptiveName() + "]").c_str()
00318 
00319 #define CLDEBUG MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00320 strncpy(MYLOGFIL, CLOGFILE, LBS2-1),MYLOGLEV=LOG_DEBUG,SENDLOG
00321 #define CLINFO MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00322 strncpy(MYLOGFIL, CLOGFILE, LBS2-1),MYLOGLEV=LOG_INFO,SENDLOG
00323 #define CLERROR MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00324 strncpy(MYLOGFIL, CLOGFILE, LBS2-1),MYLOGLEV=LOG_ERR,SENDLOG
00325 #define CLFATAL MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00326 strncpy(MYLOGFIL, CLOGFILE, LBS2-1),MYLOGLEV=LOG_CRIT,SENDLOG
00327 
00328 #define CPLDEBUG MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00329 strncpy(MYLOGFIL, CLOGFILE, LBS2-1),MYLOGLEV=LOG_DEBUG,SENDPLOG
00330 #define CPLINFO MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00331 strncpy(MYLOGFIL, CLOGFILE, LBS2-1),MYLOGLEV=LOG_INFO,SENDPLOG
00332 #define CPLERROR MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00333 strncpy(MYLOGFIL, CLOGFILE, LBS2-1),MYLOGLEV=LOG_ERR,SENDPLOG
00334 #define CPLFATAL MYLOGLIN=__LINE__,strncpy(MYLOGFUN, __FUNCTION__, LBS2-1),\
00335 strncpy(MYLOGFIL, CLOGFILE, LBS2-1),MYLOGLEV=LOG_CRIT,SENDPLOG
00336 
00337 
00338 // NOTE: the __attribute__ tells gcc that it should issue printf-style
00339 // warnings when compiling calls to sendlog(), treating the 1st
00340 // argument (msg) as the format string, and the 2nd and subsequent
00341 // arguments as the printf-style parameters.
00342 void sendlog(const char *msg, ...)
00343   __attribute__((format(__printf__, 1, 2)));
00344 
00345 // defined in log.C:
00346 extern char MYLOGFUN[], MYLOGFIL[];
00347 extern int MYLOGLIN, MYLOGLEV, MYLOGIDVAL;
00348 extern bool MYLOG_USEID, MYLOG_USEP;
00349 
00350 #endif
00351 
00352 /// Helper function for REPORT_CURRENT_EXCEPTION macro.
00353 void report_current_exception(const int line, const char* file) throw();
00354 
00355 /// Use this inside of a catch(...) to report info about the caught exception
00356 /** There MUST be a current exception object in order for this to work
00357     (i.e., you must be inside of a catch block when you call
00358     REPORT_CURRENT_EXCEPTION). */
00359 #define REPORT_CURRENT_EXCEPTION \
00360   report_current_exception(__LINE__, __FILE__)
00361 
00362 #endif
00363 
00364 // ######################################################################
00365 /* So things look consistent in everyone's emacs... */
00366 /* Local Variables: */
00367 /* indent-tabs-mode: nil */
00368 /* End: */
Generated on Sun May 8 08:42:26 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3