看看AMPS中的日志模块,有两种写日志的方法,一是直接使用封装好的API函数写,另一种是通过应用层注册的日志回调函数,利用事件管理机制来写。
AMPS_Log.h
#ifndef __HEADER_AMPS_LOG_H__ #define __HEADER_AMPS_LOG_H__ #include <stdio.h> #include "AMPS_SystemAPI.h" #include "AMPS_Core.h" #include "AMPS_Components.h" #ifdef __cplusplus extern "C" { #endif #define AMPS_LOG_MAX_SIZE_OF_WRITE_BUFFER (1024) typedef struct _AMPSLogContext t_AMPSLogContext; struct _AMPSLogContext { void* pvAMPSContext; void* pvAMPSNetworkMsg; }; void* Log_Init(void* r_pvAMPSContext, char* r_pchFileName); void Log_Cleanup(void* r_pvAMPSLogContext); //AMPS_API int AMPS_Log(void* r_pvAMPSContext, const char* r_puchMessage , ...); int Log_HandleFileWriteEvent(t_AMPSContext* r_poAMPSContext, t_AMPSSNMEvent* r_poAMPSSNMEvent, t_AMPSNetworkMsg* r_poAMPSNetworkMsg); #ifdef __cplusplus } #endif #endif /*#ifndef __HEADER_AMPS_LOG_H__*/
AMPS_Log.c
#include "AMPS_Defines.h" #include "AMPS_LinkList.h" #include "AMPS_SystemAPI.h" #include "AMPS_Core.h" #include "AMPS_MemMgt.h" #include "AMPS_Log.h" /***************************************************************** 函数名称: Log_Init 功能描述: 日志模块初始化 入参:: void* r_pvAMPSContext APMS应用上下文 char* r_pchFileName 日志文件名 出参: 返回值: void* 日志句柄 *****************************************************************/ void* Log_Init(void* r_pvAMPSContext, char* r_pchFileName) { t_AMPSLogContext* poAMPSLogContext = NULL; t_AMPSSNMEvent oAMPSEpollEvent; t_AMPSNetworkMsg* poAMPSNetworkMsg = NULL; TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n"); poAMPSLogContext = (t_AMPSLogContext*)AMPS_InternalMalloc(sizeof(t_AMPSLogContext)); if(NULL == poAMPSLogContext) { TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed.\n"); return NULL; } /*以追加模式打开(如没有,则创建)日志文件*/ poAMPSLogContext->pvAMPSNetworkMsg = SAPI_FileOpenInterface(r_pvAMPSContext, (const char*)r_pchFileName, AMPS_TRUE, AMPS_FILE_MODE_APPEND_WRITE_CREATE); if(NULL == poAMPSLogContext->pvAMPSNetworkMsg) { TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "SAPI_FileOpenForWriting failed.\n"); return NULL; } poAMPSNetworkMsg = (t_AMPSNetworkMsg*)poAMPSLogContext->pvAMPSNetworkMsg; /*注册日志写事件*/ AMPS_SetSNMWriteEvtHandlerInNetMsg(r_pvAMPSContext, poAMPSNetworkMsg, Log_HandleFileWriteEvent); /*注册I/O事件通知*/ SAPI_SetDataInSNMEvent(r_pvAMPSContext, &oAMPSEpollEvent, poAMPSNetworkMsg); SAPI_ResetSNMEvent(r_pvAMPSContext, &oAMPSEpollEvent); SAPI_SetWriteSNMEvent(r_pvAMPSContext, &oAMPSEpollEvent); /*if (AMPS_SUCCESS != SAPI_InsertSNMEvent(r_pvAMPSContext, poAMPSNetworkMsg->nHandle, &oAMPSEpollEvent)) { TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "SAPI_InsertSNMEvent failed \n"); return NULL; }*/ poAMPSLogContext->pvAMPSContext = r_pvAMPSContext; TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving %p.\n", poAMPSLogContext); return poAMPSLogContext; } /***************************************************************** 函数名称: Log_Cleanup 功能描述: 日志模块销毁 入参:: void* r_pvAMPSContext APMS应用上下文 出参: 返回值: NA *****************************************************************/ void Log_Cleanup(void* r_pvAMPSLogContext) { t_AMPSLogContext* poAMPSLogContext = r_pvAMPSLogContext; void* pvAMPSContext = poAMPSLogContext->pvAMPSContext; TRACE( LOG_TRACE_ID(pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering %p.\n", poAMPSLogContext); /*关闭文件*/ SAPI_FileCloseInterface(pvAMPSContext, poAMPSLogContext->pvAMPSNetworkMsg); AMPS_InternalFree(r_pvAMPSLogContext); TRACE( LOG_TRACE_ID(pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n"); } /***************************************************************** 函数名称: AMPS_Log 功能描述: 日志打点函数 入参:: void* r_pvAMPSContext APMS应用上下文 const char* r_puchMessage 日志内容 ... 变长参数 出参: 返回值: int *****************************************************************/ int AMPS_Log(void* r_pvAMPSContext, const char* r_puchMessage , ...) { t_AMPSLogContext* poAMPSLogContext = AMPS_GetLogCtxt(r_pvAMPSContext); t_AMPSNetworkMsg* poAMPSNetworkMsg = poAMPSLogContext->pvAMPSNetworkMsg; t_AMPSParameterList oAMPSParameterList; void* pvMessageToSend = NULL; int nSizeOfMessage = 0; int nLengthOfQueue = 0; int nReturnValue = AMPS_ERROR_FAILURE; int nBytesWritten = 0; TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n"); AMPS_INIT_PARAM_LIST(oAMPSParameterList, r_puchMessage); pvMessageToSend = AMPS_InternalMalloc(AMPS_LOG_MAX_SIZE_OF_WRITE_BUFFER); if (NULL == pvMessageToSend) { TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for pvMessageToSend.\n"); return AMPS_ERROR_FAILURE; } /*组装日志信息*/ nSizeOfMessage = SAPI_WriteToString(r_pvAMPSContext, pvMessageToSend, &oAMPSParameterList, r_puchMessage); if (0 >= nSizeOfMessage) { TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "SAPI_WriteToString failed.\n"); AMPS_InternalFree(pvMessageToSend); return AMPS_ERROR_FAILURE; } /*获取消息队列长度*/ nLengthOfQueue = Queue_GetListBasedQueueLength(r_pvAMPSContext, &poAMPSNetworkMsg->oAMPSListBasedQueue); if(0 < nLengthOfQueue) { if(AMPS_SUCCESS != AMPS_EnQueueDataToNetMsgQ(r_pvAMPSContext, poAMPSNetworkMsg, &poAMPSNetworkMsg->oAMPSListBasedQueue, pvMessageToSend, nSizeOfMessage, 0, NULL)) { TRACE( AMPS_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_EnQueueDataToNetMsgQ failed.\n"); return AMPS_ERROR_FAILURE; } return AMPS_SUCCESS; } /*写日志*/ nReturnValue = SAPI_FileWrite(r_pvAMPSContext, poAMPSNetworkMsg, pvMessageToSend, nSizeOfMessage, &nBytesWritten); if(AMPS_ERROR_IO_PENDING == nReturnValue) { TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_WARNING, "File is marked non-blocking and the write operation would block. \n"); } else if(AMPS_SUCCESS == nReturnValue) { TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "SAPI_FileWrite is successfull. \n"); AMPS_InternalFree(pvMessageToSend); } else if(AMPS_ERROR_FAILURE == nReturnValue) { TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "SAPI_FileWrite failed.\n"); AMPS_InternalFree(pvMessageToSend); AMPS_CLEANUP_PARAM_LIST(oAMPSParameterList); return AMPS_ERROR_FAILURE; } AMPS_CLEANUP_PARAM_LIST(oAMPSParameterList); TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving\n"); return AMPS_SUCCESS; } /***************************************************************** 函数名称: Log_HandleFileWriteEvent 功能描述: 日志事件回调函数 入参:: void* r_pvAMPSContext APMS应用上下文 t_AMPSSNMEvent* r_poAMPSSNMEvent 事件上下文 t_AMPSNetworkMsg* r_poAMPSNetworkMsg 出参: 返回值: int *****************************************************************/ int Log_HandleFileWriteEvent(t_AMPSContext* r_poAMPSContext, t_AMPSSNMEvent* r_poAMPSSNMEvent, t_AMPSNetworkMsg* r_poAMPSNetworkMsg) { int nLengthOfQueue = 0; void* pvMessageToSend = NULL; int nSizeOfMessage = 0; int nMessageOffSet = 0; int nReturnValue = AMPS_ERROR_FAILURE; int nBytesWritten = 0; TRACE( LOG_TRACE_ID(r_poAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Event is EPOLLOUT.\n"); /*获取事件队列长度*/ nLengthOfQueue = Queue_GetListBasedQueueLength(r_poAMPSContext, &r_poAMPSNetworkMsg->oAMPSListBasedQueue); for ( ; nLengthOfQueue > 0; nLengthOfQueue--) { /*从事件队列中取出消息及相关信息*/ if(AMPS_SUCCESS != AMPS_DeQueueDataFromNetMsgQ(r_poAMPSContext, r_poAMPSNetworkMsg, &r_poAMPSNetworkMsg->oAMPSListBasedQueue, &pvMessageToSend, &nSizeOfMessage, &nMessageOffSet, NULL)) { TRACE( LOG_TRACE_ID(r_poAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_DeQueueDataFromNetMsgQ failed\n"); continue; } if((NULL == pvMessageToSend) || (0 >= nSizeOfMessage)) { TRACE( LOG_TRACE_ID(r_poAMPSContext), AMPS_TRACE_LEVEL_ERROR, "NULL Pointers\n"); continue; } /*写日志*/ nReturnValue = SAPI_FileWrite(r_poAMPSContext, r_poAMPSNetworkMsg, pvMessageToSend, nSizeOfMessage, &nBytesWritten); if(AMPS_ERROR_IO_PENDING == nReturnValue) { TRACE( LOG_TRACE_ID(r_poAMPSContext), AMPS_TRACE_LEVEL_WARNING, "File is marked non-blocking and write operation would block \n"); return AMPS_SUCCESS; } else if(AMPS_SUCCESS == nReturnValue) { TRACE( LOG_TRACE_ID(r_poAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "SAPI_FileWrite is successfull. \n"); AMPS_InternalFree(pvMessageToSend); } else if(AMPS_ERROR_FAILURE == nReturnValue) { TRACE( LOG_TRACE_ID(r_poAMPSContext), AMPS_TRACE_LEVEL_ERROR, "SAPI_FileWrite failed.\n"); AMPS_InternalFree(pvMessageToSend); return AMPS_SUCCESS; } } /*写完后,销毁注册的I/O事件*/ if (AMPS_SUCCESS != SAPI_DeleteSNMEvent(r_poAMPSContext, r_poAMPSNetworkMsg, r_poAMPSSNMEvent)) { TRACE( LOG_TRACE_ID(r_poAMPSContext), AMPS_TRACE_LEVEL_ERROR, "SAPI_DeleteSNMEvent is failed \n"); } return AMPS_SUCCESS; }