QTSS_Error LogError(QTSS_RoleParamPtr inParamBlock) { Assert(NULL != inParamBlock->errorParams.inBuffer); if (inParamBlock->errorParams.inBuffer == NULL) return QTSS_NoErr; UInt16 verbLvl = (UInt16) inParamBlock->errorParams.inVerbosity; if (verbLvl >= qtssIllegalVerbosity) verbLvl = qtssFatalVerbosity; QTSServerPrefs* thePrefs = QTSServerInterface::GetServer()->GetPrefs(); OSMutexLocker locker(sLogMutex); if (thePrefs->GetErrorLogVerbosity() >= inParamBlock->errorParams.inVerbosity) { size_t inStringLen = ::strlen(inParamBlock->errorParams.inBuffer); size_t lastStringLen = ::strlen(sLastErrorString); Bool16 isDuplicate = true; if (inStringLen > sizeof(sLastErrorString) -1) //truncate to max char buffer subtract \0 terminator inStringLen = sizeof(sLastErrorString) -1; if (lastStringLen != inStringLen) //same size? isDuplicate = false; // different sizes else if (::strncmp(inParamBlock->errorParams.inBuffer, sLastErrorString, lastStringLen ) != 0 ) //same chars? isDuplicate = false; //different chars //is this error message the same as the last one we received? if ( isDuplicate ) { //yes? increment count and bail if it's not the first time we've seen this message (otherwise fall thourhg and write it to the log) sDupErrorStringCount++; return QTSS_NoErr; } else { //we have a new error message, write a "previous line" message before writing the new log entry if ( sDupErrorStringCount >= 1 ) { /*** clean this up - lots of duplicate code ***/ //The error logger is the bottleneck for any and all messages printed by the server. //For debugging purposes, these messages can be printed to stdout as well. if (thePrefs->IsScreenLoggingEnabled()) qtss_printf("--last message repeated %d times\n", sDupErrorStringCount); CheckErrorLogState(); if (sErrorLog == NULL) return QTSS_NoErr; //timestamp the error char theDateBuffer[QTSSRollingLog::kMaxDateBufferSizeInBytes]; Bool16 result = QTSSRollingLog::FormatDate(theDateBuffer, false); //for now, just ignore the error. if (!result) theDateBuffer[0] = '\0'; char tempBuffer[kMaxLogStringLen]; qtss_snprintf(tempBuffer,sizeof(tempBuffer), "%s: --last message repeated %d times\n", theDateBuffer, sDupErrorStringCount); sErrorLog->WriteToLog(tempBuffer, kAllowLogToRoll); sDupErrorStringCount = 0; } ::strncpy(sLastErrorString, inParamBlock->errorParams.inBuffer, sizeof(sLastErrorString)); sLastErrorString[sizeof(sLastErrorString)-1] = '\0'; } //The error logger is the bottleneck for any and all messages printed by the server. //For debugging purposes, these messages can be printed to stdout as well. if (thePrefs->IsScreenLoggingEnabled()) qtss_printf("%s %s\n", sErrorLevel[verbLvl], inParamBlock->errorParams.inBuffer); CheckErrorLogState(); if (sErrorLog == NULL) return QTSS_NoErr; //timestamp the error char theDateBuffer[QTSSRollingLog::kMaxDateBufferSizeInBytes]; Bool16 result = QTSSRollingLog::FormatDate(theDateBuffer, false); //for now, just ignore the error. if (!result) theDateBuffer[0] = '\0'; char tempBuffer[kMaxLogStringLen]; qtss_snprintf(tempBuffer,sizeof(tempBuffer), "%s: %s %s\n", theDateBuffer, sErrorLevel[verbLvl], inParamBlock->errorParams.inBuffer); tempBuffer[sizeof(tempBuffer)-2] = '\n'; //make sure the entry has a line feed before the \0 terminator tempBuffer[sizeof(tempBuffer)-1] = '\0'; //make sure it is 0 terminated. sErrorLog->WriteToLog(tempBuffer, kAllowLogToRoll); } return QTSS_NoErr; }