| /* -*- 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 |