当前位置: 首页 > 工具软件 > AMPS > 使用案例 >

AMPS:日志模块源码解读

湛铭
2023-12-01

  看看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;
}





 类似资料: