從本節起,開始分析AMPS各模塊的源碼,其中主要地方均加了中文註釋。
跟蹤功能與通常軟件使用的日誌功能類似,但記錄的信息比日誌更詳細,通過它可以看出整個代碼的運行軌跡,AMPS支持多以下幾種跟蹤級別:
- ERROR
- WARNING
- DEBUG
- DEBUG_2
- INFO
- 終端界面顯示模式
- 文件記錄模式
- 以上兩種模式並存
#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;
}