00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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 }
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
00174
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 }
00232
00233
00234
00235