从本节起,开始分析AMPS各模块的源码,其中主要地方均加了中文注释。
跟踪功能与通常软件使用的日志功能类似,但记录的信息比日志更详细,通过它可以看出整个代码的运行轨迹,AMPS支持多以下几种跟踪级别:
- ERROR
- WARNING
- DEBUG
- DEBUG_2
- INFO
并支持如下三种跟踪模式:
- 终端界面显示模式
- 文件记录模式
- 以上两种模式并存
下面是源码:
AMPS_Trace.h
#ifndef __HEADER_AMPS_TRACE_H__
#define __HEADER_AMPS_TRACE_H__
#include "AMPS_SystemAPI.h"
#include "AMPS_API.h"
#ifdef __cplusplus
extern "C" {
#endif
/*跟踪文件名最大长度*/
#define AMPS_SIZE_OF_TRACE_FILE_NAME_PLUS_TIME_STAMP 1024
/*每个跟踪文件均以此结尾*/
#define AMPS_TRACE_FILE_NAME "trace.txt"
typedef struct _AMPSTrace t_AMPSTrace;
typedef void(*Trace_Callback)(void* r_pvAMPSTrace, int r_nLineNumber, char* r_pchFileName, const char* r_pchFunctionName, char* r_puchMessage);
/*跟踪模块使用的数据结构*/
struct _AMPSTrace
{
void* pvAMPSContext;
t_AMPSFile oAMPSFile;
char pchTraceFilePath[AMPS_SIZE_OF_TRACE_FILE_NAME_PLUS_TIME_STAMP];
t_AMPSTimerValue oAMPSTimerValue;
t_AMPSParameterList oAMPSParameterList;
unsigned int unModuleId;
unsigned int unTraceLevel;
unsigned int unTraceMode;
int nTraceID;
};
int Trace_Init(void* r_pvAMPSContext, char* r_pchFileName, unsigned int r_unTraceLevel, unsigned int r_unTraceMode);
void Trace_Cleanup(void* r_pvAMPSContext);
int Trace_OpenFileForTracing(void* r_pvAMPSTrace, char* r_pchFileName);
void Trace_SetTraceForTraceID(void* r_pvAMPSContext, unsigned int r_unTraceID);
void Trace_ClearTraceForTraceID(void* r_pvAMPSContext, unsigned int r_unTraceID);
void Trace_SetTraceLevel(void* r_pvAMPSContext, unsigned int r_unTraceLevel);
void Trace_ClearTraceLevel(void* r_pvAMPSContext, unsigned int r_unTraceLevel);
void Trace_SetTraceMode(void* r_pvAMPSContext, unsigned int r_unTraceMode);
void Trace_ClearTraceMode(void* r_pvAMPSContext, unsigned int r_unTraceMode);
int Trace_GetTraceID(void* r_pvAMPSContext);
#ifdef __cplusplus
}
#endif
#endif /*#ifndef __HEADER_AMPS_TRACE_H__*/
AMPS_Trace.c
#include "AMPS_Defines.h"
#include "AMPS_LinkList.h"
#include "AMPS_SystemAPI.h"
#include "AMPS_Core.h"
#include "AMPS_MemMgt.h"
#include "AMPS_Trace.h"
#include "AMPS_Core.h"
#include "AMPS_API.h"
/*全局跟踪句柄*/
t_AMPSTrace* g_poAMPSTrace;
/*跟踪级别*/
char ppchTraceStr[5][20] =
{
"ERROR",
"WARNING",
"DEBUG",
"DEBUG_2",
"INFO"
};
/*****************************************************************
函数名称: Trace_Init
功能描述: 初始化跟踪模块,由AMPS核心模块初始函数Core_Init调用
入参::
void* r_pvAMPSContext AMPS应用上下文数据结构
char* r_pchFilePath 跟踪文件路径
unsigned int r_unTraceLevel 跟踪级别,取值为:
char ppchTraceStr[5][20] =
{
"ERROR",
"WARNING",
"DEBUG",
"DEBUG_2",
"INFO"
};
unsigned int r_unTraceLevel 跟踪记录模式,取值为:
typedef enum
{
AMPS_TRACE_MODE_DISPLAY = 1,
AMPS_TRACE_MODE_FILE = 2,
AMPS_TRACE_MODE_BOTH = 3
}e_AMPSTraceMode;
出参:
--
返回值:
AMPS_SUCCESS: success
AMPS_ERROR_FAILURE: fail
*****************************************************************/
int Trace_Init(void* r_pvAMPSContext, char* r_pchFilePath, unsigned int r_unTraceLevel, unsigned int r_unTraceMode)
{
t_AMPSTrace* poAMPSTrace = NULL;
printf("Trace_Init : Entering %s with mode %d .\n", r_pchFilePath, r_unTraceMode);
poAMPSTrace = (t_AMPSTrace*)AMPS_InternalMalloc(sizeof(t_AMPSTrace));
if(NULL == poAMPSTrace)
{
printf("Trace_Init : AMPS_InternalMalloc failed.\n");
return AMPS_ERROR_FAILURE;
}
poAMPSTrace->pvAMPSContext = r_pvAMPSContext;
poAMPSTrace->unTraceLevel = r_unTraceLevel ;
poAMPSTrace->unModuleId = 0;
poAMPSTrace->unTraceMode = r_unTraceMode;
poAMPSTrace->nTraceID = 1;
memcpy(poAMPSTrace->pchTraceFilePath, r_pchFilePath, strlen(r_pchFilePath));
if((AMPS_TRACE_MODE_FILE == poAMPSTrace->unTraceMode) || (AMPS_TRACE_MODE_BOTH == poAMPSTrace->unTraceMode))
{
printf("Opening File from Init \n");
if(AMPS_SUCCESS != Trace_OpenFileForTracing(poAMPSTrace, poAMPSTrace->pchTraceFilePath))
{
printf("Trace_Init: SAPI_FileOpen failed\n");
AMPS_InternalFree(poAMPSTrace);
return AMPS_ERROR_FAILURE;
}
}
/*将初始化好的跟踪信息赋值给全局跟踪句柄保存*/
g_poAMPSTrace = poAMPSTrace;
printf("Trace_Init : Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Trace_Cleanup
功能描述: 注销跟踪模块,由AMPS核心模块注销函数Core_Cleanup调用
入参::
void* r_pvAMPSContext AMPS应用上下文数据结构
出参:
--
返回值:
void
*****************************************************************/
void Trace_Cleanup(void* r_pvAMPSContext)
{
t_AMPSTrace* poAMPSTrace = g_poAMPSTrace;
printf("Trace_Cleanup : Entering.\n");
if(NULL == poAMPSTrace)
{
return;
}
/*跟踪运行模式中设置了文件模式,则先关闭跟踪文件*/
if((AMPS_TRACE_MODE_FILE == poAMPSTrace->unTraceMode) || (AMPS_TRACE_MODE_BOTH == poAMPSTrace->unTraceMode))
{
printf("Trace_Cleanup : call SAPI_FileClose.\n");
SAPI_FileClose(r_pvAMPSContext, &poAMPSTrace->oAMPSFile);
}
/*释放初始化时保存的全局跟踪句柄*/
AMPS_InternalFree(poAMPSTrace);
printf("Trace_Cleanup : Leaving.\n");
}
/*****************************************************************
函数名称: AMPS_Trace
功能描述: 跟踪打点函数,在需要记录信息的地方调用此函数即可,通常此函数
使用下面的简化格式:
#define TRACE( nModuleID, nTraceLevel, pMessage , ... ) \
AMPS_Trace( __LINE__, __FILE__, __FUNCTION__, nModuleID,\
nTraceLevel, pMessage, __VA_ARGS__)
入参::
int r_nLineNumber 当前打点所处文件行
char* r_pchFileName 当前打点所处文件名
const char* r_pchFunctionName 当前打点所处函数名
unsigned int r_unModuleId 打点的模块号
unsigned int r_unTraceLevel 跟踪级别
char* r_puchMessage, ... 跟踪内容
出参:
--
返回值:
void
*****************************************************************/
void AMPS_Trace(int r_nLineNumber, char* r_pchFileName, const char* r_pchFunctionName, unsigned int r_unModuleId, unsigned int r_unTraceLevel, char* r_puchMessage, ...)
{
t_AMPSTrace* poAMPSTrace = g_poAMPSTrace;
t_AMPSParameterList oAMPSParameterList;
unsigned int unModuleId = 0;
unsigned int unTraceLevel = 0;
unsigned int unTraceMode = 0;
if(NULL == poAMPSTrace)
{
return;
}
unModuleId = poAMPSTrace->unModuleId;
unTraceLevel = poAMPSTrace->unTraceLevel;
unTraceMode = poAMPSTrace->unTraceMode;
/*如果打点所填写的模块号与初始化时使用的模块号是否一致,且跟踪级别一致,
刚记录跟踪信息,不则,不记录*/
if((unModuleId & r_unModuleId) && (unTraceLevel & r_unTraceLevel))
{
int nOffset = 0;
/*设置文件路径*/
char* pchFileName = strrchr(r_pchFileName, '\\');
if(NULL == pchFileName)
{
pchFileName = r_pchFileName;
}
else
{
pchFileName += 1;
}
/*根据级别不同,获取不同便移量,用于获得其对应的字符串类型的日志级别*/
while( (r_unTraceLevel = (r_unTraceLevel>>1)) != 0 ) { nOffset++;}
/*保存自定义的跟踪信息到va_list中*/
AMPS_INIT_PARAM_LIST(oAMPSParameterList, r_puchMessage);
/*获取系统时间*/
SAPI_GetCurrentTime(poAMPSTrace->pvAMPSContext, &poAMPSTrace->oAMPSTimerValue);
/*当模式为终端显示时,设置字体颜色*/
if(AMPS_TRACE_MODE_DISPLAY & unTraceMode)
{
SAPI_SetConsoleTextColor(nOffset, ppchTraceStr[nOffset], poAMPSTrace->oAMPSTimerValue.nHour, poAMPSTrace->oAMPSTimerValue.nMinute, poAMPSTrace->oAMPSTimerValue.nSecond, poAMPSTrace->oAMPSTimerValue.nMilliSecond, pchFileName, r_nLineNumber, r_pchFunctionName);
vprintf(r_puchMessage, oAMPSParameterList);
SAPI_SetDefaultConsoleTextColor(nOffset);
}
/*文件模式下的处理*/
if(AMPS_TRACE_MODE_FILE & unTraceMode && NULL != poAMPSTrace->oAMPSFile.hFileHandle)
{
fprintf(poAMPSTrace->oAMPSFile.hFileHandle,"%-7.8s=>%3.02d:%02d:%02d:%03d: ", ppchTraceStr[nOffset], poAMPSTrace->oAMPSTimerValue.nHour, poAMPSTrace->oAMPSTimerValue.nMinute, poAMPSTrace->oAMPSTimerValue.nSecond, poAMPSTrace->oAMPSTimerValue.nMilliSecond);
fprintf(poAMPSTrace->oAMPSFile.hFileHandle,"%-20.20s:%5d:%-30.30s: ", pchFileName, r_nLineNumber, r_pchFunctionName);
//fprintf(poAMPSTrace->oAMPSFile.hFileHandle,"%8.8s :%02d:%02d:%2d:%03d: ", ppchTraceStr[nOffset], poAMPSTrace->oAMPSTimerValue.nHour, poAMPSTrace->oAMPSTimerValue.nMinute, poAMPSTrace->oAMPSTimerValue.nSecond, poAMPSTrace->oAMPSTimerValue.nMilliSecond);
//fprintf(poAMPSTrace->oAMPSFile.hFileHandle,"%-20.20s:%5d:%-30.30s: ", r_pchFileName, r_nLineNumber, r_pchFunctionName);
vfprintf(poAMPSTrace->oAMPSFile.hFileHandle, r_puchMessage, oAMPSParameterList);
fflush(poAMPSTrace->oAMPSFile.hFileHandle);
}
/*清空va_list*/
AMPS_CLEANUP_PARAM_LIST(oAMPSParameterList);
}
}
/*****************************************************************
函数名称: Trace_SetTraceForTraceID
功能描述: 设置跟踪模块
入参::
void* r_pvAMPSContext AMPS应用上下文数据结构
unsigned int r_unTraceID 跟踪模块
出参:
--
返回值:
void
*****************************************************************/
void Trace_SetTraceForTraceID(void* r_pvAMPSContext, unsigned int r_unTraceID)
{
t_AMPSTrace* poAMPSTrace = g_poAMPSTrace;
if(NULL == poAMPSTrace)
{
return;
}
poAMPSTrace->unModuleId |= r_unTraceID;
}
/*****************************************************************
函数名称: Trace_ClearTraceForTraceID
功能描述: 清除跟踪模块
入参::
void* r_pvAMPSContext AMPS应用上下文数据结构
unsigned int r_unTraceID 跟踪模块
出参:
--
返回值:
void
*****************************************************************/
void Trace_ClearTraceForTraceID(void* r_pvAMPSContext, unsigned int r_unTraceID)
{
t_AMPSTrace* poAMPSTrace = g_poAMPSTrace;
if(NULL == poAMPSTrace)
{
return;
}
poAMPSTrace->unModuleId &= (~r_unTraceID);
}
/*****************************************************************
函数名称: Trace_SetTraceLevel
功能描述: 设置跟踪级别
入参::
void* r_pvAMPSContext AMPS应用上下文数据结构
unsigned int r_unTraceLevel 跟踪级别
出参:
--
返回值:
void
*****************************************************************/
void Trace_SetTraceLevel(void* r_pvAMPSContext, unsigned int r_unTraceLevel)
{
t_AMPSTrace* poAMPSTrace = g_poAMPSTrace;
if(NULL == poAMPSTrace)
{
return;
}
poAMPSTrace->unTraceLevel |= r_unTraceLevel;
}
/*****************************************************************
函数名称: Trace_ClearTraceLevel
功能描述: 清除跟踪级别
入参::
void* r_pvAMPSContext AMPS应用上下文数据结构
unsigned int r_unTraceLevel 跟踪级别
出参:
--
返回值:
void
*****************************************************************/
void Trace_ClearTraceLevel(void* r_pvAMPSContext, unsigned int r_unTraceLevel)
{
t_AMPSTrace* poAMPSTrace = g_poAMPSTrace;
if(NULL == poAMPSTrace)
{
return;
}
poAMPSTrace->unTraceLevel &= r_unTraceLevel;
}
/*****************************************************************
函数名称: Trace_SetTraceMode
功能描述: 设置跟踪模式
入参::
void* r_pvAMPSContext AMPS应用上下文数据结构
unsigned int r_unTraceMode 跟踪模式
出参:
--
返回值:
void
*****************************************************************/
void Trace_SetTraceMode(void* r_pvAMPSContext, unsigned int r_unTraceMode)
{
t_AMPSTrace* poAMPSTrace = g_poAMPSTrace;
if(NULL == poAMPSTrace)
{
return;
}
poAMPSTrace->unTraceMode |= r_unTraceMode;
/*使用了文件模式时,打开跟踪文件*/
if((AMPS_TRACE_MODE_FILE == poAMPSTrace->unTraceMode) || (AMPS_TRACE_MODE_BOTH == poAMPSTrace->unTraceMode))
{
Trace_OpenFileForTracing(poAMPSTrace, poAMPSTrace->pchTraceFilePath);
}
}
/*****************************************************************
函数名称: Trace_ClearTraceMode
功能描述: 清除跟踪模式
入参::
void* r_pvAMPSContext AMPS应用上下文数据结构
unsigned int r_unTraceMode 跟踪模式
出参:
--
返回值:
void
*****************************************************************/
void Trace_ClearTraceMode(void* r_pvAMPSContext, unsigned int r_unTraceMode)
{
t_AMPSTrace* poAMPSTrace = g_poAMPSTrace;
if(NULL == poAMPSTrace)
{
return;
}
poAMPSTrace->unTraceMode &= r_unTraceMode;
}
/*****************************************************************
函数名称: Trace_GetTraceID
功能描述: 获取跟踪ID
入参::
void* r_pvAMPSContext AMPS应用上下文数据结构
出参:
--
返回值:
int 跟踪ID
*****************************************************************/
int Trace_GetTraceID(void* r_pvAMPSContext)
{
t_AMPSTrace* poAMPSTrace = g_poAMPSTrace;
if(NULL == poAMPSTrace)
{
return AMPS_INVALID_TRACE_ID;
}
poAMPSTrace->nTraceID *= 2;
return(poAMPSTrace->nTraceID);
}
/*****************************************************************
函数名称: Trace_OpenFileForTracing
功能描述: 打开跟踪文件
入参::
void* r_pvAMPSTrace AMPS跟踪上下文数据结构
r_pvAMPSTrace 跟踪文件名称
出参:
--
返回值:
AMPS_SUCCESS
AMPS_ERROR_FAILURE
*****************************************************************/
int Trace_OpenFileForTracing(void* r_pvAMPSTrace, char* r_pchFileName)
{
t_AMPSTrace* poAMPSTrace = r_pvAMPSTrace;
char pchFileNameWithTimeStamp[AMPS_SIZE_OF_TRACE_FILE_NAME_PLUS_TIME_STAMP];
if(NULL == poAMPSTrace)
{
return AMPS_ERROR_FAILURE;
}
memset(pchFileNameWithTimeStamp, 0, AMPS_SIZE_OF_TRACE_FILE_NAME_PLUS_TIME_STAMP);
SAPI_GetCurrentTime(poAMPSTrace->pvAMPSContext, &poAMPSTrace->oAMPSTimerValue);
sprintf(pchFileNameWithTimeStamp, "%s/%d.%d.%d.%d_%s", poAMPSTrace->pchTraceFilePath, poAMPSTrace->oAMPSTimerValue.nHour, poAMPSTrace->oAMPSTimerValue.nMinute, poAMPSTrace->oAMPSTimerValue.nSecond, poAMPSTrace->oAMPSTimerValue.nMilliSecond,AMPS_TRACE_FILE_NAME);
if(AMPS_SUCCESS != SAPI_FileOpen(poAMPSTrace->pvAMPSContext, &poAMPSTrace->oAMPSFile, pchFileNameWithTimeStamp, AMPS_TRUE))
{
printf("Trace_OpenFileForTracing: SAPI_FileOpen failed\n");
return AMPS_ERROR_FAILURE;
}
return AMPS_SUCCESS;
}