SyslogAppender.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2004 Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2005 Novell, Inc. All rights reserved.
00004 *
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 *
00008 *  - Redistributions of source code must retain the above copyright notice,
00009 *    this list of conditions and the following disclaimer.
00010 *
00011 *  - Redistributions in binary form must reproduce the above copyright notice,
00012 *    this list of conditions and the following disclaimer in the documentation
00013 *    and/or other materials provided with the distribution.
00014 *
00015 *  - Neither the name of Vintela, Inc., Novell, Inc., nor the names of its
00016 *    contributors may be used to endorse or promote products derived from this
00017 *    software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc., Novell, Inc., OR THE 
00023 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 *******************************************************************************/
00031 
00032 
00037 #include "blocxx/BLOCXX_config.h"
00038 #include "blocxx/SyslogAppender.hpp"
00039 #include "blocxx/Logger.hpp"
00040 #include "blocxx/LogMessage.hpp"
00041 #include "blocxx/Mutex.hpp"
00042 #include "blocxx/MutexLock.hpp"
00043 #include "blocxx/Format.hpp"
00044 #include <syslog.h>
00045 
00046 #if defined(BLOCXX_WIN32)
00047 #define snprintf _snprintf // stupid windoze...
00048 #endif
00049 
00050 namespace BLOCXX_NAMESPACE
00051 {
00052 
00053 namespace
00054 {
00055    Mutex syslogGuard;
00056 
00057 #if defined(NAME_MAX)
00058    static char log_ident[NAME_MAX];
00059 #else
00060    static char log_ident[255];
00061 #endif
00062 
00063    struct Facilities
00064    {
00065       const char * const name;
00066       const int          code;
00067    };
00068 
00069    static struct Facilities facilities[] =
00070    {
00071 #ifdef LOG_AUTHPRIV
00072       { "auth",   LOG_AUTH },
00073 #endif
00074 #ifdef LOG_AUTHPRIV
00075       { "authpriv",  LOG_AUTHPRIV   },
00076 #endif
00077 #ifdef LOG_CRON
00078       { "cron",   LOG_CRON },
00079 #endif
00080 #ifdef LOG_DAEMON
00081       { "daemon", LOG_DAEMON  },
00082 #endif
00083 #ifdef LOG_FTP
00084       { "ftp", LOG_FTP     },
00085 #endif
00086 #ifdef LOG_KERN
00087       { "kern",   LOG_KERN },
00088 #endif
00089 #ifdef LOG_LPR
00090       { "lpr", LOG_LPR     },
00091 #endif
00092 #ifdef LOG_MAIL
00093       { "mail",   LOG_MAIL },
00094 #endif
00095 #ifdef LOG_NEWS
00096       { "news",   LOG_NEWS },
00097 #endif
00098 #ifdef LOG_USER
00099       { "user",   LOG_USER },
00100 #endif
00101 #ifdef LOG_UUCP
00102       { "uucp",   LOG_UUCP },
00103 #endif
00104 #ifdef LOG_LOCAL0
00105       { "local0", LOG_LOCAL0  },
00106 #endif
00107 #ifdef LOG_LOCAL1
00108       { "local1", LOG_LOCAL1  },
00109 #endif
00110 #ifdef LOG_LOCAL2
00111       { "local2", LOG_LOCAL2  },
00112 #endif
00113 #ifdef LOG_LOCAL3
00114       { "local3", LOG_LOCAL3  },
00115 #endif
00116 #ifdef LOG_LOCAL4
00117       { "local4", LOG_LOCAL4  },
00118 #endif
00119 #ifdef LOG_LOCAL5
00120       { "local5", LOG_LOCAL5  },
00121 #endif
00122 #ifdef LOG_LOCAL6
00123       { "local6", LOG_LOCAL6  },
00124 #endif
00125 #ifdef LOG_LOCAL7
00126       { "local7", LOG_LOCAL7  },
00127 #endif
00128       { NULL,     0     }
00129    };
00130 
00131 } // anonymous namespace
00132 
00133 
00135 SyslogAppender::SyslogAppender(const StringArray& components,
00136    const StringArray& categories,
00137    const String& pattern,
00138    const String& identity,
00139    const String& facility)
00140    : LogAppender(components, categories, pattern)
00141 {
00142    if( identity.empty() || identity.isSpaces())
00143    {
00144       BLOCXX_THROW(LoggerException, "SyslogAppender: Empty syslog identity name");
00145    }
00146    if( facility.empty())
00147    {
00148       BLOCXX_THROW(LoggerException, "SyslogAppender: Empty syslog facility name");
00149    }
00150 
00151    struct Facilities *f = facilities;
00152    for( ; f->name != NULL; f++)
00153    {
00154       if( facility.equals(f->name))
00155          break;
00156    }
00157 
00158    if( f->name == NULL)
00159    {
00160       BLOCXX_THROW(LoggerException, Format("SyslogAppender: Unknown syslog facility name: %1", facility).toString().c_str());
00161    }
00162 
00163    MutexLock lock(syslogGuard);
00164    if (!calledOpenLog)
00165    {
00166       /*
00167        * Warning: openlog on linux remembers only the
00168        *          pointer to log_ident ...
00169        */
00170       ::snprintf( log_ident, sizeof(log_ident), "%s", identity.c_str());
00171       openlog( log_ident, LOG_CONS, f->code);
00172       calledOpenLog = true;
00173    }
00174 }
00175 
00177 SyslogAppender::~SyslogAppender() {}
00178 
00180 void
00181 SyslogAppender::doProcessLogMessage(const String& formattedMessage, const LogMessage& message) const
00182 {
00183    int syslogPriority;
00184    if (message.category == Logger::STR_FATAL_CATEGORY)
00185    {
00186       syslogPriority = LOG_CRIT;
00187    }
00188    else if (message.category == Logger::STR_ERROR_CATEGORY)
00189    {
00190       syslogPriority = LOG_ERR;
00191    }
00192    else if (message.category == Logger::STR_INFO_CATEGORY)
00193    {
00194       syslogPriority = LOG_INFO;
00195    }
00196    else if (message.category == Logger::STR_DEBUG_CATEGORY)
00197    {
00198       syslogPriority = LOG_DEBUG;
00199    }
00200    else
00201    {
00202       syslogPriority = LOG_INFO;
00203    }
00204 
00205    StringArray a = formattedMessage.tokenize("\n");
00206    MutexLock lock(syslogGuard);
00207    for (size_t i = 0; i < a.size(); ++i)
00208    {
00209       syslog( syslogPriority, "%s", a[i].c_str() );
00210    }
00211 }
00212 
00214 bool SyslogAppender::calledOpenLog = false;
00215 const String SyslogAppender::STR_DEFAULT_MESSAGE_PATTERN("[%t]%m");
00216 
00217 
00218 } // end namespace BLOCXX_NAMESPACE
00219 
00220 
00221 
00222 

Generated on Fri Jun 16 15:39:09 2006 for blocxx by  doxygen 1.4.6