errlog.h

00001 /*<std-header orig-src='shore' incl-file-exclusion='ERRLOG_H'>
00002 
00003  $Id: errlog.h,v 1.1 2010/12/09 15:29:05 nhall Exp $
00004 
00005 SHORE -- Scalable Heterogeneous Object REpository
00006 
00007 Copyright (c) 1994-99 Computer Sciences Department, University of
00008                       Wisconsin -- Madison
00009 All Rights Reserved.
00010 
00011 Permission to use, copy, modify and distribute this software and its
00012 documentation is hereby granted, provided that both the copyright
00013 notice and this permission notice appear in all copies of the
00014 software, derivative works or modified versions, and any portions
00015 thereof, and that both notices appear in supporting documentation.
00016 
00017 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00018 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00019 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00020 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00021 
00022 This software was developed with support by the Advanced Research
00023 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00024 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00025 Further funding for this work was provided by DARPA through
00026 Rome Research Laboratory Contract No. F30602-97-2-0247.
00027 
00028 */
00029 
00030 #ifndef ERRLOG_H
00031 #define ERRLOG_H
00032 
00033 #include "w_defines.h"
00034 
00035 /*  -- do not edit anything above this line --   </std-header>*/
00036 
00037 /* errlog.h -- facilities for logging errors */
00038 
00039 #include <cassert>
00040 #include <cstdlib>
00041 #include <cstddef>
00042 #include <w.h>
00043 #include <iostream>
00044 #include <cstdio>    // XXX just needs a forward decl
00045 #include <w_pthread.h> 
00046 
00047 #ifdef __GNUG__
00048 #pragma interface
00049 #endif
00050 
00051 class ErrLog; // forward
00052 class logstream; // forward
00053 
00054 #ifndef    _SYSLOG_H
00055 #define LOG_EMERG 0 
00056 #define LOG_ALERT 1
00057 #define LOG_CRIT  2
00058 #define LOG_ERR   3
00059 #define LOG_WARNING 4
00060 #define LOG_NOTICE  5
00061 #define LOG_INFO  6
00062 #define LOG_DEBUG 7
00063 #define LOG_USER  8
00064 #endif
00065 
00066 /** \brief A namespace for errlog-related types.
00067  */
00068 namespace shore_errlog {
00069 using namespace std;
00070 
00071 /*!\enum LogPriority
00072  * \brief Enumeration that enables filtering of messages by priority.
00073  *
00074  * The following __omanip functions are defined to correspond 
00075  * to the LogPriority:
00076  * emerg_prio, fatal_prio, internal_prio, 
00077  * error_prio, warning_prio, info_prio, debug_prio
00078  *
00079  * Log messages must end with the new __omanip function
00080  * flushl.
00081  */
00082 enum LogPriority {
00083     log_none = -1,    // none (for global variable logging_level only)
00084     log_emerg = LOG_EMERG,        // no point in continuing (syslog's LOG_EMERG)
00085     log_fatal = LOG_ALERT,        // no point in continuing (syslog's LOG_ALERT)
00086     log_alert = log_fatal,        // alias
00087     log_internal = LOG_CRIT,    // internal error 
00088     log_error = LOG_ERR,        // client error 
00089     log_warning = LOG_WARNING,    // client error 
00090     log_info = LOG_INFO,        // just for yucks 
00091     log_debug=LOG_DEBUG,        // for debugging gory details 
00092     log_all,
00093     default_prio = log_error
00094 };
00095 
00096 } /* namespace syslog_compat */
00097 
00098 using namespace shore_errlog;
00099 
00100 extern ostream& flushl(ostream& o);
00101 extern ostream& emerg_prio(ostream& o);
00102 extern ostream& fatal_prio(ostream& o);
00103 extern ostream& internal_prio(ostream& o);
00104 extern ostream& error_prio(ostream& o);
00105 extern ostream& warning_prio(ostream& o);
00106 extern ostream& info_prio(ostream& o);
00107 extern ostream& debug_prio(ostream& o);
00108 extern void setprio(ostream&, LogPriority);
00109 extern logstream *is_logstream(std::basic_ostream<char, std::char_traits<char > > &);
00110 /** \brief A strstream-based log output stream. 
00111  * \details
00112  * Responds to these iomanip functions :
00113  *  emerg_prio, 
00114  *  fatal_prio, 
00115  *  internal_prio, 
00116  *  error_prio, 
00117  *  warning_prio, 
00118  *  info_prio, 
00119  *  debug_prio
00120  */
00121 class logstream : public w_ostrstream {
00122     friend class ErrLog;
00123     friend ostream &flush_and_setprio(ostream& o, LogPriority p);
00124     friend ostream& emerg_prio(ostream& o);
00125     friend ostream& fatal_prio(ostream& o);
00126     friend ostream& internal_prio(ostream& o);
00127     friend ostream& error_prio(ostream& o);
00128     friend ostream& warning_prio(ostream& o);
00129     friend ostream& info_prio(ostream& o);
00130     friend ostream& debug_prio(ostream& o);
00131 
00132     unsigned int     __magic1;
00133     LogPriority     _prio;
00134     ErrLog*        _log;
00135     unsigned int     __magic2;
00136 
00137 public:
00138 /** \cond skip */
00139  friend logstream *is_logstream(std::basic_ostream<char, std::char_traits<char > > &);
00140 
00141     enum { LOGSTREAM__MAGIC = 0xad12bc45 };
00142 private:
00143     // DEAD static w_ostrstream static_stream;
00144 public:
00145     logstream(char *buf, size_t bufsize = 1000)
00146     : w_ostrstream(buf, bufsize),
00147       __magic1(LOGSTREAM__MAGIC),
00148       _prio(log_none), 
00149       __magic2(LOGSTREAM__MAGIC)
00150         {
00151             // tie this to a hidden stream; 
00152    // DEAD ios::tie(&static_stream);
00153             // DEAD assert(ios::tie() == &static_stream) ;
00154             assert(__magic1==LOGSTREAM__MAGIC);
00155         }
00156 
00157 protected:
00158     void  init_errlog(ErrLog* mine) { _log = mine; }
00159 /** \endcond skip
00160  */
00161 };
00162 
00163 /** \enum LoggingDestination Describes the possible log destinations,
00164  * used for the ErrLog constructor.
00165  */
00166 enum LoggingDestination {
00167     log_to_ether, /*! no logging */
00168     log_to_unix_file, /*! sent to a unix file identified by name */
00169     log_to_open_file, /*! sent to an open unix FILE* */
00170     log_to_stderr  /*! sent to stderr */
00171 }; 
00172 
00173 typedef void (*ErrLogFunc)(ErrLog *, void *);
00174 
00175 
00176 /** \brief A syslog-style output stream for logging errors, information, etc.
00177  *
00178  * This output stream is used for issuing errors, "information",
00179  * debugging tracing, etc. to the operator (e.g., stderr) or to
00180  * a file,  somewhat like syslog.
00181  * \attention This predates true multi-threading and is thus not thread-safe.
00182  * We have not yet replaced this code, with a thread-safe version.
00183  * It is still useful for debugging non-timing-dependent issues,
00184  * for issuing operator messages before multithreading really starts, e.g.,
00185  * during recovery.
00186  *
00187  * Example:
00188  * \code
00189  * ErrLog errlog(log_to_unix_file, "sm.errlog");
00190  * errlog->clog << info_prio << "Restart recovery : analysis phase " << flushl;
00191  * \endcode
00192  */
00193 class ErrLog {
00194     friend class logstream;
00195     friend logstream *is_logstream(std::basic_ostream<char, std::char_traits<char > > &);
00196     friend ostream &flush_and_setprio(ostream& o, LogPriority p);
00197 
00198     LoggingDestination _destination;
00199     LogPriority       _level;
00200     FILE*             _file;        // if local file logging is used
00201     const char *      _ident; // identity for syslog & local use
00202     char *            _buffer; // default is static buffer
00203     size_t            _bufsize; 
00204     unsigned int      _magic;
00205     pthread_mutex_t*  _errlog_mutex;
00206 
00207     enum { ERRORLOG__MAGIC = 0xa2d29754 };
00208 
00209 public:
00210 
00211     /** Create a log.
00212      * @param[in] ident  The name of the log.
00213      * @param[in] dest   Indicates destination (unix file, stderr, etc).
00214      * @param[in] filename Name of destination or "-' .
00215      * @param[in] level  Minimum priority level of messages to be sent to the file. For filtering.
00216      * @param[in] ownbuf Buffer to use. Default is NULL.
00217      * @param[in] ownbufsz Size of given buffer. Default is 0.
00218      *
00219      * Using the name "-" is the same as specifying log_to_stderr
00220      */
00221     ErrLog(
00222         const char *ident,
00223         LoggingDestination dest, // required
00224         const char *filename = 0,             
00225         LogPriority level =  default_prio,
00226         char *ownbuf = 0,
00227         int  ownbufsz = 0  // length of ownbuf, if ownbuf is given
00228     );
00229 
00230     /** Create a log.
00231      * @param[in] ident  The name of the log.
00232      * @param[in] dest   Indicates destination (unix file, stderr, etc).
00233      * @param[in] file   Already open FILE*.  Default is NULL.
00234      * @param[in] level  Minimum priority level of messages to be sent to the file. For filtering.
00235      * @param[in] ownbuf Buffer to use. Default is NULL.
00236      * @param[in] ownbufsz Size of given buffer. Default is 0.
00237      */
00238     ErrLog(
00239         const char *ident,
00240         LoggingDestination dest, // required
00241         FILE *file = 0,             
00242         LogPriority level =  default_prio,
00243         char *ownbuf = 0,
00244         int  ownbufsz = 0  // length of ownbuf, if ownbuf is given
00245     );
00246 
00247     ~ErrLog();
00248 
00249     /** Convert a char string to an enumeration value.  
00250      * @param[in] arg The string to parse.
00251      * @param[out] ok Returns true/false if parse worked/not (optional)
00252      */
00253     static LogPriority parse(const char *arg, bool *ok=0);
00254 
00255     /** A stream that can be used with operator<<.
00256      * Example:
00257      * \code
00258      * ErrLog E("XXX", log_to_unix_file, "XXX.out");
00259      * E->clog << obj << endl;
00260      * \endcode
00261      */
00262     logstream    clog;
00263 
00264     /** Format and issue a message with the given priority, that
00265      * is, don't issue it unless this priority is equal to or higher 
00266      * than the priority of this error log.
00267      */
00268     void log(enum LogPriority prio, const char *format, ...);
00269 
00270     /** Return the name of the file if known */
00271     const char * ident() { 
00272         return _ident;
00273     }
00274     LoggingDestination    destination() { return _destination; };
00275 
00276     /** Return the current logging level */
00277     LogPriority getloglevel() { return _level; }
00278 
00279     /** Return a static string describing the current logging level */
00280     const char * getloglevelname() {
00281         switch(_level) {
00282             case log_none:
00283                 return "log_none";
00284             case log_emerg:
00285                 return "log_emerg";
00286             case log_fatal:
00287                 return "log_fatal";
00288             case log_internal:
00289                 return "log_internal";
00290             case log_error:
00291                 return "log_error";
00292             case log_warning:
00293                 return "log_warning";
00294             case log_info:
00295                 return "log_info";
00296             case log_debug:
00297                 return "log_debug";
00298             case log_all:
00299                 return "log_all";
00300             default:
00301                 return "error: unknown";
00302                 // w_assert1(0);
00303         }
00304     }
00305 
00306     /** Change the current logging level */
00307     LogPriority setloglevel( LogPriority prio);
00308 
00309 private:
00310     void _init1();
00311     void _init2();
00312     void _flush();
00313     void _openlogfile( const char *filename );
00314     void _closelogfile();
00315     NORET ErrLog(const ErrLog &); // disabled
00316     
00317 
00318 } /* ErrLog */;
00319 
00320 /*<std-footer incl-file-exclusion='ERRLOG_H'>  -- do not edit anything below this line -- */
00321 
00322 #endif          /*</std-footer>*/

Generated on Thu Dec 9 08:42:27 2010 for Shore Storage Manager by  doxygen 1.4.7