blob: 34e0bff78faa6d2ffe17d9a98945b4135a88eb58 [file] [log] [blame]
/*
* Copyright 2003-2004 The Apache Software Foundation.
// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __AXISLOG_H_INCLUDED_
#define __AXISLOG_H_INCLUDED_
#include <string>
#include <stdio.h>
#include <stdarg.h>
#include <axis/GDefine.hpp>
using namespace std;
// Types of trace records
#define TRACE_TYPE_ENTRY ">"
#define TRACE_TYPE_EXIT "<"
#define TRACE_TYPE_AUDIT "A"
#define TRACE_TYPE_DEBUG "D"
#define TRACE_TYPE_EVENT "E"
#define TRACE_TYPE_INFO "I"
#define TRACE_TYPE_UNCOND "U"
#define TRACE_TYPE_WARN "W"
#define TRACE_TYPE_EXCEPT "X"
// Trace components
#define TRACE_COMPONENT_ENGINE "engine "
#define TRACE_COMPONENT_STUB "stub "
#define TRACE_COMPONENT_TRANSPORT "transport "
#define TRACE_COMPONENT_PARSER "parser "
// Trace filters
#define TRACE_FILTER_NOENTRYEXIT "noEntryExit"
#define TRACE_FILTER_ENGINE "engine"
#define TRACE_FILTER_STUB "stub"
#define TRACE_FILTER_TRANSPORT "transport"
#define TRACE_FILTER_PARSER "parser"
AXIS_CPP_NAMESPACE_START
/**
* Class used to enable tracing. Used by all components. To enable trace that
* is sent to a file,one needs to invoke startTrace() method. To enable trace that is
* sent to stdout, invoke enableConsoleMode(). Note that console mode and trace to
* a file can be active at the same time. To terminate trace, invoke stop().
* <P>
* Axis components are made of the engine, the parser, the transport, and the stubs (client
* and server) that are generated by the WSDL2Ws tool. The tracing facility by default will
* trace all the components when tracing is enabled (currently the stubs are not generated).
* One can filter out what is traced by setting the LogFilter configutation variable.
* For example, if one wanted to produce trace data that does not include entry/exit records
* and only includes the transport and parser components, one would invoke setLogFilter() as
* follows:
* <xmp>
* setLogFilter("transport;parser;noEntryExit")
* </xmp>
* <P>
* The above statement will produce trace records for the parser and transport component, and will
* exclude entry/exit trace records - showing only debug and exception (if any occur) records.
* <P>
* It should be noted that setting log filter to NULL string or NULL pointer is equivalent to:
* <xmp>
* setLogFilter("stub;engine;transport;parser")
* </xmp>
*
* @author Nadir Amra (amra@us.ibm.com)
*/
class AxisTrace
{
public:
// Starting and stopping trace. If log file path is not set, no logging is done
// unless ConsoleMode is enabled, in which case log records will be written to stdout.
static int startTrace(const char* logFilePath, bool dumpEnvironment=true);
static void stopTrace();
static bool isLoggingEnabled() { return (m_logFileIsSet || m_consoleMode); }
static std::string& getLogFilePath() { return m_logFilePath; }
// Setting log filters. The string filter is a semicolon delimited string
// of possible filters. For example, setLogFilter("noEntryExit;").
static void setLogFilter(const char *filters);
static std::string getLogFilter();
// Rest log filters to default values, which is: "stub;engine;transport;parser"
static void resetLogFilter();
// Whether to print log records to the console (i.e. stdout).
static void enableConsoleMode();
static void disableConsoleMode();
// Entry/exit tracing.
static void writeEntry (const char* component, const char* functionName, const char * fmt, ...);
static void writeExit (const char* component, const char* functionName, const char * fmt, ...);
// Write trace data. Trace records will include prefix (i.e. timestamp, etc).
static void writeTrace (const char* component, const char* type, const char* functionName,
const char * fmt, ...);
static void writeTrace (const char* component, const char* type, const char* functionName,
int lineNumber, const char* fileName, const char * fmt, ...);
static void writeTrace (const char* component, const char* type, const char* functionName,
bool hexFormat, int dataLen, const char *data);
static void writeTrace (const char *fmt, va_list vargs);
// Write trace data. No trace record prefix is printed out (i.e. no timestamp, etc).
static void writeTrace (std::string& s);
static void writeTrace (const char *data, int dataLen, bool hexFormat=false);
static void writeTrace (const char *str);
// To determine when a log component is enabled.
static bool isStubLoggingEnabled() { return m_stubLogLevelEnabled; }
static bool isEngineLoggingEnabled() { return m_engineLogLevelEnabled; }
static bool isParserLoggingEnabled() { return m_parserLogLevelEnabled; }
static bool isTransportLoggingEnabled() { return m_transportLogLevelEnabled; }
private:
// Internal function for writing trace data
static void generatePrefix(std::string &prefix, const char *fmt);
// Data fields.
static bool m_logFileIsSet;
static bool m_stubLogLevelEnabled;
static bool m_engineLogLevelEnabled;
static bool m_parserLogLevelEnabled;
static bool m_transportLogLevelEnabled;
static bool m_consoleMode;
static bool m_noEntryExit;
static std::string m_logFilePath;
};
AXIS_CPP_NAMESPACE_END
// ==================================================================================
// Macros to do tracing setup, used when entry/exit is not wanted
// ==================================================================================
#define logSetFunctionNameStub(lFunctionName) \
const char* logFunctionName = lFunctionName; \
const char* logComponent = TRACE_COMPONENT_STUB; \
bool loggingEnabled = (AxisTrace::isLoggingEnabled() && AxisTrace::isStubLoggingEnabled());
#define logSetFunctionNameEngine(lFunctionName) \
const char* logFunctionName = lFunctionName; \
const char* logComponent = TRACE_COMPONENT_ENGINE; \
bool loggingEnabled = (AxisTrace::isLoggingEnabled() && AxisTrace::isEngineLoggingEnabled());
#define logSetFunctionNameParser(lFunctionName) \
const char* logFunctionName = lFunctionName; \
const char* logComponent = TRACE_COMPONENT_PARSER; \
bool loggingEnabled = (AxisTrace::isLoggingEnabled() && AxisTrace::isParserLoggingEnabled());
#define logSetFunctionNameTransport(lFunctionName) \
const char* logFunctionName = lFunctionName; \
const char* logComponent = TRACE_COMPONENT_TRANSPORT; \
bool loggingEnabled = (AxisTrace::isLoggingEnabled() && AxisTrace::isTransportLoggingEnabled());
// ==================================================================================
// Macros to simply use of entry tracing
// ==================================================================================
#define logEntryStub(lFunctionName) \
logSetFunctionNameStub(lFunctionName) \
{ \
if (loggingEnabled) { \
AxisTrace::writeEntry(logComponent, logFunctionName, NULL); \
} \
}
#define logEntryEngine(lFunctionName) \
logSetFunctionNameEngine(lFunctionName) \
{ \
if (loggingEnabled) { \
AxisTrace::writeEntry(logComponent, logFunctionName, NULL); \
} \
}
#define logEntryParser(lFunctionName) \
logSetFunctionNameParser(lFunctionName) \
{ \
if (loggingEnabled) { \
AxisTrace::writeEntry(logComponent, logFunctionName, NULL); \
} \
}
#define logEntryTransport(lFunctionName) \
logSetFunctionNameTransport(lFunctionName) \
{ \
if (loggingEnabled) { \
AxisTrace::writeEntry(logComponent, logFunctionName, NULL); \
} \
}
// ==================================================================================
// Macros to simply use of exit tracing
// ==================================================================================
#define logExit() \
{ \
if (loggingEnabled) { \
AxisTrace::writeExit(logComponent, logFunctionName, NULL); \
} \
}
#define logExitWithReturnCode(lRC) \
{ \
if (loggingEnabled) { \
AxisTrace::writeExit(logComponent, logFunctionName, "Exit with return code of %s", lRC == AXIS_SUCCESS ? "AXIS_SUCCESS" : "AXIS_FAIL"); \
} \
}
#define logExitWithInteger(lint) \
{ \
if (loggingEnabled) { \
AxisTrace::writeExit(logComponent, logFunctionName, "Exit with integer value of %d", lint); \
} \
}
#define logExitWithPointer(lPointer) \
{ \
if (loggingEnabled) { \
AxisTrace::writeExit(logComponent, logFunctionName, "Exit with object pointer %p", lPointer); \
} \
}
#define logExitWithString(lString) \
{ \
if (loggingEnabled) { \
AxisTrace::writeExit(logComponent, logFunctionName, "Exit with string \"%s\"", lString); \
} \
}
#define logExitWithBoolean(lBoolean) \
{ \
if (loggingEnabled) { \
AxisTrace::writeExit(logComponent, logFunctionName, "Exit with boolean %s", lBoolean ? "true" : "false"); \
} \
}
#define logExitWithMessage(lfmt) \
{ \
if (loggingEnabled) { \
AxisTrace::writeExit(logComponent, logFunctionName, lfmt); \
} \
}
// ==================================================================================
// Macros to simplify tracing thrown exceptions
// ==================================================================================
#define logThrowException(lException) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_EXCEPT, logFunctionName, __LINE__, __FILE__, lException); \
AxisTrace::writeExit(logComponent, logFunctionName, NULL); \
} \
}
#define logThrowExceptionNoExit(lException) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_EXCEPT, logFunctionName, __LINE__, __FILE__, lException); \
} \
}
#define logThrowExceptionWithData(lException, lExceptionMessage) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_EXCEPT, logFunctionName, __LINE__, __FILE__, "%s: %s", lException, lExceptionMessage); \
AxisTrace::writeExit(logComponent, logFunctionName, NULL); \
} \
}
#define logThrowExceptionWithDataNoExit(lException, lExceptionMessage) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_EXCEPT, logFunctionName, __LINE__, __FILE__, "%s: %s", lException, lExceptionMessage); \
} \
}
#define logRethrowException() \
{ \
if (loggingEnabled) { \
AxisTrace::writeExit(logComponent, logFunctionName, "%s", "Rethrowing exception"); \
} \
}
// ==================================================================================
// Macros to simplify tracing
// ==================================================================================
#define logDebug(lFmt) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_DEBUG, logFunctionName, lFmt); \
} \
}
#define logDebugArg1(lFmt, lArg1) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_DEBUG, logFunctionName, lFmt, lArg1); \
} \
}
#define logDebugArg2(lFmt, lArg1, lArg2) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_DEBUG, logFunctionName, lFmt, lArg1, lArg2); \
} \
}
#define logDebugArg3(lFmt, lArg1, lArg2, lArg3) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_DEBUG, logFunctionName, lFmt, lArg1, lArg2, lArg3); \
} \
}
#define logDebugArg4(lFmt, lArg1, lArg2, lArg3, lArg4) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_DEBUG, logFunctionName, lFmt, lArg1, lArg2, lArg3, lArg4); \
} \
}
#define logDebugBuffer(lBuf, lBufLen) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_DEBUG, logFunctionName, false, lBufLen, lBuf); \
} \
}
#define logWarning(lFmt) \
{ \
if (loggingEnabled) { \
AxisTrace::writeTrace(logComponent, TRACE_TYPE_WARN, logFunctionName, lFmt); \
} \
}
#endif