⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rvloglistener.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
Filename   : rvloglistener.c
Description: rvloglistener file - message log listener
************************************************************************
        Copyright (c) 2001 RADVISION Inc. and RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Inc. and RADVISION Ltd.. No part of this document may be
reproduced in any form whatsoever without written prior approval by
RADVISION Inc. or RADVISION Ltd..

RADVISION Inc. and RADVISION Ltd. reserve the right to revise this
publication and make changes without obligation to notify any person of
such revisions or changes.
***********************************************************************/

#include "rvmemory.h"
#include "rvthread.h"
#include "rvclock.h"
#include "rvtm.h"
#include "rvstdio.h"
#include "rvloglistener.h"


#if (RV_LOGLISTENER_TYPE != RV_LOGLISTENER_NONE)
/* Make sure we have the internal listeners set */



/* Lets make error codes a little easier to type */
#define RvLogListenerErrorCode(_e) RvErrorCode(RV_ERROR_LIBCODE_CCORE, RV_CCORE_MODULE_LOGLISTENER, (_e))



/* Types of listeners */
#define RV_LOGLISTENER_TYPE_TERMINAL 1
#define RV_LOGLISTENER_TYPE_LOGFILE 2
#define RV_LOGLISTENER_TYPE_DEBUG 3

/* Information about which listeners are allocated */
static RvBool rvListenerUsed[3];


#if ((RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32) || \
    (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_FILE_AND_TERMINAL))

typedef struct
{
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32)
    HANDLE      openedFile; /* Handle of the currently opened file */
#else
    FILE*       openedFile; /* Handle of the currently opened file */
#endif
    RvChar      baseFilename[256]; /* Base name of files */
    RvUint32    numFiles; /* Number of files in cycle */
    RvUint32    curFileNum; /* Current file number being used */
    RvUint32    maxFileSize; /* Maximum size of file in cycle */
    RvUint32    curSize; /* Current size of file */
    RvBool      flushLines; /* If RV_TRUE, then on each message, the logfile is flushed */
    RvBool      openError; /* Indication of errors - on error, we stop logging to the log files */
} LogFileListener;

static LogFileListener rvLogFileListener;

#endif  /* ((RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32) || \
    (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_FILE_AND_TERMINAL)) */




/********************************************************************************************
 *
 *                                  Internal functions
 *
 ********************************************************************************************/


/********************************************************************************************
 * logFormatMessage
 *
 * purpose : Format a log record into a printable string
 * input   : logRecord  - Information related with the logged message
 * output  : size       - Size of formatter message in characters
 *                        Can be passed as NULL
 * return  : Pointer to string holding the formatted text
 ********************************************************************************************/
static RvChar* logFormatMessage(
    IN  RvLogRecord*    logRecord,
    OUT RvUint32*       size)
{
    RvChar* buf;
    RvChar* threadName = NULL;
    RvThread* threadInfo;
    RvTime t;
    RvTm tm;
    const RvChar* mtypeStr;
    RvUint32 len;

    /* Find the message type string */
    switch (RvLogRecordGetMessageType(logRecord))
    {
        case RV_LOGLEVEL_EXCEP:   mtypeStr = "EXCEP"; break;
        case RV_LOGLEVEL_ERROR:   mtypeStr = "ERROR"; break;
        case RV_LOGLEVEL_WARNING: mtypeStr = "WARN "; break;
        case RV_LOGLEVEL_INFO :   mtypeStr = "INFO "; break;
        case RV_LOGLEVEL_DEBUG:   mtypeStr = "DEBUG"; break;
        case RV_LOGLEVEL_ENTER:   mtypeStr = "ENTER"; break;
        case RV_LOGLEVEL_LEAVE:   mtypeStr = "LEAVE"; break;
        default:
            return (char*)"Error in message type!";
    }

    /* Move back in the text - there's free space there for our formatting */
    buf = (RvChar *)RvLogRecordGetText(logRecord) - 38;

    /* Find out the thread's name */
    threadInfo = RvLogRecordGetThread(logRecord);
    if (threadInfo != NULL)
        threadName = RvThreadGetName(threadInfo);
    if (threadName == NULL)
        threadName = (RvChar *)"Unknown";

    /* Get the time of the log */
    RvClockGet(&t);
    RvTmConstructLocal(&tm, &t);

    /* Format the additional information into the reserved space in the beginning of the buffer */
    /* 8+1+2+1+2+1+2+1+10+2+5+3 = */
    RvSprintf(buf, "%8.8s %2.2u:%2.2u:%2.2u %-10.10s: %s -",
        threadName,
        RvTmGetHour(&tm), RvTmGetMin(&tm), RvTmGetSec(&tm),
        RvLogSourceGetName(RvLogRecordGetSource(logRecord)),
        mtypeStr);

    /* We're done with time information */
    RvTimeDestruct(&t);
    RvTmDestruct(&tm);

    /* This one is for the addition of the actual string after the fomatted header */
    buf[37] = ' ';

    /* Add a newline in the end and calculate the size of message */
    len = strlen(buf);
    buf[len] = '\0';
    if (size != NULL)
        *size = len;

    /* Return the formatted buffer */
    return buf;
}


/********************************************************************************************
 * logPrintTerminal
 *
 * purpose : Callback that is executed whenever a message has to be logged to the terminal
 * input   : logRecord  - Information related with the logged message
 *           userData   - stdout or stderr (FILE*)
 * output  : None
 * return  : None
 ********************************************************************************************/
static void RVCALLCONV logPrintTerminal(
    IN RvLogRecord* logRecord,
    IN void*        userData)
{
    FILE* f = (FILE *)userData;

    /* We use %s so we don't get formatting characters by mistake into the message - this might
       cause us to crash */
    fprintf(f, "%s\n", logFormatMessage(logRecord, NULL));
}



#if ((RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32) || \
    (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_FILE_AND_TERMINAL))

/********************************************************************************************
 * logPrintLogfile
 *
 * purpose : Callback that is executed whenever a message has to be logged to the logfile
 * input   : logRecord  - Information related with the logged message
 *           userData   - LogFileListener struct
 * output  : None
 * return  : None
 ********************************************************************************************/
static void RVCALLCONV logPrintLogfile(
    IN RvLogRecord* logRecord,
    IN void*        userData)
{
    LogFileListener* logInfo = (LogFileListener *)userData;
    RvChar* logMessage;
    RvUint32 logMessageSize;

    /* Make sure we didn't encounter any errors while trying to open a logfile */
    if (logInfo->openError) return;

    /* See if we have to switch to another file */
    if ((logInfo->openedFile == NULL) ||
        ((logInfo->numFiles > 1) && (logInfo->curSize > logInfo->maxFileSize)))
    {
        /* We need to open the next file... */
        RvChar fname[300];
        RvChar* fnamePtr;

        /* Close the currently opened one */
        if (logInfo->openedFile != NULL)
        {
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32)
            CloseHandle(logInfo->openedFile);
#else
            fclose(logInfo->openedFile);
#endif
            logInfo->openedFile = NULL;
            logInfo->curSize = 0;
        }

        /* Determine the filename */
        if (logInfo->numFiles > 1)
        {
            logInfo->curFileNum = (logInfo->curFileNum + 1) % logInfo->numFiles;

            RvSprintf(fname, "%s%d", logInfo->baseFilename, logInfo->curFileNum);
            fnamePtr = fname;
        }
        else
            fnamePtr = logInfo->baseFilename;

        /* Open the next logfile */
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32)
        logInfo->openedFile = CreateFile((LPCTSTR)fnamePtr, GENERIC_WRITE,
            FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
        logInfo->openError = (logInfo->openedFile == INVALID_HANDLE_VALUE);
#else
        logInfo->openedFile = fopen(fnamePtr, "wb");
        logInfo->openError = (logInfo->openedFile == NULL);
#endif
        /* If we're having any error opening files we shouldn't continue here */
        if (logInfo->openError)
            return;
    }

    if ((logInfo->numFiles == 1) && (logInfo->maxFileSize != 0) && 
        (logInfo->curSize > logInfo->maxFileSize))
    {
        /* move to the beginning of the file */
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32)
        SetFilePointer(logInfo->openedFile, 0, NULL, FILE_BEGIN);
#else
        fseek(logInfo->openedFile, 0, SEEK_SET);
#endif
        logInfo->curSize = 0;
    }
        
    /* At long last - put the message in the logfile */
    logMessage = logFormatMessage(logRecord, &logMessageSize);
    logMessage[logMessageSize] = '\n';
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32)
    {
        DWORD bytesWritten;
        WriteFile(logInfo->openedFile, logMessage, logMessageSize, &bytesWritten, NULL);
        WriteFile(logInfo->openedFile, "\r\n", 2, &bytesWritten, NULL);
    }
#else
    fwrite(logMessage, logMessageSize+1, 1, logInfo->openedFile);
#endif

    logMessage[logMessageSize] = '\0';

    /* See if we have to flush the logfile after adding the message */
    if (logInfo->flushLines)
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32)
        FlushFileBuffers(logInfo->openedFile);
#else
        fflush(logInfo->openedFile);
#endif

    /* Make sure we are aware of the logfile's size */
    logInfo->curSize += logMessageSize;
}

#endif /* ((RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32) || \
    (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_FILE_AND_TERMINAL)) */




#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32)

#if 0


/********************************************************************************************
 * logPrintWindow
 *
 * purpose : Callback that is executed whenever a message has to be logged to a window
 * input   : logRecord  - Information related with the logged message
 *           userData   - WindowListener struct
 * output  : None
 * return  : None
 ********************************************************************************************/
static void RVCALLCONV logPrintWindow(
    IN RvLogRecord* logRecord,
    IN void*        userData)
{
    WindowListener* winInfo = (WindowListener *)userData;
    RvChar* logMessage;
    RvUint32 logMessageSize;
    RvStatus ret;

    logMessage = logFormatMessage(logRecord, &logMessageSize);

    ret = RvLockGet(&winInfo->lock);
    assert(ret == RV_OK);

    /* Make sure we have enough space in pending messages buffer */
    while (logMessageSize > (winInfo->bufferSize - winInfo->curUsedBufSize))
    {
        RvLockRelease(&winInfo->lock); /* Must release this lock before calling SendMessage! */
        SendMessage(winInfo->hWnd, LOGWND_PENDING, 0, 0);
        ret = RvLockGet(&winInfo->lock);
        assert(ret == RV_OK);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -