errlog.h

00001 /*<std-header orig-src='shore' incl-file-exclusion='ERRLOG_H'>
00002 
00003  $Id: errlog.h,v 1.2 2012/01/02 21:52:27 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 public:
00144     logstream(char *buf, size_t bufsize = 1000)
00145     : w_ostrstream(buf, bufsize),
00146       __magic1(LOGSTREAM__MAGIC),
00147       _prio(log_none), 
00148       __magic2(LOGSTREAM__MAGIC)
00149         {
00150             // tie this to a hidden stream; 
00151             assert(__magic1==LOGSTREAM__MAGIC);
00152         }
00153 
00154 protected:
00155     void  init_errlog(ErrLog* mine) { _log = mine; }
00156 /** \endcond skip
00157  */
00158 };
00159 
00160 /** \enum LoggingDestination Describes the possible log destinations,
00161  * used for the ErrLog constructor.
00162  */
00163 enum LoggingDestination {
00164     log_to_ether, /*! no logging */
00165     log_to_unix_file, /*! sent to a unix file identified by name */
00166     log_to_open_file, /*! sent to an open unix FILE* */
00167     log_to_stderr  /*! sent to stderr */
00168 }; 
00169 
00170 typedef void (*ErrLogFunc)(ErrLog *, void *);
00171 
00172 
00173 /** \brief A syslog-style output stream for logging errors, information, etc.
00174  *
00175  * This output stream is used for issuing errors, "information",
00176  * debugging tracing, etc. to the operator (e.g., stderr) or to
00177  * a file,  somewhat like syslog.
00178  * \attention This predates true multi-threading and is thus not thread-safe.
00179  * We have not yet replaced this code, with a thread-safe version.
00180  * It is still useful for debugging non-timing-dependent issues,
00181  * for issuing operator messages before multithreading really starts, e.g.,
00182  * during recovery.
00183  *
00184  * Example:
00185  * \code
00186  * ErrLog errlog(log_to_unix_file, "sm.errlog");
00187  * errlog->clog << info_prio << "Restart recovery : analysis phase " << flushl;
00188  * \endcode
00189  */
00190 class ErrLog {
00191     friend class logstream;
00192     friend logstream *is_logstream(std::basic_ostream<char, std::char_traits<char > > &);
00193     friend ostream &flush_and_setprio(ostream& o, LogPriority p);
00194 
00195     LoggingDestination _destination;
00196     LogPriority       _level;
00197     FILE*             _file;        // if local file logging is used
00198     const char *      _ident; // identity for syslog & local use
00199     char *            _buffer; // default is static buffer
00200     size_t            _bufsize; 
00201     unsigned int      _magic;
00202     pthread_mutex_t*  _errlog_mutex;
00203 
00204     enum { ERRORLOG__MAGIC = 0xa2d29754 };
00205 
00206 public:
00207 
00208     /** Create a log.
00209      * @param[in] ident  The name of the log.
00210      * @param[in] dest   Indicates destination (unix file, stderr, etc).
00211      * @param[in] filename Name of destination or "-' .
00212      * @param[in] level  Minimum priority level of messages to be sent to the file. For filtering.
00213      * @param[in] ownbuf Buffer to use. Default is NULL.
00214      * @param[in] ownbufsz Size of given buffer. Default is 0.
00215      *
00216      * Using the name "-" is the same as specifying log_to_stderr
00217      */
00218     ErrLog(
00219         const char *ident,
00220         LoggingDestination dest, // required
00221         const char *filename = 0,             
00222         LogPriority level =  default_prio,
00223         char *ownbuf = 0,
00224         int  ownbufsz = 0  // length of ownbuf, if ownbuf is given
00225     );
00226 
00227     /** Create a log.
00228      * @param[in] ident  The name of the log.
00229      * @param[in] dest   Indicates destination (unix file, stderr, etc).
00230      * @param[in] file   Already open FILE*.  Default is NULL.
00231      * @param[in] level  Minimum priority level of messages to be sent to the file. For filtering.
00232      * @param[in] ownbuf Buffer to use. Default is NULL.
00233      * @param[in] ownbufsz Size of given buffer. Default is 0.
00234      */
00235     ErrLog(
00236         const char *ident,
00237         LoggingDestination dest, // required
00238         FILE *file = 0,             
00239         LogPriority level =  default_prio,
00240         char *ownbuf = 0,
00241         int  ownbufsz = 0  // length of ownbuf, if ownbuf is given
00242     );
00243 
00244     ~ErrLog();
00245 
00246     /** Convert a char string to an enumeration value.  
00247      * @param[in] arg The string to parse.
00248      * @param[out] ok Returns true/false if parse worked/not (optional)
00249      */
00250     static LogPriority parse(const char *arg, bool *ok=0);
00251 
00252     /** A stream that can be used with operator<<.
00253      * Example:
00254      * \code
00255      * ErrLog E("XXX", log_to_unix_file, "XXX.out");
00256      * E->clog << obj << endl;
00257      * \endcode
00258      */
00259     logstream    clog;
00260 
00261     /** Format and issue a message with the given priority, that
00262      * is, don't issue it unless this priority is equal to or higher 
00263      * than the priority of this error log.
00264      */
00265     void log(enum LogPriority prio, const char *format, ...);
00266 
00267     /** Return the name of the file if known */
00268     const char * ident() { 
00269         return _ident;
00270     }
00271     LoggingDestination    destination() { return _destination; };
00272 
00273     /** Return the current logging level */
00274     LogPriority getloglevel() { return _level; }
00275 
00276     /** Return a static string describing the current logging level */
00277     const char * getloglevelname() {
00278         switch(_level) {
00279             case log_none:
00280                 return "log_none";
00281             case log_emerg:
00282                 return "log_emerg";
00283             case log_fatal:
00284                 return "log_fatal";
00285             case log_internal:
00286                 return "log_internal";
00287             case log_error:
00288                 return "log_error";
00289             case log_warning:
00290                 return "log_warning";
00291             case log_info:
00292                 return "log_info";
00293             case log_debug:
00294                 return "log_debug";
00295             case log_all:
00296                 return "log_all";
00297             default:
00298                 return "error: unknown";
00299                 // w_assert1(0);
00300         }
00301     }
00302 
00303     /** Change the current logging level */
00304     LogPriority setloglevel( LogPriority prio);
00305 
00306 private:
00307     void _init1();
00308     void _init2();
00309     void _flush();
00310     void _openlogfile( const char *filename );
00311     void _closelogfile();
00312     NORET ErrLog(const ErrLog &); // disabled
00313     
00314 
00315 } /* ErrLog */;
00316 
00317 /*<std-footer incl-file-exclusion='ERRLOG_H'>  -- do not edit anything below this line -- */
00318 
00319 #endif          /*</std-footer>*/

Generated on Mon Jan 2 15:13:57 2012 for Shore Storage Manager by  doxygen 1.4.7