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

📄 cplog.cxx

📁 RTP协议
💻 CXX
📖 第 1 页 / 共 2 页
字号:
    va_list ap;    if (pri <= CpLogPriority::getPriority())    {	Lock lock(cpLogMutex);        va_start(ap, fmt);        vCpLog(pri, m_fname, m_lineno, fmt, ap);        va_end(ap);    }}#endifvoid cpLog_impl_(int pri, const char* file, int line, const char* fmt, ...){    va_list ap;    if (pri <= CpLogPriority::getPriority())    {        // We need to protect access to vCpLog. The race we are really         // worried about is not the multiple writes to the same file        // descriptor, since the underlying system libraries protect        // against that. We are more worried about the race caused by file        // rotation. If we aren't locked here, we could possible close the        // cpLogFd during file rotation, then try to write to that file        // from another thread. This is something that the underlying        // system libraries cannot protect against.        //	Lock lock(cpLogMutex);        va_start(ap, fmt);        vCpLog(pri, file, line, fmt, ap);        va_end(ap);    }}voidvCpLog(int pri, const char* file, int line, const char* fmt, va_list ap){    assert (pri >= 0 && pri <= LAST_PRIORITY);    char datebuf [DATEBUF_SIZE];    int datebufCharsRemaining;    struct timeval tv;    int result = gettimeofday (&tv, NULL);        if (result == -1)    {        /* If we can't get the time of day, don't print a timestamp.        (Under Unix, this will never happen:  gettimeofday can fail only        if the timezone is invalid [which it can't be, since it is        uninitialized] or if &tv or &tz are invalid pointers.) */        datebuf [0] = '\0';    }    else    {        /* The tv_sec field represents the number of seconds passed since        the Epoch, which is exactly the argument gettimeofday needs. */        const time_t timeInSeconds = (time_t) tv.tv_sec;        struct tm localT;        strftime (datebuf,                  DATEBUF_SIZE,                  "%Y%m%d-%H%M%S", /* guaranteed to fit in 256 chars,                                      hence don't check return code */#if defined( __APPLE__ )                  localtime (&timeInSeconds));#else                  localtime_r (&timeInSeconds, &localT));#endif    }    char msbuf[5];    /* Dividing (without remainder) by 1000 rounds the microseconds    measure to the nearest millisecond. */    sprintf(msbuf, ".%3.3ld", (tv.tv_usec / 1000));    datebufCharsRemaining = DATEBUF_SIZE - strlen (datebuf);    strncat (datebuf, msbuf, datebufCharsRemaining - 1);    datebuf[DATEBUF_SIZE - 1] = '\0'; /* Just in case strncat truncated msbuf,                                     thereby leaving its last character at                                     the end, instead of a null terminator */    if (usingSyslog)    {        #if !defined(WIN32)        /* syslog does not recognize priorities conceptually lower (numerically        greater) than LOG_DEBUG.  If our current priority is lower, "promote"        it to LOG_DEBUG. */        int coercedPriority = (pri <= LOG_DEBUG) ? pri : LOG_DEBUG;	char buf[4097];	vsnprintf(buf, 4096, fmt, ap);        syslog (coercedPriority,                "%s [%5.5ld] %s %s: %s:%d %s\n",                datebuf,                VThread::selfId(),                priNameShort[pri],                CpLogPriority::getLabel(),                file,                line,		buf);        #else	printf("syslog not implemented for win32");	assert(0);        #endif // !defined(WIN32)    }    else    {        fprintf (cpLogFd,                 "%s [%5.5ld] %s %s: %s:%d ",                 datebuf,                 VThread::selfId(),                 priNameShort[pri],                 CpLogPriority::getLabel(),                 file,                 line);        vfprintf (cpLogFd, fmt, ap);        fprintf (cpLogFd, "\n");        fflush(cpLogFd);        /* in case we just pushed the current file past the size limit... */        rotateFilesIfNecessary();    }}/* Handle a critical error in cpLog itself (an error so bad, by definition,it prevents logging in the normal way).  Do this by reverting to usingstandard error as the log "file" and immediately printing a warning aboutthe situation.*/voidhandleCriticalError (char* fmt, ...){    cpLogFd = stderr;    strcpy (cpLogFilename, "");    fprintf (cpLogFd, "\nCRITICAL LOGGING ERROR:\n");        va_list ap;    va_start (ap, fmt);    vfprintf (cpLogFd, fmt, ap);    va_end (ap);    fprintf (cpLogFd, "\ncpLog has reverted to logging to standard error...\n\n");}inlinevoidrotateFilesIfNecessary(){    /* If we are logging to standard error, there are no files to rotate. */    if (cpLogFd == stderr)    {        return;    }    /* If we are logging to syslog, log rotation is somebody else's problem    (SEP); the log file name is outside of our knowledge, and the file itself    may be outside of our permissions */    if (usingSyslog)    {        return;    }    /* Test to see if the present log file has exceeded the maximum       size.  (If it has, rotate it.) */    struct stat fileInfo;        if (stat (cpLogFilename, &fileInfo))    {        /* What?  We can't see the log file? */        handleCriticalError ("cpLog could not stat its own current log file, %s:  %s", cpLogFilename, strerror (errno));            return;    }        if (fileInfo.st_size >= SIZE_PER_LOGFILE)    {        rotateFiles();    }}/* Move the file names, cascading down, so that logfile.1 is renamedto logfile.2, logfile.2 is renamed to logfile.3, et cetera.  logfile.6,if it exists, will be overwritten. */voidrotateFiles(){    /* First double-check the log file size, to avoid a race condition.    It is possible that, between the time rotateFiles was called and    the present moment, some other thread has attempted to log a message    (using vCpLog), noticed that fileInfo.st_size +. SIZE_PER_LOGFILE    (in rotateFilesIfNecessary), and rotated the logs out from under us.    */    struct stat fileInfo;    if (stat (cpLogFilename, &fileInfo) != 0)    {        handleCriticalError ("rotateFiles could not stat the log file (%s)", cpLogFilename);    }    if (fileInfo.st_size < SIZE_PER_LOGFILE)    {        /* The race condition occurred; our files have already been        moved for us. */        return;    }    /* Close the current log file */    if( fclose (cpLogFd) )    {        handleCriticalError ("Could not close the log file:  %s", strerror (errno));    }    /* Make room for the new log file */    for( int i = numberOfBackupFilesToKeep - 1; i >= 0; i-- )    {        string oldFilename( cpLogFilename );        if( i > 0 )        {            oldFilename += "." + itos( i );        }        const char* oldFilename_c_str = oldFilename.c_str();        if (stat (oldFilename_c_str, &fileInfo) == 0) /* if the file _does_ exist... */        {            string newFilename( cpLogFilename );            newFilename += "." + itos( i+1 );            const char* newFilename_c_str = newFilename.c_str();            if (rename (oldFilename_c_str, newFilename_c_str) != 0) /* If rename() fails... */            {                handleCriticalError ("cpLog could not rename %s to %s:  %s", oldFilename_c_str, newFilename_c_str, strerror (errno));                return;            }        }        /* The only reason the file should be un-stat-able is that it        does not exist.  That is a legitimate condition, since rotation may        not yet have created a file with that number (i).  Any other failure        is an error. */        else if (errno != ENOENT)        {            handleCriticalError ("cpLog could not stat %s:  %s", oldFilename_c_str, strerror (errno));            return;        }    }    /* Open the log file for writing once more.  (The current log file will    always have the name stored in cpLogFilename, without a numeric extension.)*/    openTheLogFile();}voidcpLogSetPriority (int pri){    CpLogPriority::setPriority(pri);}intcpLogGetPriority (){    return CpLogPriority::getPriority();}voidcpLogSetPriorityThread (vthread_t thread_id, int pri){    if (pri < 0)        return ;    CpLogPriority::setPriorityThread(thread_id, pri);}voidcpLogClearPriorityThread (vthread_t thread_id){    CpLogPriority::clearPriorityThread(thread_id);}voidcpLogSetLabel (const char* label){    CpLogPriority::setLabel(label);}voidcpLogSetLabelThread (vthread_t thread_id, const char* label){    CpLogPriority::setLabelThread(thread_id, label);}voidcpLogClearLabelThread (vthread_t thread_id){    CpLogPriority::clearLabelThread(thread_id);}voidcpLogShow (void){    fprintf (stderr, "\tLabel    : %s\n", CpLogPriority::getLabel());    fprintf (stderr, "\tPriority : %s\n", priName[CpLogPriority::getPriority()]);    fprintf (stderr, "\tFile     : %s (cpLogFd = %d)\n", cpLogFilename, fileno(cpLogFd));}intcpLogStrToPriority(const char* priority){    string pri = priority;    if (pri.find("LOG_", 0) == 0)    {        pri.erase(0, 4);    }    int i = 0;    while (priName[i] != 0)    {        if (pri == priName[i])        {            return i;        }        i++;    }    return -1;  // invalid}void cpLogSetFileSize (const int size){    SIZE_PER_LOGFILE = size;} void cpLogSetNumOfBackupFiles (const int num){    numberOfBackupFilesToKeep = num;}const char*cpLogPriorityToStr(int priority){    int priorityCount = 0;    while (priName[priorityCount] != 0)    {        priorityCount++;    }    if ((priority >= 0) && (priority < priorityCount))    {        return priName[priority];    }    else    {        return 0;    }}/* this function is not called, it is just compiled to make sure that   the cpLog Macro expansion works */voidtestCpLogMacroExpansion(){    if (true)        cpLog(LOG_DEBUG, "this is a test");    else        cpLog(LOG_DEBUG, "and a second");}/* Local Variables: *//* c-file-style: "stroustrup" *//* indent-tabs-mode: nil *//* c-file-offsets: ((access-label . -) (inclass . ++)) *//* c-basic-offset: 4 *//* End: */

⌨️ 快捷键说明

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