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