blob: cd3ebefdb669602cbc7edeb97e21e88d9214f39d [file] [log] [blame]
/* -*- C++ -*- */
/*
* 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.
*
*
*/
// !!! This include file must be first thing in file !!!
#include "../platforms/PlatformAutoSense.hpp"
#include <time.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string>
// cctype is needed to make isprint compile on linux
#include <cctype>
#include <ctime>
#include <cstring>
#include "AxisTrace.h"
AXIS_CPP_NAMESPACE_START
using namespace std;
// Initialization of static trace variables.
bool AxisTrace::m_logFileIsSet = false;
bool AxisTrace::m_stubLogLevelEnabled = true;
bool AxisTrace::m_engineLogLevelEnabled = true;
bool AxisTrace::m_parserLogLevelEnabled = true;
bool AxisTrace::m_transportLogLevelEnabled = true;
bool AxisTrace::m_noEntryExit = false;
bool AxisTrace::m_consoleMode = false;
string AxisTrace::m_logFilePath = "";
//******************************************************************************
//
// AxisTrace::startTrace() Implementation
//
//******************************************************************************
int AxisTrace::
startTrace(const char* logFilePath,
bool dumpEnvironment)
{
// If startTrace() already invoked, just return.
if (NULL == logFilePath || 0x00 == *logFilePath)
return AXIS_FAIL;
m_logFileIsSet = true;
// Set log directory
m_logFilePath = logFilePath;
// We need to do open here in order to ensure file is created and tagged as ASCII.
// This is to cater to EBCDIC-based systems such as IBM i operating system. Should really
// not matter for ASCII-based operating systems such as UNIX and windows.
FILE *logFile = fopen(m_logFilePath.c_str(), TRACE_FILE_MODE1);
if (logFile != NULL)
fclose(logFile);
// Now dump out environment information
if (dumpEnvironment)
{
string text = "************ Start Display Current Environment ************\n";
text += "Axis C++ libraries built on ";
text += __DATE__;
text += " at ";
text += __TIME__;
text += "\n";
writeTrace(text);
char *envVars[]={"AXISCPP_DEPLOY", "PATH","LIBPATH","LD_LIBRARY_PATH","SHLIB_PATH",
"PWD","CLASSPATH","INCLUDE","LIB","NLSPATH","OS",
"COMPUTERNAME","USERNAME","HOSTNAME","LANG","LOGIN","LOGNAME",
"MACHTYPE","OSTYPE","UID","USER"};
for (unsigned i=0; i<(sizeof(envVars)/sizeof(char*)); i++)
{
text = envVars[i];
const char *value = getenv(envVars[i]);
if (NULL!=value)
{
text += "=";
text += value;
text += "\n";
writeTrace(text);
}
}
writeTrace("************* End Display Current Environment *************\n");
}
return AXIS_SUCCESS;
}
//******************************************************************************
//
// AxisTrace::stopTrace() Implementation
//
//******************************************************************************
void AxisTrace::
stopTrace()
{
m_logFilePath = "";
m_logFileIsSet = false;
}
//******************************************************************************
//
// AxisTrace::setLogFilter() Implementation
//
//******************************************************************************
void AxisTrace::
setLogFilter(const char *filters)
{
resetLogFilter();
if (filters == NULL || *filters == 0x00)
return;
string filters_s = filters;
if (filters_s.find(TRACE_FILTER_NOENTRYEXIT) != string::npos)
m_noEntryExit = true;
if (filters_s.find(TRACE_FILTER_STUB) == string::npos)
m_stubLogLevelEnabled = false;
if (filters_s.find(TRACE_FILTER_ENGINE) == string::npos)
m_engineLogLevelEnabled = false;
if (filters_s.find(TRACE_FILTER_PARSER) == string::npos)
m_parserLogLevelEnabled = false;
if (filters_s.find(TRACE_FILTER_TRANSPORT) == string::npos)
m_transportLogLevelEnabled = false;
}
//******************************************************************************
//
// AxisTrace::getLogFilters() Implementation
//
//******************************************************************************
string AxisTrace::
getLogFilter()
{
string filters = "";
string delimiter = ";";
if (m_noEntryExit)
filters += TRACE_FILTER_NOENTRYEXIT + delimiter;
if (m_stubLogLevelEnabled)
filters += TRACE_FILTER_STUB + delimiter;
if (m_engineLogLevelEnabled)
filters += TRACE_FILTER_ENGINE + delimiter;
if (m_parserLogLevelEnabled)
filters += TRACE_FILTER_PARSER + delimiter;
if (m_transportLogLevelEnabled)
filters += TRACE_FILTER_TRANSPORT + delimiter;
return filters;
}
//******************************************************************************
//
// AxisTrace::resetLogFilters() Implementation
//
//******************************************************************************
void AxisTrace::
resetLogFilter()
{
m_stubLogLevelEnabled = true;
m_engineLogLevelEnabled = true;
m_parserLogLevelEnabled = true;
m_transportLogLevelEnabled = true;
m_noEntryExit = false;
}
//******************************************************************************
//
// AxisTrace::enableConsoleMode() Implementation
//
//******************************************************************************
void AxisTrace::
enableConsoleMode()
{
m_consoleMode = true;
}
//******************************************************************************
//
// AxisTrace::disableConsoleMode() Implementation
//
//******************************************************************************
void AxisTrace::
disableConsoleMode()
{
m_consoleMode = false;
}
//******************************************************************************
//
// AxisTrace::writeEntry() Implementation
//
//******************************************************************************
void AxisTrace::
writeEntry (const char* component,
const char* functionName,
const char * fmt,
...)
{
// If logging is not enabled, just return
if (!isLoggingEnabled())
return;
// Filter out entry/exit? If so, simply return.
if (m_noEntryExit)
return;
// Construct final formatter
char myfmt[1024];
if (NULL == fmt)
fmt = "";
sprintf(myfmt, "%s %s %s(): %s\n", component, TRACE_TYPE_ENTRY, functionName, fmt);
va_list vargs;
va_start(vargs,fmt);
writeTrace(myfmt, vargs);
va_end(vargs);
}
//******************************************************************************
//
// AxisTrace::writeExit() Implementation
//
//******************************************************************************
void AxisTrace::
writeExit (const char* component,
const char* functionName,
const char * fmt,
...)
{
// If logging is not enabled, just return
if (!isLoggingEnabled())
return;
// Filter out entry/exit? If so, simply return.
if (m_noEntryExit)
return;
// Construct final formatter
char myfmt[1024];
if (NULL == fmt)
fmt = "";
sprintf(myfmt, "%s %s %s(): %s\n", component, TRACE_TYPE_EXIT, functionName, fmt);
va_list vargs;
va_start(vargs,fmt);
writeTrace(myfmt, vargs);
va_end(vargs);
}
//******************************************************************************
//
// AxisTrace::writeTrace() Implementation
//
//******************************************************************************
void AxisTrace::
writeTrace (const char* component,
const char* type,
const char* functionName,
const char * fmt,
...)
{
// If logging is not enabled, just return
if (!isLoggingEnabled())
return;
// Construct final formatter
char myfmt[1024];
if (NULL == fmt)
fmt = "";
sprintf(myfmt, "%s %s %s(): %s\n", component, type, functionName, fmt);
va_list vargs;
va_start(vargs,fmt);
writeTrace(myfmt, vargs);
va_end(vargs);
}
//******************************************************************************
//
// AxisTrace::writeTrace() Implementation
//
//******************************************************************************
void AxisTrace::
writeTrace (const char* component,
const char* type,
const char* functionName,
int lineNumber,
const char* fileName,
const char * fmt,
...)
{
// If logging is not enabled, just return
if (!isLoggingEnabled())
return;
// Construct final formatter
char myfmt[1024];
if (NULL == fmt)
fmt = "";
sprintf(myfmt, "%s %s %s(): Line=%d: File=%s:\n%s\n", component, type, functionName, lineNumber, fileName, fmt);
va_list vargs;
va_start(vargs,fmt);
writeTrace(myfmt, vargs);
va_end(vargs);
}
//******************************************************************************
//
// AxisTrace::writeTrace() Implementation
//
//******************************************************************************
void AxisTrace::
writeTrace(const char* component,
const char* type,
const char* functionName,
bool hexFormat,
int dataLen,
const char *data)
{
// If logging is not enabled, just return
if (!isLoggingEnabled())
return;
int len = 0;
if (NULL == data || dataLen==0)
return;
// Construct final formatter - the confuscated nature of the code is due to
// the support of EBCDIC based systems.
char myfmt[1024];
sprintf(myfmt, "%s %s %s(): \n", component, type, functionName);
string prefix;
generatePrefix(prefix, myfmt);
PLATFORM_STRTOASC(prefix.c_str());
if (!m_logFilePath.empty())
{
FILE *logFile = fopen(m_logFilePath.c_str(), TRACE_FILE_MODE1);
if (logFile != NULL)
{
fprintf(logFile, "%s%*s%s", prefix.c_str(), dataLen, data, "\x0a");
fflush(logFile);
fclose(logFile);
}
}
if (m_consoleMode)
{
fprintf(stdout, myfmt, dataLen, data);
fflush(stdout);
}
}
//******************************************************************************
//
// AxisTrace::writeTrace() Implementation
//
//******************************************************************************
void AxisTrace::
writeTrace(const char* data, int dataLen, bool hexFormat)
{
// If logging is not enabled, just return
if (!isLoggingEnabled())
return;
int len = 0;
if (NULL == data || dataLen==0)
return;
if (!m_logFilePath.empty())
{
FILE *logFile = fopen(m_logFilePath.c_str(), TRACE_FILE_MODE2);
if (logFile != NULL)
{
len = fwrite(data, 1, dataLen, logFile);
fflush(logFile);
fclose(logFile);
}
}
if (m_consoleMode)
{
len = fwrite(data, 1, dataLen, stdout);
fflush(stdout);
}
}
//******************************************************************************
//
// AxisTrace::writeTrace() Implementation
//
//******************************************************************************
void AxisTrace::
writeTrace(string& s)
{
// If logging is not enabled, just return
if (!isLoggingEnabled())
return;
writeTrace(s.c_str(), s.length());
}
//******************************************************************************
//
// AxisTrace::writeTrace() Implementation
//
//******************************************************************************
void AxisTrace::writeTrace (const char *str)
{
writeTrace(str, strlen(str));
}
//******************************************************************************
//
// AxisTrace::writeTrace() Implementation
//
//******************************************************************************
void AxisTrace::
writeTrace(const char* fmt,
va_list vargs)
{
int len = 0;
string prefix;
generatePrefix(prefix, fmt);
// Dump the data
if (!m_logFilePath.empty())
{
FILE *logFile = fopen(m_logFilePath.c_str(), TRACE_FILE_MODE2);
if (logFile != NULL)
{
len = vfprintf(logFile, prefix.c_str(), vargs);
fflush(logFile);
fclose(logFile);
}
}
if (m_consoleMode)
{
len = vfprintf(stdout, prefix.c_str(), vargs);
fflush(stdout);
}
}
//******************************************************************************
//
// AxisTrace::generatePrefix() Implementation
//
//******************************************************************************
void AxisTrace::
generatePrefix(string &prefix, const char *fmt)
{
if (NULL == fmt)
fmt = "";
const int workBufLen=1024;
char workBuf[workBufLen];
memset(workBuf,0,workBufLen);
// Generate trace timestamp.
PLATFORM_TIMEB timeBuffer;
PLATFORM_GET_TIME_IN_MILLIS( &timeBuffer );
struct tm *tm = localtime(&timeBuffer.time);
strftime(workBuf,workBufLen,"[%d/%m/%Y %H:%M:%S:", tm);
prefix = workBuf;
sprintf(workBuf, "%03u] ", timeBuffer.millitm);
prefix += workBuf;
// Generate trace thread ID - on some system thread ID is long long (64 bits)!
LONGLONG tid = (LONGLONG)PLATFORM_GET_THREAD_ID;
sprintf(workBuf, PRINTF_LONGLONG_LOG_FORMAT_SPECIFIER, tid);
prefix += workBuf;
prefix += " ";
// Add the format passed-in.
prefix += fmt;
}
AXIS_CPP_NAMESPACE_END