blocxx
|
00001 /******************************************************************************* 00002 * Copyright (C) 2004-2005, Vintela, Inc. All rights reserved. 00003 * Copyright (C) 2005-2006, 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 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of Vintela, Inc., nor Novell, Inc., 00014 * nor the names of its contributors or employees may be used to 00015 * endorse or promote products derived from this software without 00016 * specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00028 * POSSIBILITY OF SUCH DAMAGE. 00029 *******************************************************************************/ 00030 00031 00036 #include "blocxx/BLOCXX_config.h" 00037 #include "blocxx/SyslogAppender.hpp" 00038 #include "blocxx/Logger.hpp" 00039 #include "blocxx/LogMessage.hpp" 00040 #include "blocxx/Mutex.hpp" 00041 #include "blocxx/MutexLock.hpp" 00042 #include "blocxx/Format.hpp" 00043 #include "blocxx/GlobalMutex.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 // anonymous 00054 { 00055 GlobalMutex syslogGuard = BLOCXX_GLOBAL_MUTEX_INIT(); 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 } // End of 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, 00145 "SyslogAppender: Empty syslog identity name" 00146 ); 00147 } 00148 if( facility.empty()) 00149 { 00150 BLOCXX_THROW(LoggerException, 00151 "SyslogAppender: Empty syslog facility name" 00152 ); 00153 } 00154 00155 struct Facilities *f = facilities; 00156 for( ; f->name != NULL; f++) 00157 { 00158 if( facility.equals(f->name)) 00159 break; 00160 } 00161 if( f->name == NULL) 00162 { 00163 BLOCXX_THROW(LoggerException, 00164 Format("SyslogAppender: Unknown syslog facility name: %1", 00165 facility).c_str() 00166 ); 00167 } 00168 00169 MutexLock lock(syslogGuard); 00170 if (!calledOpenLog) 00171 { 00172 /* 00173 * Warning: openlog on linux remembers only the 00174 * pointer to log_ident ... 00175 */ 00176 ::snprintf( log_ident, sizeof(log_ident), "%s", identity.c_str()); 00177 openlog( log_ident, LOG_CONS, f->code); 00178 calledOpenLog = true; 00179 } 00180 } 00181 00183 SyslogAppender::~SyslogAppender() {} 00184 00186 void 00187 SyslogAppender::doProcessLogMessage(const String& formattedMessage, const LogMessage& message) const 00188 { 00189 int syslogPriority; 00190 if (message.category.equalsIgnoreCase(Logger::STR_FATAL_CATEGORY)) 00191 { 00192 syslogPriority = LOG_CRIT; 00193 } 00194 else if (message.category.equalsIgnoreCase(Logger::STR_ERROR_CATEGORY)) 00195 { 00196 syslogPriority = LOG_ERR; 00197 } 00198 else if (message.category.equalsIgnoreCase(Logger::STR_WARNING_CATEGORY)) 00199 { 00200 syslogPriority = LOG_WARNING; 00201 } 00202 else if (message.category.equalsIgnoreCase(Logger::STR_INFO_CATEGORY)) 00203 { 00204 syslogPriority = LOG_INFO; 00205 } 00206 else if (message.category.equalsIgnoreCase(Logger::STR_DEBUG_CATEGORY) 00207 || message.category.equalsIgnoreCase(Logger::STR_DEBUG2_CATEGORY) 00208 || message.category.equalsIgnoreCase(Logger::STR_DEBUG3_CATEGORY)) 00209 { 00210 syslogPriority = LOG_DEBUG; 00211 } 00212 else 00213 { 00214 syslogPriority = LOG_INFO; 00215 } 00216 00217 StringArray a = formattedMessage.tokenize("\n"); 00218 MutexLock lock(syslogGuard); 00219 for (size_t i = 0; i < a.size(); ++i) 00220 { 00221 char format[] = "%s"; 00222 syslog( syslogPriority, format, a[i].c_str() ); 00223 } 00224 } 00225 00227 bool SyslogAppender::calledOpenLog = false; 00228 const GlobalString SyslogAppender::STR_DEFAULT_MESSAGE_PATTERN = BLOCXX_GLOBAL_STRING_INIT("[%t]%m"); 00229 00230 00231 } // end namespace BLOCXX_NAMESPACE 00232 00233 00234 00235