看看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"); }elseif(AMPS_SUCCESS == nReturnValue) { TRACE( LOG_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "SAPI_FileWrite is successfull. \n");AMPS_InternalFree(pvMessageToSend); }elseif(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;intnSizeOfMessage = 0;intnMessageOffSet = 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; } elseif(AMPS_SUCCESS == nReturnValue) {TRACE( LOG_TRACE_ID(r_poAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "SAPI_FileWrite is successfull. \n");AMPS_InternalFree(pvMessageToSend); } elseif(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;}