version 1.10, 2002/04/19 20:50:33
|
version 1.71.10.1, 2013/07/30 05:38:50
|
|
|
//%///////////////////////////////////////////////////////////////////////////// |
//%LICENSE//////////////////////////////////////////////////////////////// |
// |
|
// Copyright (c) 2000, 2001 BMC Software, Hewlett-Packard Company, IBM, |
|
// The Open Group, Tivoli Systems |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|
// of this software and associated documentation files (the "Software"), to |
|
// deal in the Software without restriction, including without limitation the |
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|
// sell copies of the Software, and to permit persons to whom the Software is |
|
// furnished to do so, subject to the following conditions: |
|
// |
|
// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN |
|
// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED |
|
// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT |
|
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
// |
|
//============================================================================== |
|
// | // |
// Author: Sushma Fernandes, Hewlett-Packard Company (sushma_fernandes@hp.com) |
// Licensed to The Open Group (TOG) under one or more contributor license |
|
// agreements. Refer to the OpenPegasusNOTICE.txt file distributed with |
|
// this work for additional information regarding copyright ownership. |
|
// Each contributor licenses this file to you under the OpenPegasus Open |
|
// Source License; you may not use this file except in compliance with the |
|
// License. |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a |
|
// copy of this software and associated documentation files (the "Software"), |
|
// to deal in the Software without restriction, including without limitation |
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
// and/or sell copies of the Software, and to permit persons to whom the |
|
// Software is furnished to do so, subject to the following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included |
|
// in all copies or substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
|
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
|
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
// | // |
// Modified By: Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com) |
////////////////////////////////////////////////////////////////////////// |
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include <Pegasus/Common/Config.h> | #include <Pegasus/Common/Config.h> |
|
#include <Pegasus/Common/Constants.h> |
#include <Pegasus/Common/Tracer.h> | #include <Pegasus/Common/Tracer.h> |
#include <Pegasus/Common/Destroyer.h> |
#include <Pegasus/Common/TraceFileHandler.h> |
|
#include <Pegasus/Common/TraceLogHandler.h> |
|
#include <Pegasus/Common/TraceMemoryHandler.h> |
#include <Pegasus/Common/Thread.h> | #include <Pegasus/Common/Thread.h> |
#include <Pegasus/Common/IPC.h> |
|
#include <Pegasus/Common/System.h> | #include <Pegasus/Common/System.h> |
|
#include <Pegasus/Common/HTTPMessage.h> |
|
#include <Pegasus/Common/StringConversion.h> |
|
#include <Pegasus/Common/FileSystem.h> |
| |
PEGASUS_USING_STD; | PEGASUS_USING_STD; |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
|
/** |
|
String constants for naming the various Trace components. |
|
These strings will used when turning on tracing for the respective |
|
components. The component list must be kept in sync with the |
|
TraceComponentId enumeration. |
|
|
|
The tracer uses the _traceComponentMask in form of a 64bit field to mask |
|
the user configured components. |
|
Please ensure that no more than 64 components are specified in the |
|
TRACE_COMPONENT_LIST. |
|
|
|
The following example shows the usage of trace component names. |
|
The setTraceComponents method is used to turn on tracing for the |
|
components: Config and Repository. The component names are passed as a |
|
comma separated list. |
|
|
|
Tracer::setTraceComponents("Config,Repository"); |
|
*/ |
|
char const* Tracer::TRACE_COMPONENT_LIST[] = |
|
{ |
|
"Xml", |
|
"XmlIO", |
|
"Http", |
|
"Repository", |
|
"Dispatcher", |
|
"OsAbstraction", |
|
"Config", |
|
"IndicationHandler", |
|
"Authentication", |
|
"Authorization", |
|
"UserManager", |
|
"Shutdown", |
|
"Server", |
|
"IndicationService", |
|
"MessageQueueService", |
|
"ProviderManager", |
|
"ObjectResolution", |
|
"WQL", |
|
"CQL", |
|
"Thread", |
|
"CIMExportRequestDispatcher", |
|
"SSL", |
|
"ControlProvider", |
|
"CIMOMHandle", |
|
"L10N", |
|
"ExportClient", |
|
"Listener", |
|
"DiscardedData", |
|
"ProviderAgent", |
|
"IndicationFormatter", |
|
"StatisticalData", |
|
"CMPIProvider", |
|
"IndicationGeneration", |
|
"IndicationReceipt", |
|
"CMPIProviderInterface", |
|
"WsmServer", |
|
"RsServer", |
|
#ifdef PEGASUS_ENABLE_PROTOCOL_WEB |
|
"WebServer", |
|
#endif |
|
"LogMessages", |
|
"WMIMapperConsumer", |
|
"InternalProvider" |
|
}; |
|
|
|
// Set the number of defined components |
|
const Uint32 Tracer::_NUM_COMPONENTS = |
|
sizeof(TRACE_COMPONENT_LIST)/sizeof(TRACE_COMPONENT_LIST[0]); |
|
|
|
|
|
// Defines the value values for trace facilities |
|
// Keep the TRACE_FACILITY_LIST in sync with the TRACE_FACILITY_INDEX, |
|
// so that the index matches the according string in the list. |
|
char const* Tracer::TRACE_FACILITY_LIST[] = |
|
{ |
|
"File", |
|
"Log", |
|
"Memory", |
|
0 |
|
}; |
|
|
|
|
// Set the trace levels | // Set the trace levels |
// These levels will be compared against a trace level mask to determine | // These levels will be compared against a trace level mask to determine |
// if a specific trace level is enabled | // if a specific trace level is enabled |
| |
|
const Uint32 Tracer::LEVEL0 = 0; |
const Uint32 Tracer::LEVEL1 = (1 << 0); | const Uint32 Tracer::LEVEL1 = (1 << 0); |
const Uint32 Tracer::LEVEL2 = (1 << 1); | const Uint32 Tracer::LEVEL2 = (1 << 1); |
const Uint32 Tracer::LEVEL3 = (1 << 2); | const Uint32 Tracer::LEVEL3 = (1 << 2); |
const Uint32 Tracer::LEVEL4 = (1 << 3); | const Uint32 Tracer::LEVEL4 = (1 << 3); |
|
const Uint32 Tracer::LEVEL5 = (1 << 4); |
// Set the return codes |
|
const Boolean Tracer::_SUCCESS = 1; |
|
const Boolean Tracer::_FAILURE = 0; |
|
| |
// Set the Enter and Exit messages | // Set the Enter and Exit messages |
const char Tracer::_FUNC_ENTER_MSG[] = "Entering method"; |
const char Tracer::_METHOD_ENTER_MSG[] = "Entering method"; |
const char Tracer::_FUNC_EXIT_MSG[] = "Exiting method"; |
const char Tracer::_METHOD_EXIT_MSG[] = "Exiting method"; |
|
|
// Set Log messages |
|
const char Tracer::_LOG_MSG[] = "LEVEL1 may only be used with trace macros PEG_FUNC_ENTER/PEG_FUNC_EXIT or PEG_METHOD_ENTER/PEG_METHOD_EXIT."; |
|
| |
// Initialize singleton instance of Tracer | // Initialize singleton instance of Tracer |
Tracer* Tracer::_tracerInstance = 0; | Tracer* Tracer::_tracerInstance = 0; |
|
|
// Set component separator | // Set component separator |
const char Tracer::_COMPONENT_SEPARATOR = ','; | const char Tracer::_COMPONENT_SEPARATOR = ','; |
| |
// Set the number of defined components |
|
const Uint32 Tracer::_NUM_COMPONENTS = |
|
sizeof(TRACE_COMPONENT_LIST)/sizeof(TRACE_COMPONENT_LIST[0]); |
|
|
|
// Set the line maximum | // Set the line maximum |
const Uint32 Tracer::_STRLEN_MAX_UNSIGNED_INT = 21; | const Uint32 Tracer::_STRLEN_MAX_UNSIGNED_INT = 21; |
| |
// Set the max PID and Thread ID Length | // Set the max PID and Thread ID Length |
const Uint32 Tracer::_STRLEN_MAX_PID_TID = 20; |
const Uint32 Tracer::_STRLEN_MAX_PID_TID = 21; |
|
|
|
// Initialize public indicator of trace state |
|
Boolean Tracer::_traceOn=false; |
|
Uint32 Tracer::_traceLevelMask=0; |
|
Uint64 Tracer::_traceComponentMask=(Uint64)0; |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
// Tracer constructor | // Tracer constructor |
|
|
// Single Instance of Tracer is maintained for each process. | // Single Instance of Tracer is maintained for each process. |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
Tracer::Tracer() | Tracer::Tracer() |
|
: _traceMemoryBufferSize(PEGASUS_TRC_DEFAULT_BUFFER_SIZE_KB), |
|
_traceFacility(TRACE_FACILITY_FILE), |
|
_runningOOP(false), |
|
_traceHandler(0) |
{ | { |
// Initialize Trace File Handler |
|
_traceHandler=new TraceFileHandler(); |
|
_traceLevelMask=0; |
|
_traceComponentMask=new Boolean[_NUM_COMPONENTS]; |
|
| |
// Initialize ComponentMask array to false |
// The tracer uses a 64bit field to mask the user configured components. |
for (Uint32 index=0;index < _NUM_COMPONENTS; |
// This assert ensures that no more than 64 components are specified in the |
_traceComponentMask[index++]=false); |
// TRACE_COMPONENT_LIST. |
|
PEGASUS_ASSERT(_NUM_COMPONENTS <= 64); |
|
|
|
// Instantiate trace handler according to configured facility |
|
_setTraceHandler(_traceFacility); |
} | } |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
|
|
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
Tracer::~Tracer() | Tracer::~Tracer() |
{ | { |
delete []_traceComponentMask; |
|
delete _traceHandler; | delete _traceHandler; |
delete _tracerInstance; | delete _tracerInstance; |
} | } |
| |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
//Traces the given message |
//Factory function for the trace handler instances. |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
void Tracer::_trace( |
void Tracer::_setTraceHandler( Uint32 traceFacility ) |
const Uint32 traceComponent, |
|
const Uint32 traceLevel, |
|
const char* fmt, |
|
va_list argList) |
|
{ | { |
if ( traceLevel == LEVEL1 ) |
TraceHandler * oldTrcHandler = _traceHandler; |
|
|
|
switch(traceFacility) |
{ | { |
// ATTN: Setting the Log file type to DEBUG_LOG |
case TRACE_FACILITY_LOG: |
// May need to change to an appropriate log file type |
_traceFacility = TRACE_FACILITY_LOG; |
Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG); |
_traceHandler = new TraceLogHandler(); |
|
break; |
|
|
|
case TRACE_FACILITY_MEMORY: |
|
_traceFacility = TRACE_FACILITY_MEMORY; |
|
_traceHandler = new TraceMemoryHandler(); |
|
break; |
|
|
|
case TRACE_FACILITY_FILE: |
|
default: |
|
_traceFacility = TRACE_FACILITY_FILE; |
|
_traceHandler = new TraceFileHandler(); |
} | } |
else |
delete oldTrcHandler; |
|
} |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
// Validates if a given file path if it is eligible for writing traces. |
|
//////////////////////////////////////////////////////////////////////////////// |
|
Boolean Tracer::_isValidTraceFile(String fileName) |
{ | { |
if (_isTraceEnabled(traceComponent,traceLevel)) |
// Check if the file path is a directory |
|
FileSystem::translateSlashes(fileName); |
|
if (FileSystem::isDirectory(fileName)) |
{ | { |
_trace(traceComponent,"",fmt,argList); |
return false; |
} | } |
|
|
|
// Check if the file exists and is writable |
|
if (FileSystem::exists(fileName)) |
|
{ |
|
return FileSystem::canWrite(fileName); |
} | } |
|
|
|
// Check if directory is writable |
|
Uint32 index = fileName.reverseFind('/'); |
|
|
|
if (index != PEG_NOT_FOUND) |
|
{ |
|
String dirName = fileName.subString(0,index); |
|
|
|
if (dirName.size() == 0) |
|
{ |
|
dirName = "/"; |
|
} |
|
|
|
if (!FileSystem::isDirectory(dirName)) |
|
{ |
|
return false; |
|
} |
|
|
|
return FileSystem::canWrite(dirName); |
|
} |
|
|
|
String currentDir; |
|
|
|
// Check if there is permission to write in the |
|
// current working directory |
|
FileSystem::getCurrentDirectory(currentDir); |
|
|
|
return FileSystem::canWrite(currentDir); |
} | } |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
|
|
void Tracer::_trace( | void Tracer::_trace( |
const char* fileName, | const char* fileName, |
const Uint32 lineNum, | const Uint32 lineNum, |
const Uint32 traceComponent, |
const TraceComponentId traceComponent, |
const Uint32 traceLevel, |
|
const char* fmt, | const char* fmt, |
va_list argList) | va_list argList) |
{ | { |
char* message; | char* message; |
|
|
if ( traceLevel == LEVEL1 ) |
|
{ |
|
Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG); |
|
} |
|
else |
|
{ |
|
if (_isTraceEnabled(traceComponent,traceLevel)) |
|
{ |
|
// | // |
// Allocate memory for the message string | // Allocate memory for the message string |
// Needs to be updated if additional info is added | // Needs to be updated if additional info is added |
// | // |
message = new char[ strlen(fileName) + | message = new char[ strlen(fileName) + |
_STRLEN_MAX_UNSIGNED_INT + _STRLEN_MAX_PID_TID ]; |
_STRLEN_MAX_UNSIGNED_INT + (_STRLEN_MAX_PID_TID * 2) + 8]; |
sprintf( | sprintf( |
message, | message, |
"[%d:%u:%s:%u]: ", |
"[%u:%s:%s:%u]: ", |
System::getPID(), | System::getPID(), |
Uint32(pegasus_thread_self()), |
Threads::id().buffer, |
fileName, | fileName, |
lineNum); | lineNum); |
| |
_trace(traceComponent,message,fmt,argList); | _trace(traceComponent,message,fmt,argList); |
delete []message; | delete []message; |
} | } |
} |
|
} |
|
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
//Traces the given buffer |
//Traces the message in the given CIMException object. |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
void Tracer::_traceBuffer( |
void Tracer::_traceCIMException( |
const Uint32 traceComponent, |
const TraceComponentId traceComponent, |
const Uint32 traceLevel, |
const CIMException& cimException) |
const char* data, |
|
const Uint32 size) |
|
{ |
|
if ( traceLevel == LEVEL1 ) |
|
{ | { |
Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG); |
// get the CIMException trace message string |
|
CString traceMsg = |
|
TraceableCIMException(cimException).getTraceDescription().getCString(); |
|
// trace the string |
|
_traceCString(traceComponent, "", (const char*) traceMsg); |
} | } |
else |
|
{ |
char* Tracer::_formatHexDump( |
if (_isTraceEnabled(traceComponent,traceLevel)) |
char* targetBuffer, |
|
const char * data, |
|
Uint32 size) |
{ | { |
char* tmpBuf = new char[size+1]; |
unsigned char* p = (unsigned char*)data; |
|
unsigned char buf[16]; |
|
size_t n = 0; |
|
int len; |
| |
strncpy( tmpBuf, data, size ); |
for (size_t i = 0, col = 0; i < size; i++) |
tmpBuf[size] = '\0'; |
{ |
trace(traceComponent,traceLevel,"%s",tmpBuf); |
unsigned char c = p[i]; |
|
buf[n++] = c; |
| |
delete []tmpBuf; |
if (col == 0) |
|
{ |
|
len = sprintf(targetBuffer, "%06X ", (unsigned int)i); |
|
targetBuffer+=len; |
} | } |
|
|
|
len = sprintf(targetBuffer, "%02X", c); |
|
targetBuffer+=len; |
|
|
|
if ( ((col+1) & 3) == 0 ) |
|
{ |
|
*targetBuffer = ' '; |
|
targetBuffer++; |
} | } |
|
if (col + 1 == sizeof(buf) || i + 1 == size) |
|
{ |
|
for (size_t j = col + 1; j < sizeof(buf); j++) |
|
{ |
|
targetBuffer[0]=' '; |
|
targetBuffer[1]=' '; |
|
targetBuffer[2]=' '; |
|
targetBuffer += 3; |
} | } |
//////////////////////////////////////////////////////////////////////////////// |
for (size_t j = 0; j < n; j++) |
//Traces the given buffer - Overloaded for including FileName and Line number |
|
//////////////////////////////////////////////////////////////////////////////// |
|
void Tracer::_traceBuffer( |
|
const char* fileName, |
|
const Uint32 lineNum, |
|
const Uint32 traceComponent, |
|
const Uint32 traceLevel, |
|
const char* data, |
|
const Uint32 size) |
|
{ | { |
if ( traceLevel == LEVEL1 ) |
c = buf[j]; |
|
|
|
if (c >= ' ' && c <= '~') |
{ | { |
Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG); |
*targetBuffer = c; |
} | } |
else | else |
{ | { |
if ( _isTraceEnabled( traceComponent, traceLevel ) ) |
*targetBuffer = '.'; |
{ |
|
char* tmpBuf = new char[size+1]; |
|
|
|
strncpy( tmpBuf, data, size ); |
|
tmpBuf[size] = '\0'; |
|
trace(fileName,lineNum,traceComponent,traceLevel,"%s",tmpBuf); |
|
|
|
delete []tmpBuf; |
|
} | } |
|
targetBuffer++; |
} | } |
|
*targetBuffer = '\n'; |
|
targetBuffer++; |
|
n = 0; |
} | } |
|
if (col + 1 == sizeof(buf)) |
//////////////////////////////////////////////////////////////////////////////// |
|
//Traces the given string |
|
//////////////////////////////////////////////////////////////////////////////// |
|
void Tracer::_traceString( |
|
const Uint32 traceComponent, |
|
const Uint32 traceLevel, |
|
const String& traceString) |
|
{ | { |
if ( traceLevel == LEVEL1 ) |
col = 0; |
{ |
|
Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG); |
|
} | } |
else | else |
{ | { |
if (_isTraceEnabled(traceComponent,traceLevel)) |
col++; |
{ |
|
ArrayDestroyer<char> traceMsg(traceString.allocateCString()); |
|
trace(traceComponent,traceLevel,"%s",traceMsg.getPointer()); |
|
} | } |
} | } |
|
*targetBuffer = '\n'; |
|
targetBuffer++; |
|
return targetBuffer; |
} | } |
| |
//////////////////////////////////////////////////////////////////////////////// |
SharedArrayPtr<char> Tracer::traceFormatChars( |
//Traces the given string - Overloaded to include the fileName and line number |
const Buffer& data, |
//of trace origin. |
bool binary) |
//////////////////////////////////////////////////////////////////////////////// |
|
void Tracer::_traceString( |
|
const char* fileName, |
|
const Uint32 lineNum, |
|
const Uint32 traceComponent, |
|
const Uint32 traceLevel, |
|
const String& traceString) |
|
{ | { |
if ( traceLevel == LEVEL1 ) |
static char start[]="\n### Begin of binary data\n"; |
|
static char end[]="\n### End of binary data\n"; |
|
static char msg[] ="\n### Parts of data omitted. Only first 768 bytes and "\ |
|
"last 256 bytes shown. For complete information, use traceLevel 5.\n\n"; |
|
|
|
SharedArrayPtr<char> outputBuffer( |
|
new char[(10*data.size()+sizeof(start)+sizeof(end)+sizeof(msg))]); |
|
|
|
char* target = outputBuffer.get(); |
|
size_t size = data.size(); |
|
|
|
if (0 == size) |
{ | { |
Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG); |
target[0] = 0; |
|
return outputBuffer; |
} | } |
else |
if (binary) |
{ | { |
if ( _isTraceEnabled( traceComponent, traceLevel ) ) |
memcpy(target,&(start[0]),sizeof(start)-1); |
|
target+=sizeof(start)-1; |
|
// If there are more then 1024 bytes of binary data and the trace level |
|
// is not at highest level(5), we only trace part of the data and not |
|
// everything |
|
if ((_traceLevelMask & Tracer::LEVEL5) || (size <= 1024)) |
{ | { |
ArrayDestroyer<char> traceMsg(traceString.allocateCString()); |
target=_formatHexDump(target, data.getData(), size); |
trace(fileName,lineNum,traceComponent,traceLevel,"%s",traceMsg.getPointer()); |
|
} |
|
} |
|
} |
|
| |
//////////////////////////////////////////////////////////////////////////////// |
|
//Traces the message in the given CIMException object. |
|
//////////////////////////////////////////////////////////////////////////////// |
|
void Tracer::_traceCIMException( |
|
const Uint32 traceComponent, |
|
const Uint32 traceLevel, |
|
CIMException cimException) |
|
{ |
|
if ( traceLevel == LEVEL1 ) |
|
{ |
|
Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG); |
|
} | } |
else | else |
{ | { |
if ( _isTraceEnabled( traceComponent, traceLevel ) ) |
target=_formatHexDump(target, data.getData(), 768); |
{ |
|
// get the CIMException trace message string |
|
String traceMsg = cimException.getTraceMessage(); |
|
| |
// trace the string |
memcpy(target, &(msg[0]), sizeof(msg)-1); |
_traceString(traceComponent, traceLevel, traceMsg); |
target+=sizeof(msg)-1; |
|
|
|
target=_formatHexDump(target, &(data.getData()[size-256]), 256); |
} | } |
|
memcpy(target,&(end[0]),sizeof(end)); |
|
} |
|
else |
|
{ |
|
memcpy(target, data.getData(), size); |
|
target[size] = 0; |
} | } |
|
return outputBuffer; |
} | } |
| |
//////////////////////////////////////////////////////////////////////////////// |
SharedArrayPtr<char> Tracer::getHTTPRequestMessage( |
//Traces method entry |
const Buffer& requestMessage) |
//////////////////////////////////////////////////////////////////////////////// |
|
void Tracer::_traceEnter( |
|
const char* fileName, |
|
const Uint32 lineNum, |
|
const Uint32 traceComponent, |
|
const char* fmt, |
|
...) |
|
{ | { |
va_list argList; |
const Uint32 requestSize = requestMessage.size(); |
char* message; |
|
| |
if (_isTraceEnabled(traceComponent,LEVEL1)) |
// Check if requestMessage contains "application/x-openpegasus" |
|
// and if true format the the requestBuf as HexDump for tracing |
|
// |
|
// Binary is only possible on localConnect and doesn't have Basic |
|
// authorization for that reason |
|
if (strstr(requestMessage.getData(),"application/x-openpegasus")) |
{ | { |
|
return traceFormatChars(requestMessage,true); |
|
} |
| |
va_start(argList,fmt); |
// Make a copy of the request message. |
|
SharedArrayPtr<char> |
|
requestBuf(new char [requestSize + 1]); |
|
strncpy(requestBuf.get(), requestMessage.getData(), requestSize); |
|
requestBuf.get()[requestSize] = 0; |
| |
// | // |
// Allocate memory for the message string |
// Check if requestBuffer contains a Basic authorization header. |
// Needs to be updated if additional info is added |
// If true, suppress the user/passwd info in the request buffer. |
// | // |
message = new char[ strlen(fileName) + |
char* sep; |
_STRLEN_MAX_UNSIGNED_INT + _STRLEN_MAX_PID_TID ]; |
const char* line = requestBuf.get(); |
sprintf( |
|
message, |
|
"[%d:%u:%s:%u]: ", |
|
System::getPID(), |
|
Uint32(pegasus_thread_self()), |
|
fileName, |
|
lineNum); |
|
_trace(traceComponent,message,fmt,argList); |
|
| |
va_end(argList); |
while ((sep = HTTPMessage::findSeparator(line)) && (line != sep)) |
delete []message; |
{ |
|
if (HTTPMessage::expectHeaderToken(line, "Authorization") && |
|
HTTPMessage::expectHeaderToken(line, ":") && |
|
HTTPMessage::expectHeaderToken(line, "Basic")) |
|
{ |
|
// Suppress the user/passwd info |
|
HTTPMessage::skipHeaderWhitespace(line); |
|
for ( char* userpass = (char*)line ; |
|
userpass < sep; |
|
*userpass = 'X', userpass++) |
|
{ |
|
} |
|
break; |
|
} |
|
|
|
line = sep + ((*sep == '\r') ? 2 : 1); |
} | } |
|
return requestBuf; |
} | } |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
//Traces method exit |
//Traces method entry and exit |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
void Tracer::_traceExit( |
void Tracer::_traceMethod( |
const char* fileName, | const char* fileName, |
const Uint32 lineNum, | const Uint32 lineNum, |
const Uint32 traceComponent, |
const TraceComponentId traceComponent, |
const char* fmt |
const char* methodEntryExit, |
...) |
const char* method) |
{ | { |
va_list argList; |
|
char* message; | char* message; |
| |
if (_isTraceEnabled(traceComponent,LEVEL1)) |
|
{ |
|
va_start(argList,fmt); |
|
|
|
// | // |
// Allocate memory for the message string | // Allocate memory for the message string |
// Needs to be updated if additional info is added | // Needs to be updated if additional info is added |
// | // |
|
// assume Method entry/exit string 15 characters long |
|
// +1 space character |
message = new char[ strlen(fileName) + | message = new char[ strlen(fileName) + |
_STRLEN_MAX_UNSIGNED_INT + _STRLEN_MAX_PID_TID ]; |
_STRLEN_MAX_UNSIGNED_INT + (_STRLEN_MAX_PID_TID * 2) + 8 |
|
+ 16]; |
|
|
sprintf( | sprintf( |
message, | message, |
"[%d:%u:%s:%u]: ", |
"[%u:%s:%s:%u]: %s ", |
System::getPID(), | System::getPID(), |
Uint32(pegasus_thread_self()), |
Threads::id().buffer, |
fileName, | fileName, |
lineNum); |
lineNum, |
_trace(traceComponent,message,fmt,argList); |
methodEntryExit); |
va_end(argList); |
|
| |
delete []message; |
_traceCString(traceComponent, message, method); |
} |
|
} |
|
| |
//////////////////////////////////////////////////////////////////////////////// |
delete [] message; |
//Checks if trace is enabled for the given component and level |
|
//////////////////////////////////////////////////////////////////////////////// |
|
Boolean Tracer::_isTraceEnabled(const Uint32 traceComponent, |
|
const Uint32 traceLevel) |
|
{ |
|
Tracer* instance = _getInstance(); |
|
if (traceComponent >= _NUM_COMPONENTS) |
|
{ |
|
return false; |
|
} |
|
return ((instance->_traceComponentMask[traceComponent]) && |
|
(traceLevel & instance->_traceLevelMask)); |
|
} | } |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
//Called by all trace interfaces to log message to trace file |
//Called by all trace interfaces with variable arguments |
|
//to log message to trace file |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
void Tracer::_trace( | void Tracer::_trace( |
const Uint32 traceComponent, |
const TraceComponentId traceComponent, |
const char* message, | const char* message, |
const char* fmt, | const char* fmt, |
va_list argList) | va_list argList) |
{ | { |
char* msgHeader; | char* msgHeader; |
|
Uint32 msgLen; |
|
Uint32 usec,sec; |
| |
// Get the current system time and prepend to message | // Get the current system time and prepend to message |
String currentTime = System::getCurrentASCIITime(); |
System::getCurrentTimeUsec(sec,usec); |
ArrayDestroyer<char> timeStamp(currentTime.allocateCString()); |
|
| |
// | // |
// Allocate messageHeader. | // Allocate messageHeader. |
// Needs to be updated if additional info is added | // Needs to be updated if additional info is added |
// | // |
msgHeader = new char [strlen(message) |
|
+ strlen(TRACE_COMPONENT_LIST[traceComponent]) |
|
+ strlen(timeStamp.getPointer()) + _STRLEN_MAX_PID_TID]; |
|
| |
// Construct the message header | // Construct the message header |
// The message header is in the following format | // The message header is in the following format |
// timestamp: <component name> [file name:line number] | // timestamp: <component name> [file name:line number] |
if (strcmp(message,"") != 0) |
// |
|
// Format string length calculation: |
|
// 11(sec)+ 2('s-')+11(usec)+4('us: ')+1(' ')+1(\0) = 30 |
|
if (*message != '\0') |
{ | { |
sprintf(msgHeader,"%s: %s %s",timeStamp.getPointer(), |
msgHeader = new char [strlen(message) + |
|
strlen(TRACE_COMPONENT_LIST[traceComponent]) + 30]; |
|
|
|
msgLen = sprintf(msgHeader, "%us-%uus: %s %s", sec, usec, |
TRACE_COMPONENT_LIST[traceComponent] ,message); | TRACE_COMPONENT_LIST[traceComponent] ,message); |
} | } |
else | else |
{ | { |
// | // |
// Since the message is blank form a string using the pid and tid |
// Allocate messageHeader. |
|
// Needs to be updated if additional info is added |
|
// |
|
// Format string length calculation: |
|
// 11(sec)+2('s-')+11(usec)+4('us: ')+ |
|
// +2(' [')+1(':')+3(']: ')+1(\0) = 35 |
|
msgHeader = new char[2 * _STRLEN_MAX_PID_TID + |
|
strlen(TRACE_COMPONENT_LIST[traceComponent]) + 35]; |
|
|
|
msgLen = sprintf(msgHeader, "%us-%uus: %s [%u:%s]: ", sec, usec, |
|
TRACE_COMPONENT_LIST[traceComponent], |
|
System::getPID(), Threads::id().buffer); |
|
} |
|
|
|
// Call trace file handler to write message |
|
_getInstance()->_traceHandler->handleMessage(msgHeader,msgLen,fmt,argList); |
|
|
|
delete [] msgHeader; |
|
} |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
//Called by all trace interfaces using a character string without format string |
|
//to log message to trace file |
|
//////////////////////////////////////////////////////////////////////////////// |
|
void Tracer::_traceCString( |
|
const TraceComponentId traceComponent, |
|
const char* message, |
|
const char* cstring) |
|
{ |
|
char* completeMessage; |
|
Uint32 msgLen; |
|
Uint32 usec,sec; |
|
|
|
// Get the current system time and prepend to message |
|
System::getCurrentTimeUsec(sec,usec); |
|
|
|
// |
|
// Allocate completeMessage. |
|
// Needs to be updated if additional info is added |
|
// |
|
|
|
// Construct the message header |
|
// The message header is in the following format |
|
// timestamp: <component name> [file name:line number] |
// | // |
char* tmpBuffer; |
// Format string length calculation: |
|
// 11(sec)+ 2('s-')+11(usec)+4('us: ')+1(' ')+1(\0) = 30 |
|
if (*message != '\0') |
|
{ |
|
completeMessage = new char [strlen(message) + |
|
strlen(TRACE_COMPONENT_LIST[traceComponent]) + |
|
strlen(cstring) + 30]; |
| |
|
msgLen = sprintf(completeMessage, "%us-%uus: %s %s%s", sec, usec, |
|
TRACE_COMPONENT_LIST[traceComponent], message, cstring); |
|
} |
|
else |
|
{ |
// | // |
// Allocate messageHeader. | // Allocate messageHeader. |
// Needs to be updated if additional info is added | // Needs to be updated if additional info is added |
// | // |
tmpBuffer = new char[_STRLEN_MAX_PID_TID]; |
// Format string length calculation: |
sprintf(tmpBuffer, "[%u:%u]: ", System::getPID(), |
// 11(sec)+2('s-')+11(usec)+4('us: ')+ |
Uint32(pegasus_thread_self())); |
// +2(' [')+1(':')+3(']: ')+1(\0) = 35 |
|
completeMessage = new char[2 * _STRLEN_MAX_PID_TID + |
sprintf(msgHeader,"%s: %s %s ",timeStamp.getPointer(), |
strlen(TRACE_COMPONENT_LIST[traceComponent]) + |
TRACE_COMPONENT_LIST[traceComponent] ,tmpBuffer ); |
strlen(cstring) +35]; |
delete []tmpBuffer; |
|
|
msgLen = sprintf(completeMessage, "%us-%uus: %s [%u:%s] %s", sec, usec, |
|
TRACE_COMPONENT_LIST[traceComponent], |
|
System::getPID(), Threads::id().buffer, |
|
cstring); |
} | } |
| |
// Call trace file handler to write message | // Call trace file handler to write message |
_getInstance()->_traceHandler->handleMessage(msgHeader,fmt,argList); |
_getInstance()->_traceHandler->handleMessage(completeMessage,msgLen); |
delete []msgHeader; |
|
|
delete [] completeMessage; |
} | } |
| |
|
|
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
//Validate the trace file | //Validate the trace file |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
Boolean Tracer::isValidFileName(const char* filePath) | Boolean Tracer::isValidFileName(const char* filePath) |
{ | { |
return (_getInstance()->_traceHandler->isValidFilePath(filePath)); |
Tracer* instance = _getInstance(); |
|
String testTraceFile(filePath); |
|
|
|
if (instance->_runningOOP) |
|
{ |
|
testTraceFile.append("."); |
|
testTraceFile.append(instance->_oopTraceFileExtension); |
|
} |
|
|
|
return _isValidTraceFile(testTraceFile); |
} | } |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
//Validate the trace components | //Validate the trace components |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
Boolean Tracer::isValidComponents(const String traceComponents) |
Boolean Tracer::isValidComponents(const String& traceComponents) |
{ | { |
String invalidComponents; | String invalidComponents; |
return isValidComponents(traceComponents, invalidComponents); | return isValidComponents(traceComponents, invalidComponents); |
} | } |
| |
Boolean Tracer::isValidComponents( | Boolean Tracer::isValidComponents( |
const String traceComponents, String& invalidComponents) |
const String& traceComponents, |
|
String& invalidComponents) |
{ | { |
// Validate the trace components and modify the traceComponents argument | // Validate the trace components and modify the traceComponents argument |
// to reflect the invalid components | // to reflect the invalid components |
| |
Uint32 position=0; | Uint32 position=0; |
Uint32 index=0; | Uint32 index=0; |
String componentName = String::EMPTY; |
String componentName; |
String componentStr = String::EMPTY; |
String componentStr; |
Boolean validComponent=false; | Boolean validComponent=false; |
Boolean retCode=true; | Boolean retCode=true; |
| |
|
|
// Check if ALL is specified | // Check if ALL is specified |
if (String::equalNoCase(componentStr,"ALL")) | if (String::equalNoCase(componentStr,"ALL")) |
{ | { |
return _SUCCESS; |
return true; |
} | } |
| |
// Append _COMPONENT_SEPARATOR to the end of the traceComponents | // Append _COMPONENT_SEPARATOR to the end of the traceComponents |
componentStr += _COMPONENT_SEPARATOR; |
componentStr.append(_COMPONENT_SEPARATOR); |
| |
while (componentStr != String::EMPTY) | while (componentStr != String::EMPTY) |
{ | { |
|
|
| |
if ( !validComponent ) | if ( !validComponent ) |
{ | { |
invalidComponents += componentName; |
invalidComponents.append(componentName); |
invalidComponents += _COMPONENT_SEPARATOR; |
invalidComponents.append(_COMPONENT_SEPARATOR); |
} | } |
} | } |
} | } |
else | else |
{ | { |
// trace components is empty, it is a valid value so return true | // trace components is empty, it is a valid value so return true |
return _SUCCESS; |
return true; |
} | } |
|
|
if ( invalidComponents != String::EMPTY ) | if ( invalidComponents != String::EMPTY ) |
{ | { |
retCode = false; | retCode = false; |
|
|
} | } |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
|
//Validate the trace facility |
|
//////////////////////////////////////////////////////////////////////////////// |
|
Boolean Tracer::isValidTraceFacility(const String& traceFacility) |
|
{ |
|
Boolean retCode = false; |
|
|
|
if (traceFacility.size() != 0) |
|
{ |
|
Uint32 index = 0; |
|
while (TRACE_FACILITY_LIST[index] != 0 ) |
|
{ |
|
if (String::equalNoCase(traceFacility,TRACE_FACILITY_LIST[index])) |
|
{ |
|
retCode = true; |
|
break; |
|
} |
|
index++; |
|
} |
|
} |
|
|
|
return retCode; |
|
} |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
// Notify the trare running out of process and provide the trace file extension |
|
// for the out of process trace file. |
|
//////////////////////////////////////////////////////////////////////////////// |
|
void Tracer::setOOPTraceFileExtension(const String& oopTraceFileExtension) |
|
{ |
|
Tracer* instance = _getInstance(); |
|
instance->_oopTraceFileExtension = oopTraceFileExtension; |
|
instance->_runningOOP=true; |
|
instance->_traceMemoryBufferSize /= PEGASUS_TRC_BUFFER_OOP_SIZE_DEVISOR; |
|
|
|
} |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
//Returns the Singleton instance of the Tracer | //Returns the Singleton instance of the Tracer |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
Tracer* Tracer::_getInstance() | Tracer* Tracer::_getInstance() |
|
|
} | } |
| |
// PEGASUS_REMOVE_TRACE defines the compile time inclusion of the Trace | // PEGASUS_REMOVE_TRACE defines the compile time inclusion of the Trace |
// interfaces. If defined the interfaces map to empty functions |
// interfaces. This section defines the trace functions IF the remove |
|
// trace flag is NOT set. If it is set, they are defined as empty functions |
|
// in the header file. |
| |
#ifndef PEGASUS_REMOVE_TRACE | #ifndef PEGASUS_REMOVE_TRACE |
| |
|
|
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
Uint32 Tracer::setTraceFile(const char* traceFile) | Uint32 Tracer::setTraceFile(const char* traceFile) |
{ | { |
return (_getInstance()->_traceHandler->setFileName (traceFile)); |
if (*traceFile == 0) |
|
{ |
|
return 1; |
|
} |
|
|
|
Tracer* instance = _getInstance(); |
|
String newTraceFile(traceFile); |
|
|
|
if (instance->_runningOOP) |
|
{ |
|
newTraceFile.append("."); |
|
newTraceFile.append(instance->_oopTraceFileExtension); |
|
} |
|
|
|
if (_isValidTraceFile(newTraceFile)) |
|
{ |
|
instance->_traceFile = newTraceFile; |
|
instance->_traceHandler->configurationUpdated(); |
|
} |
|
else |
|
{ |
|
return 1; |
|
} |
|
|
|
|
|
return 0; |
|
|
} | } |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
|
|
| |
switch (traceLevel) | switch (traceLevel) |
{ | { |
|
case LEVEL0: |
|
_traceLevelMask = 0x00; |
|
break; |
|
|
case LEVEL1: | case LEVEL1: |
_getInstance()->_traceLevelMask = 0x01; |
_traceLevelMask = 0x01; |
break; | break; |
| |
case LEVEL2: | case LEVEL2: |
_getInstance()->_traceLevelMask = 0x03; |
_traceLevelMask = 0x03; |
break; | break; |
| |
case LEVEL3: | case LEVEL3: |
_getInstance()->_traceLevelMask = 0x07; |
_traceLevelMask = 0x07; |
break; | break; |
| |
case LEVEL4: | case LEVEL4: |
_getInstance()->_traceLevelMask = 0x0F; |
_traceLevelMask = 0x0F; |
|
break; |
|
|
|
case LEVEL5: |
|
_traceLevelMask = 0x1F; |
break; | break; |
| |
default: | default: |
_getInstance()->_traceLevelMask = 0; |
_traceLevelMask = 0x00; |
retCode = 1; | retCode = 1; |
} | } |
|
|
|
// If one of the components was set for tracing and the traceLevel |
|
// is not zero, then turn on tracing. |
|
_traceOn=((_traceComponentMask!=(Uint64)0)&&(_traceLevelMask!=LEVEL0)); |
|
|
return retCode; | return retCode; |
} | } |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
// Set components to be traced. | // Set components to be traced. |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
void Tracer::setTraceComponents( const String traceComponents ) |
void Tracer::setTraceComponents(const String& traceComponents) |
{ |
|
Uint32 position = 0; |
|
Uint32 index = 0; |
|
String componentName = String::EMPTY; |
|
String componentStr = traceComponents; |
|
String invalidComponents = String::EMPTY; |
|
|
|
if (componentStr != String::EMPTY) |
|
{ | { |
// Check if ALL is specified | // Check if ALL is specified |
if (String::equalNoCase(componentStr,"ALL")) |
if (String::equalNoCase(traceComponents,"ALL")) |
{ | { |
for (index=0; index < _NUM_COMPONENTS; |
// initialize ComponentMask bit array to true |
_getInstance()->_traceComponentMask[index++] = true); |
_traceComponentMask = (Uint64)-1; |
|
|
|
// If tracing isn't turned off by a traceLevel of zero, let's |
|
// turn on the flag that activates tracing. |
|
_traceOn = (_traceLevelMask != LEVEL0); |
|
|
return ; | return ; |
} | } |
| |
// initialise ComponentMask array to False |
// initialize ComponentMask bit array to false |
for (index = 0;index < _NUM_COMPONENTS; |
_traceComponentMask = (Uint64)0; |
_getInstance()->_traceComponentMask[index++] = false); |
_traceOn = false; |
|
|
|
if (traceComponents != String::EMPTY) |
|
{ |
|
Uint32 index = 0; |
|
Uint32 position = 0; |
|
String componentName; |
|
String componentStr = traceComponents; |
|
|
| |
// Append _COMPONENT_SEPARATOR to the end of the traceComponents | // Append _COMPONENT_SEPARATOR to the end of the traceComponents |
componentStr += _COMPONENT_SEPARATOR; |
componentStr.append(_COMPONENT_SEPARATOR); |
| |
while (componentStr != String::EMPTY) | while (componentStr != String::EMPTY) |
{ | { |
|
|
if (String::equalNoCase( | if (String::equalNoCase( |
componentName,TRACE_COMPONENT_LIST[index])) | componentName,TRACE_COMPONENT_LIST[index])) |
{ | { |
_getInstance()->_traceComponentMask[index]=true; |
_traceComponentMask=_traceComponentMask|((Uint64)1<<index); |
|
|
// Found component, break from the loop | // Found component, break from the loop |
break; | break; |
} | } |
|
|
index++; | index++; |
} | } |
} | } |
|
|
// Remove the searched componentname from the traceComponents | // Remove the searched componentname from the traceComponents |
componentStr.remove(0,position+1); | componentStr.remove(0,position+1); |
} | } |
|
// If one of the components was set for tracing and the traceLevel |
|
// is not zero, then turn on tracing. |
|
_traceOn=((_traceComponentMask!=(Uint64)0)&&(_traceLevelMask!=LEVEL0)); |
|
} |
|
|
|
return ; |
|
} |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
// Set the trace facility to be used |
|
//////////////////////////////////////////////////////////////////////////////// |
|
Uint32 Tracer::setTraceFacility(const String& traceFacility) |
|
{ |
|
Uint32 retCode = 0; |
|
Tracer* instance = _getInstance(); |
|
|
|
if (traceFacility.size() != 0) |
|
{ |
|
Uint32 index = 0; |
|
while (TRACE_FACILITY_LIST[index] != 0 ) |
|
{ |
|
if (String::equalNoCase( traceFacility,TRACE_FACILITY_LIST[index])) |
|
{ |
|
if (index != instance->_traceFacility) |
|
{ |
|
instance->_setTraceHandler(index); |
|
} |
|
retCode = 1; |
|
break; |
|
} |
|
index++; |
|
} |
|
} |
|
|
|
return retCode; |
|
} |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
// Get the trace facility in use |
|
//////////////////////////////////////////////////////////////////////////////// |
|
Uint32 Tracer::getTraceFacility() |
|
{ |
|
return _getInstance()->_traceFacility; |
|
} |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
// Set the size of the memory trace buffer |
|
//////////////////////////////////////////////////////////////////////////////// |
|
Boolean Tracer::setTraceMemoryBufferSize(Uint32 bufferSize) |
|
{ |
|
Tracer* instance = _getInstance(); |
|
if (instance->_runningOOP) |
|
{ |
|
// in OOP we reduce the trace memory buffer by factor |
|
// PEGASUS_TRC_BUFFER_OOP_SIZE_DEVISOR |
|
instance->_traceMemoryBufferSize = |
|
bufferSize / PEGASUS_TRC_BUFFER_OOP_SIZE_DEVISOR; |
} | } |
else | else |
{ | { |
// initialise ComponentMask array to False |
instance->_traceMemoryBufferSize = bufferSize; |
for (Uint32 index = 0;index < _NUM_COMPONENTS; |
} |
_getInstance()->_traceComponentMask[index++] = false); |
|
|
// If we decide to dynamically change the trace buffer size, |
|
// this is where it needs to be implemented. |
|
return true; |
} | } |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
// Flushes the trace buffer to traceFilePath. This method will only |
|
// have an effect when traceFacility=Memory. |
|
//////////////////////////////////////////////////////////////////////////////// |
|
void Tracer::flushTrace() |
|
{ |
|
_getInstance()->_traceHandler->flushTrace(); |
return ; | return ; |
} | } |
| |
#endif |
|
|
void Tracer::traceEnter( |
|
TracerToken& token, |
|
const char* file, |
|
size_t line, |
|
TraceComponentId traceComponent, |
|
const char* method) |
|
{ |
|
token.component = traceComponent; |
|
token.method = method; |
|
|
|
if (isTraceEnabled(traceComponent, LEVEL5)) |
|
{ |
|
_traceMethod( |
|
file, (Uint32)line, traceComponent, |
|
_METHOD_ENTER_MSG, method); |
|
} |
|
} |
|
|
|
void Tracer::traceExit( |
|
TracerToken& token, |
|
const char* file, |
|
size_t line) |
|
{ |
|
if (isTraceEnabled(token.component, LEVEL5) && token.method) |
|
_traceMethod( |
|
file, (Uint32)line, token.component, |
|
_METHOD_EXIT_MSG, token.method); |
|
} |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
//Traces the given string - Overloaded to include the fileName and line number |
|
//of trace origin. |
|
//////////////////////////////////////////////////////////////////////////////// |
|
void Tracer::traceCString( |
|
const char* fileName, |
|
const Uint32 lineNum, |
|
const TraceComponentId traceComponent, |
|
const char* cstring) |
|
{ |
|
char* message; |
|
|
|
Uint32 msgLen; |
|
Uint32 usec,sec; |
|
|
|
// Get the current system time |
|
System::getCurrentTimeUsec(sec,usec); |
|
|
|
// |
|
// Allocate memory for the message string |
|
// Needs to be updated if additional info is added |
|
// |
|
message = new char [strlen(fileName) + |
|
_STRLEN_MAX_UNSIGNED_INT + (_STRLEN_MAX_PID_TID * 2) + 8 + |
|
strlen(TRACE_COMPONENT_LIST[traceComponent]) + |
|
strlen(cstring) + 30]; |
|
|
|
msgLen = sprintf(message, "%us-%uus: %s [%u:%s:%s:%u]: %s", |
|
sec, |
|
usec, |
|
TRACE_COMPONENT_LIST[traceComponent], |
|
System::getPID(), |
|
Threads::id().buffer, |
|
fileName, |
|
lineNum, |
|
cstring); |
|
|
|
// Call trace file handler to write message |
|
_getInstance()->_traceHandler->handleMessage(message,msgLen); |
|
|
|
delete [] message; |
|
} |
|
|
|
void Tracer::traceCIMException( |
|
const TraceComponentId traceComponent, |
|
const Uint32 traceLevel, |
|
const CIMException& cimException) |
|
{ |
|
if (isTraceEnabled(traceComponent, traceLevel)) |
|
{ |
|
_traceCIMException(traceComponent, cimException); |
|
} |
|
} |
|
|
|
#endif /* !PEGASUS_REMOVE_TRACE */ |
|
|
|
//set the trace file size only when the tracing is on a file |
|
void Tracer::setMaxTraceFileSize(const String &size) |
|
{ |
|
Tracer *inst = _getInstance(); |
|
if ( inst->getTraceFacility() == TRACE_FACILITY_FILE ) |
|
{ |
|
Uint32 traceFileSizeKBytes = 0; |
|
tracePropertyToUint32(size, traceFileSizeKBytes); |
|
|
|
//Safe to typecast here as we know that handler is of type file |
|
TraceFileHandler *hdlr = (TraceFileHandler*) (inst->_traceHandler); |
|
|
|
hdlr->setMaxTraceFileSize(traceFileSizeKBytes*1024); |
|
|
|
} |
|
} |
|
|
|
//set the trace file number for rolling only when the tracing is on a file |
|
void Tracer::setMaxTraceFileNumber(const String &maxTraceFileNumber) |
|
{ |
|
Tracer *inst = _getInstance(); |
|
|
|
if ( inst->getTraceFacility() == TRACE_FACILITY_FILE ) |
|
{ |
|
Uint32 numberOfTraceFiles = 0; |
|
tracePropertyToUint32(maxTraceFileNumber, numberOfTraceFiles); |
|
|
|
//Safe to typecast here as we know that handler is of type file |
|
TraceFileHandler *hdlr = (TraceFileHandler*) (inst->_traceHandler); |
|
|
|
hdlr->setMaxTraceFileNumber(numberOfTraceFiles); |
|
} |
|
} |
|
|
|
// |
|
// Converts the quantifiable trace proprties string into a Uint32 value. |
|
// It returns false and the bufferSize is set to 0 if the string was not valid. |
|
// |
|
Boolean Tracer::tracePropertyToUint32( |
|
const String& traceProperty, Uint32& valueInUint32 ) |
|
{ |
|
Boolean retCode = false; |
|
Uint64 uInt64BufferSize; |
|
|
|
valueInUint32 = 0; |
|
CString stringBufferSize = traceProperty.getCString(); |
|
|
|
|
|
retCode = StringConversion::decimalStringToUint64(stringBufferSize, |
|
uInt64BufferSize); |
|
|
|
if (retCode ) |
|
{ |
|
retCode = StringConversion::checkUintBounds(uInt64BufferSize, |
|
CIMTYPE_UINT32); |
|
} |
|
|
|
if (retCode ) |
|
{ |
|
valueInUint32 = (Uint32)uInt64BufferSize; |
|
} |
|
|
|
return retCode; |
|
} |
|
|
| |
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |