VOID VmAuthsvcLog( int level, const char* fmt, ...) { char extraLogMessage[EXTRA_LOG_MESSAGE_LEN] = {0}; struct timespec tspec = {0}; struct tm mytm = {0}; char logMessage[MAX_LOG_MESSAGE_LEN]; va_list va; const char* logLevelTag = ""; if ((level & vmauthsvc_debug) || (level == VMAUTHSVC_DEBUG_ANY)) { va_start( va, fmt ); vsnprintf( logMessage, sizeof(logMessage), fmt, va ); logMessage[sizeof(logMessage)-1] = '\0'; va_end( va ); if (vmauthsvc_syslog) { int sysLogLevel = logLevelToSysLogLevel(level); snprintf(extraLogMessage, sizeof(extraLogMessage) - 1, "t@%lu: ", (unsigned long) pthread_self()); syslog(sysLogLevel, "%s%s", extraLogMessage, logMessage); } else { clock_gettime(CLOCK_REALTIME, &tspec); gmtime_r(&tspec.tv_sec, &mytm); logLevelTag = logLevelToTag(level); snprintf(extraLogMessage, sizeof(extraLogMessage) - 1, "%4d-%02d-%02dT%02d:%02d:%02d.%03ldZ:t@%lu:%-3.7s: ", mytm.tm_year+1900, mytm.tm_mon+1, mytm.tm_mday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec, tspec.tv_nsec/NSECS_PER_MSEC, (unsigned long) pthread_self(), logLevelTag? logLevelTag : "UNKNOWN"); if( logFile != NULL ) { fprintf(logFile, "%s%s\n", extraLogMessage, logMessage); fflush( logFile ); } else { fprintf(stderr, "%s%s\n", extraLogMessage, logMessage); fflush( stderr ); } } } }
void Logstream::flush(Tee *t) { const size_t MAX_LOG_LINE = 1024 * 10; // this ensures things are sane if ( doneSetup == 1717 ) { string msg = ss.str(); string threadName = getThreadName(); const char * type = logLevelToString(logLevel); size_t msgLen = msg.size(); if ( msgLen > MAX_LOG_LINE ) msgLen = MAX_LOG_LINE; const int spaceNeeded = (int)( msgLen + 64 /* for extra info */ + threadName.size()); int bufSize = 128; while ( bufSize < spaceNeeded ) bufSize += 128; BufBuilder b(bufSize); char* dateStr = b.grow(24); curTimeString(dateStr); dateStr[23] = ' '; // change null char to space if (!threadName.empty()) { b.appendChar( '[' ); b.appendStr( threadName , false ); b.appendChar( ']' ); b.appendChar( ' ' ); } for ( int i=0; i<indent; i++ ) b.appendChar( '\t' ); if ( type[0] ) { b.appendStr( type , false ); b.appendStr( ": " , false ); } if ( msg.size() > MAX_LOG_LINE ) { stringstream sss; sss << "warning: log line attempted (" << msg.size() / 1024 << "k) over max size(" << MAX_LOG_LINE / 1024 << "k)"; sss << ", printing beginning and end ... "; b.appendStr( sss.str(), false ); const char * xx = msg.c_str(); b.appendBuf( xx , MAX_LOG_LINE / 3 ); b.appendStr( " .......... ", false ); b.appendStr( xx + msg.size() - ( MAX_LOG_LINE / 3 ) ); } else { b.appendStr( msg ); } string out( b.buf() , b.len() - 1); verify( b.len() < spaceNeeded ); scoped_lock lk(mutex); if( t ) t->write(logLevel,out); if ( globalTees ) { for ( unsigned i=0; i<globalTees->size(); i++ ) (*globalTees)[i]->write(logLevel,out); } #if defined(_WIN32) int fd = fileno( logfile ); if ( _isatty( fd ) ) { fflush( logfile ); writeUtf8ToWindowsConsole( out.data(), out.size() ); } #else if ( isSyslog ) { syslog( logLevelToSysLogLevel(logLevel) , "%s" , out.data() ); } #endif else if ( fwrite( out.data(), out.size(), 1, logfile ) ) { fflush(logfile); } else { int x = errno; cout << "Failed to write to logfile: " << errnoWithDescription(x) << ": " << out << endl; } #ifdef POSIX_FADV_DONTNEED // This only applies to pages that have already been flushed RARELY posix_fadvise(fileno(logfile), 0, 0, POSIX_FADV_DONTNEED); #endif } _init(); }