1 mike 1.13 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.18 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
|
5 mike 1.13 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 kumpf 1.18 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
10 mike 1.13 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
|
13 kumpf 1.18 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
14 mike 1.13 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
16 kumpf 1.18 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19 mike 1.13 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Mike Brasher (mbrasher@bmc.com)
25 //
|
26 kumpf 1.16 // Modified By: Sushma Fernandes (Hewlett-Packard Company)
27 // sushma_fernandes@hp.com
|
28 david 1.25 // Modified By: Dave Rosckes (IBM)
29 // rosckes@us.ibm.com
|
30 mike 1.13 //
31 //%/////////////////////////////////////////////////////////////////////////////
32
33 #include <iostream>
34 #include <fstream>
|
35 kumpf 1.23 #include <cstring>
|
36 mike 1.13 #include "Logger.h"
37 #include "System.h"
|
38 kumpf 1.16 #include "Destroyer.h"
|
39 mday 1.28.6.2 #include <Pegasus/Common/MessageLoader.h> //l10n
|
40 kumpf 1.16
|
41 mike 1.13 PEGASUS_USING_STD;
42
43 PEGASUS_NAMESPACE_BEGIN
44
45 const Uint32 Logger::TRACE = (1 << 0);
46 const Uint32 Logger::INFORMATION = (1 << 1);
47 const Uint32 Logger::WARNING = (1 << 2);
48 const Uint32 Logger::SEVERE = (1 << 3);
49 const Uint32 Logger::FATAL = (1 << 4);
50
|
51 david 1.26 static char const* LOGLEVEL_LIST[] =
52 {
53 "TRACE",
54 "INFORMATION",
55 "WARNING",
56 "SEVERE",
57 "FATAL"
58 };
59
60
|
61 mike 1.13 LoggerRep* Logger::_rep = 0;
62 String Logger::_homeDirectory = ".";
|
63 kumpf 1.16
|
64 david 1.26 const Uint32 Logger::_NUM_LOGLEVEL = 5;
65
66 // Set separator
67 const char Logger::_SEPARATOR = '@';
68
69 Uint32 Logger::_severityMask;
|
70 kumpf 1.16
|
71 mike 1.13 Uint32 Logger::_writeControlMask = 0xF; // Set all on by default
72
|
73 david 1.26 // Set the return codes
74 const Boolean Logger::_SUCCESS = 1;
75 const Boolean Logger::_FAILURE = 0;
76
|
77 mike 1.13 /* _allocLogFileName. Allocates the name from a name set.
78 Today this is static. However, it should be completely
79 configerable and driven from the config file so that
80 Log organization and names are open.
81 ATTN: rewrite this so that names, choice to do logs and
82 mask for level of severity are all driven from configuration
83 input.
84 */
|
85 kumpf 1.22 static CString _allocLogFileName(
|
86 mike 1.13 const String& homeDirectory,
87 Logger::LogFileType logFileType)
88 {
|
89 mike 1.15 static const char* fileNames[] =
|
90 mike 1.13 {
91 "PegasusTrace.log",
92 "PegasusStandard.log",
93 "PegasusError.log",
94 "PegasusDebug.log"
95 };
96
97 int index = int(logFileType);
98
99 if (index > Logger::NUM_LOGS)
100 index = Logger::ERROR_LOG;
101
102 const char* logFileName = fileNames[index];
103
104 String result;
|
105 kumpf 1.19 result.reserveCapacity(homeDirectory.size() + 1 + strlen(logFileName));
|
106 kumpf 1.20 result.append(homeDirectory);
107 result.append('/');
108 result.append(logFileName);
|
109 kumpf 1.22 return result.getCString();
|
110 mike 1.13 }
111
112 class LoggerRep
113 {
114 public:
115
116 LoggerRep(const String& homeDirectory)
117 {
|
118 david 1.27 #if !defined(PEGASUS_USE_SYSLOGS)
|
119 mike 1.13 // Add test for home directory set.
120
121 // If home directory does not exist, create it.
|
122 kumpf 1.22 CString lgDir = homeDirectory.getCString();
|
123 mike 1.13
124 if (!System::isDirectory(lgDir))
125 System::makeDirectory(lgDir);
126
|
127 karl 1.14 // KS: I put the second test in just in case some trys to create
|
128 mike 1.13 // a completly erronous directory. At least we will get a message
|
129 mday 1.28.6.2 if (!System::isDirectory(lgDir)){
130 //l10n
131 //cerr << "Logging Disabled";
132 MessageLoaderParms parms("Common.Logger.LOGGING_DISABLED",
133 "Logging Disabled");
134
135 cerr << MessageLoader::getMessage(parms);
136 }
|
137 mike 1.13
|
138 kumpf 1.22 CString fileName = _allocLogFileName(homeDirectory, Logger::TRACE_LOG);
|
139 mike 1.13 _logs[Logger::TRACE_LOG].open(fileName, ios::app);
140
141 fileName = _allocLogFileName(homeDirectory, Logger::STANDARD_LOG);
142 _logs[Logger::STANDARD_LOG].open(fileName, ios::app);
143
144 fileName = _allocLogFileName(homeDirectory, Logger::ERROR_LOG);
145 _logs[Logger::ERROR_LOG].open(fileName, ios::app);
146
147 fileName = _allocLogFileName(homeDirectory, Logger::DEBUG_LOG);
148 _logs[Logger::DEBUG_LOG].open(fileName, ios::app);
|
149 kumpf 1.17 #endif
|
150 mike 1.13
151 }
152
153 ostream& logOf(Logger::LogFileType logFileType)
154 {
155 int index = int(logFileType);
156
157 if (index > int(Logger::ERROR_LOG))
158 index = Logger::ERROR_LOG;
159
160 return _logs[index];
161 }
162
163 private:
164
165 ofstream _logs[int(Logger::NUM_LOGS)];
166 };
167
|
168 david 1.26 void Logger::_putInternal(
|
169 mike 1.13 LogFileType logFileType,
170 const String& systemId,
|
171 david 1.26 const Uint32 logComponent, // TODO: Support logComponent mask in future release
172 Uint32 logLevel,
|
173 mike 1.13 const String& formatString,
|
174 mday 1.28.6.1 const String& messageId, // l10n
|
175 mike 1.13 const Formatter::Arg& arg0,
176 const Formatter::Arg& arg1,
177 const Formatter::Arg& arg2,
178 const Formatter::Arg& arg3,
179 const Formatter::Arg& arg4,
180 const Formatter::Arg& arg5,
181 const Formatter::Arg& arg6,
182 const Formatter::Arg& arg7,
183 const Formatter::Arg& arg8,
184 const Formatter::Arg& arg9)
185 {
|
186 david 1.26 // Test for logLevel against severity mask to determine
|
187 mike 1.13 // if we write this log.
|
188 david 1.26 if ((_severityMask & logLevel) != 0)
|
189 mike 1.13 {
190 if (!_rep)
191 _rep = new LoggerRep(_homeDirectory);
192
|
193 mday 1.28.6.1 // Get the logLevel String
194 // This converts bitmap to string based on highest order
195 // bit set
196 // ATTN: KS Fix this more efficiently.
197 static const char* svNames[] =
198 {
|
199 mike 1.13 "TRACE ",
200 "INFO ",
201 "WARNING ",
202 "SEVERE ",
203 "FATAL "
|
204 mday 1.28.6.1 };
205 // NUM_LEVELS = 5
206 int sizeSvNames = sizeof(svNames) / sizeof(svNames[0]) - 1;
207
208 // l10n start
209 // The localized message to be sent to the system log.
210 String localizedMsg;
211
212 // If the caller specified a messageId, then load the localized
213 // message in the locale of the server process.
214 if (messageId != String::EMPTY)
215 {
216 // A message ID was specified. Use the MessageLoader.
217 MessageLoaderParms msgParms(messageId, formatString);
218 msgParms.useProcessLocale = true;
219 msgParms.arg0 = arg0;
220 msgParms.arg1 = arg1;
221 msgParms.arg2 = arg2;
222 msgParms.arg3 = arg3;
223 msgParms.arg4 = arg4;
224 msgParms.arg5 = arg5;
225 mday 1.28.6.1 msgParms.arg6 = arg6;
226 msgParms.arg7 = arg7;
227 msgParms.arg8 = arg8;
228 msgParms.arg9 = arg9;
229
230 localizedMsg = MessageLoader::getMessage(msgParms);
231 }
232 else
233 { // No message ID. Use the Pegasus formatter
234 localizedMsg = Formatter::format(formatString,
235 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
236 }
237 // l10n end
238
|
239 david 1.26 #if defined(PEGASUS_USE_SYSLOGS)
240
|
241 kumpf 1.16 // Open the syslog.
242 // Ignore the systemId and open the log as cimserver
|
243 david 1.26 System::openlog(systemId);
|
244 kumpf 1.16
245 // Log the message
|
246 mday 1.28.6.2 System::syslog(logLevel,(const char*)localizedMsg.getCStringUTF8());
|
247 mday 1.28.6.1
|
248 kumpf 1.16 // Close the syslog.
|
249 david 1.26 System::closelog();
|
250 david 1.25
|
251 david 1.26 #else
|
252 david 1.25
|
253 david 1.26 // Prepend the systemId to the incoming message
254 String messageString(systemId);
255 messageString.append(": ");
|
256 mday 1.28.6.2 messageString.append(localizedMsg); // l10n
|
257 david 1.25
|
258 kumpf 1.16 const char* tmp = "";
|
259 david 1.26 if (logLevel & Logger::TRACE) tmp = "TRACE ";
260 if (logLevel & Logger::INFORMATION) tmp = "INFO ";
261 if (logLevel & Logger::WARNING) tmp = "WARNING ";
262 if (logLevel & Logger::SEVERE) tmp = "SEVERE ";
263 if (logLevel & Logger::FATAL) tmp = "FATAL ";
|
264 mday 1.28.6.1 _rep->logOf(logFileType) << System::getCurrentASCIITime()
|
265 mday 1.28.6.2 << " " << tmp << messageString.getCStringUTF8() << endl;
|
266 david 1.26
|
267 kumpf 1.16 #endif
|
268 david 1.26 }
269 }
|
270 mike 1.13
|
271 david 1.26 void Logger::put(
272 LogFileType logFileType,
273 const String& systemId,
274 Uint32 logLevel,
275 const String& formatString,
276 const Formatter::Arg& arg0,
277 const Formatter::Arg& arg1,
278 const Formatter::Arg& arg2,
279 const Formatter::Arg& arg3,
280 const Formatter::Arg& arg4,
281 const Formatter::Arg& arg5,
282 const Formatter::Arg& arg6,
283 const Formatter::Arg& arg7,
284 const Formatter::Arg& arg8,
|
285 mday 1.28.6.1 const Formatter::Arg& arg9)
286 {
287 Uint32 logComponent = 0;
288
289 Logger::_putInternal(
290 logFileType,
291 systemId,
292 logComponent,
293 logLevel,
|
294 mday 1.28.6.3 formatString,
295 //l10n
|
296 mday 1.28.6.1 String::EMPTY,
297 arg0,
298 arg1,
299 arg2,
300 arg3,
301 arg4,
302 arg5,
303 arg6,
304 arg7,
305 arg8,
306 arg9);
307 }
308
309 // l10n
310 void Logger::put_l(
311 LogFileType logFileType,
312 const String& systemId,
313 Uint32 logLevel,
314 const String& messageId, // l10n
315 const String& formatString,
316 const Formatter::Arg& arg0,
317 mday 1.28.6.1 const Formatter::Arg& arg1,
318 const Formatter::Arg& arg2,
319 const Formatter::Arg& arg3,
320 const Formatter::Arg& arg4,
321 const Formatter::Arg& arg5,
322 const Formatter::Arg& arg6,
323 const Formatter::Arg& arg7,
324 const Formatter::Arg& arg8,
325 const Formatter::Arg& arg9)
|
326 david 1.26 {
327 Uint32 logComponent = 0;
328
329 Logger::_putInternal(
330 logFileType,
331 systemId,
332 logComponent,
333 logLevel,
334 formatString,
|
335 mday 1.28.6.1 messageId,
|
336 david 1.26 arg0,
337 arg1,
338 arg2,
339 arg3,
340 arg4,
341 arg5,
342 arg6,
343 arg7,
344 arg8,
|
345 mday 1.28.6.1 arg9);
|
346 david 1.26 }
347
348 void Logger::trace(
349 LogFileType logFileType,
350 const String& systemId,
351 const Uint32 logComponent,
352 const String& formatString,
353 const Formatter::Arg& arg0,
354 const Formatter::Arg& arg1,
355 const Formatter::Arg& arg2,
356 const Formatter::Arg& arg3,
357 const Formatter::Arg& arg4,
358 const Formatter::Arg& arg5,
359 const Formatter::Arg& arg6,
360 const Formatter::Arg& arg7,
361 const Formatter::Arg& arg8,
|
362 mday 1.28.6.1 const Formatter::Arg& arg9)
363 {
364 Uint32 logLevel = Logger::TRACE;
365
366 Logger::_putInternal(
367 logFileType,
368 systemId,
369 logComponent,
370 logLevel,
371 formatString,
372 // l10n
373 String::EMPTY,
374 arg0,
375 arg1,
376 arg2,
377 arg3,
378 arg4,
379 arg5,
380 arg6,
381 arg7,
382 arg8,
383 mday 1.28.6.1 arg9);
384 }
385
386 // l10n
387 void Logger::trace_l(
388 LogFileType logFileType,
389 const String& systemId,
390 const Uint32 logComponent,
391 const String& messageId,
392 const String& formatString,
393 const Formatter::Arg& arg0,
394 const Formatter::Arg& arg1,
395 const Formatter::Arg& arg2,
396 const Formatter::Arg& arg3,
397 const Formatter::Arg& arg4,
398 const Formatter::Arg& arg5,
399 const Formatter::Arg& arg6,
400 const Formatter::Arg& arg7,
401 const Formatter::Arg& arg8,
402 const Formatter::Arg& arg9)
|
403 david 1.26 {
404 Uint32 logLevel = Logger::TRACE;
405
406 Logger::_putInternal(
407 logFileType,
408 systemId,
409 logComponent,
410 logLevel,
411 formatString,
|
412 mday 1.28.6.1 messageId,
|
413 david 1.26 arg0,
414 arg1,
415 arg2,
416 arg3,
417 arg4,
418 arg5,
419 arg6,
420 arg7,
421 arg8,
|
422 mday 1.28.6.1 arg9);
|
423 mike 1.13 }
424
425 void Logger::setHomeDirectory(const String& homeDirectory)
426 {
427 _homeDirectory = homeDirectory;
428 }
|
429 david 1.26
430 ////////////////////////////////////////////////////////////////////////////////
431 // Set logLevel.
432 ////////////////////////////////////////////////////////////////////////////////
433 void Logger::setlogLevelMask( const String logLevelList )
434 {
435 Uint32 position = 0;
436 Uint32 logLevelType;
437 String logLevelName = logLevelList;
438
439 // Check if logLevel has been specified
440 if (logLevelName != String::EMPTY)
441 {
442 // initialise _severityMask
443 _severityMask = 0;
444
445 // Set logLevelType to indicate the level of logging
446 // required by the user.
447 if (String::equalNoCase(logLevelName,"TRACE"))
448 {
449 logLevelType = Logger::TRACE;
450 david 1.26 }
451 else if (String::equalNoCase(logLevelName,"INFORMATION"))
452 {
453 logLevelType = Logger::INFORMATION;
454 }
455 else if (String::equalNoCase(logLevelName,"WARNING"))
456 {
457 logLevelType = Logger::WARNING;
458 }
459 else if (String::equalNoCase(logLevelName,"SEVERE"))
460 {
461 logLevelType = Logger::SEVERE;
462 }
463 else if (String::equalNoCase(logLevelName,"FATAL"))
464 {
465 logLevelType = Logger::FATAL;
466 }
467 // Setting _severityMask. NOTE: When adding new logLevels
468 // it is essential that they are adding in ascending order
469 // based on priority. Once a case statement is true we will
470 // continue to set all following log levels with a higher
471 david 1.26 // priority.
472 switch(logLevelType)
473 {
474 case Logger::TRACE:
475 _severityMask |= Logger::TRACE;
476 case Logger::INFORMATION:
477 _severityMask |= Logger::INFORMATION;
478 case Logger::WARNING:
479 _severityMask |= Logger::WARNING;
480 case Logger::SEVERE:
481 _severityMask |= Logger::SEVERE;
482 case Logger::FATAL:
483 _severityMask |= Logger::FATAL;
484 }
485 }
486 else
487 {
488 // Property logLevel not specified, set default value.
489 _severityMask = ~Logger::TRACE;
490 }
491 return ;
492 david 1.26 }
493
494 Boolean Logger::isValidlogLevel(
495 const String logLevel)
496 {
497 // Validate the logLevel and modify the logLevel argument
498 // to reflect the invalid logLevel
499
500 Uint32 position=0;
501 Uint32 index=0;
502 String logLevelName = String::EMPTY;
503 Boolean validlogLevel=false;
504 Boolean retCode=true;
505
506 logLevelName = logLevel;
507
508 if (logLevelName != String::EMPTY)
509 {
510 // Lookup the index for logLevel name in _logLevel_LIST
511 index = 0;
512 validlogLevel = false;
513 david 1.26
514 while (index < _NUM_LOGLEVEL)
515 {
516 if (String::equalNoCase(logLevelName, LOGLEVEL_LIST[index]))
517 {
518 // Found logLevel, break from the loop
519 validlogLevel = true;
520 break;
521 }
522 else
523 {
524 index++;
525 }
526 }
527 }
528 else
529 {
530 // logLevels is empty, it is a valid value so return true
531 return _SUCCESS;
532 }
533
534 david 1.26 return validlogLevel;
535 }
536
|
537 mike 1.13
538 PEGASUS_NAMESPACE_END
|