blocxx
SyslogAppender.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright (C) 2004-2005, Vintela, Inc. All rights reserved.
3 * Copyright (C) 2005-2006, Novell, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Vintela, Inc., nor Novell, Inc.,
14 * nor the names of its contributors or employees may be used to
15 * endorse or promote products derived from this software without
16 * specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *******************************************************************************/
30 
31 
36 #include "blocxx/BLOCXX_config.h"
38 #include "blocxx/Logger.hpp"
39 #include "blocxx/LogMessage.hpp"
40 #include "blocxx/Mutex.hpp"
41 #include "blocxx/MutexLock.hpp"
42 #include "blocxx/Format.hpp"
43 #include "blocxx/GlobalMutex.hpp"
44 #include <syslog.h>
45 
46 #if defined(BLOCXX_WIN32)
47 #define snprintf _snprintf // stupid windoze...
48 #endif
49 
50 namespace BLOCXX_NAMESPACE
51 {
52 
53 namespace // anonymous
54 {
55  GlobalMutex syslogGuard = BLOCXX_GLOBAL_MUTEX_INIT();
56 
57 #if defined(NAME_MAX)
58  static char log_ident[NAME_MAX];
59 #else
60  static char log_ident[255];
61 #endif
62 
63  struct Facilities
64  {
65  const char * const name;
66  const int code;
67  };
68 
69  static struct Facilities facilities[] =
70  {
71 #ifdef LOG_AUTHPRIV
72  { "auth", LOG_AUTH },
73 #endif
74 #ifdef LOG_AUTHPRIV
75  { "authpriv", LOG_AUTHPRIV },
76 #endif
77 #ifdef LOG_CRON
78  { "cron", LOG_CRON },
79 #endif
80 #ifdef LOG_DAEMON
81  { "daemon", LOG_DAEMON },
82 #endif
83 #ifdef LOG_FTP
84  { "ftp", LOG_FTP },
85 #endif
86 #ifdef LOG_KERN
87  { "kern", LOG_KERN },
88 #endif
89 #ifdef LOG_LPR
90  { "lpr", LOG_LPR },
91 #endif
92 #ifdef LOG_MAIL
93  { "mail", LOG_MAIL },
94 #endif
95 #ifdef LOG_NEWS
96  { "news", LOG_NEWS },
97 #endif
98 #ifdef LOG_USER
99  { "user", LOG_USER },
100 #endif
101 #ifdef LOG_UUCP
102  { "uucp", LOG_UUCP },
103 #endif
104 #ifdef LOG_LOCAL0
105  { "local0", LOG_LOCAL0 },
106 #endif
107 #ifdef LOG_LOCAL1
108  { "local1", LOG_LOCAL1 },
109 #endif
110 #ifdef LOG_LOCAL2
111  { "local2", LOG_LOCAL2 },
112 #endif
113 #ifdef LOG_LOCAL3
114  { "local3", LOG_LOCAL3 },
115 #endif
116 #ifdef LOG_LOCAL4
117  { "local4", LOG_LOCAL4 },
118 #endif
119 #ifdef LOG_LOCAL5
120  { "local5", LOG_LOCAL5 },
121 #endif
122 #ifdef LOG_LOCAL6
123  { "local6", LOG_LOCAL6 },
124 #endif
125 #ifdef LOG_LOCAL7
126  { "local7", LOG_LOCAL7 },
127 #endif
128  { NULL, 0 }
129  };
130 
131 } // End of anonymous namespace
132 
133 
136  const StringArray& categories,
137  const String& pattern,
138  const String& identity,
139  const String& facility)
140  : LogAppender(components, categories, pattern)
141 {
142  if( identity.empty() || identity.isSpaces())
143  {
145  "SyslogAppender: Empty syslog identity name"
146  );
147  }
148  if( facility.empty())
149  {
151  "SyslogAppender: Empty syslog facility name"
152  );
153  }
154 
155  struct Facilities *f = facilities;
156  for( ; f->name != NULL; f++)
157  {
158  if( facility.equals(f->name))
159  break;
160  }
161  if( f->name == NULL)
162  {
164  Format("SyslogAppender: Unknown syslog facility name: %1",
165  facility).c_str()
166  );
167  }
168 
169  MutexLock lock(syslogGuard);
170  if (!calledOpenLog)
171  {
172  /*
173  * Warning: openlog on linux remembers only the
174  * pointer to log_ident ...
175  */
176  ::snprintf( log_ident, sizeof(log_ident), "%s", identity.c_str());
177  openlog( log_ident, LOG_CONS, f->code);
178  calledOpenLog = true;
179  }
180 }
181 
184 
186 void
187 SyslogAppender::doProcessLogMessage(const String& formattedMessage, const LogMessage& message) const
188 {
189  int syslogPriority;
191  {
192  syslogPriority = LOG_CRIT;
193  }
195  {
196  syslogPriority = LOG_ERR;
197  }
199  {
200  syslogPriority = LOG_WARNING;
201  }
203  {
204  syslogPriority = LOG_INFO;
205  }
209  {
210  syslogPriority = LOG_DEBUG;
211  }
212  else
213  {
214  syslogPriority = LOG_INFO;
215  }
216 
217  StringArray a = formattedMessage.tokenize("\n");
218  MutexLock lock(syslogGuard);
219  for (size_t i = 0; i < a.size(); ++i)
220  {
221  char format[] = "%s";
222  syslog( syslogPriority, format, a[i].c_str() );
223  }
224 }
225 
227 bool SyslogAppender::calledOpenLog = false;
229 
230 
231 } // end namespace BLOCXX_NAMESPACE
232 
233 
234 
235