1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
/*
* Modification History
*
* 2002-February-25 Jason Rohrer
* Created.
*
* 2002-March-11 Jason Rohrer
* Added a missing include.
*
* 2002-April-8 Jason Rohrer
* Fixed a casting, dereferencing Win32 compile bug.
* Changed to be thread-safe.
* Changed to use thread-safe printing function.
*
* 2002-April-8 Jason Rohrer
* Fixed a signed-unsigned mismatch.
*
* 2004-January-11 Jason Rohrer
* Added lock around asctime call.
* Increased scope of lock.
*
* 2004-January-29 Jason Rohrer
* Changed to use ctime instead of localtime and asctime.
* Improved locking scope.
* Changed to use autoSprintf.
*
* 2010-April-5 Jason Rohrer
* Printf-like functionality.
*
* 2010-May-14 Jason Rohrer
* String parameters as const to fix warnings.
*/
#include "PrintLog.h"
#include "minorGems/system/Time.h"
#include "minorGems/util/printUtils.h"
#include "minorGems/util/stringUtils.h"
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
const char *PrintLog::mDefaultLoggerName = "general";
PrintLog::PrintLog()
: mLoggingLevel( Log::TRACE_LEVEL ),
mLock( new MutexLock() ) {
}
PrintLog::~PrintLog() {
delete mLock;
}
void PrintLog::setLoggingLevel( int inLevel ) {
mLock->lock();
mLoggingLevel = inLevel;
mLock->unlock();
}
int PrintLog::getLoggingLevel() {
mLock->lock();
int level = mLoggingLevel;
mLock->unlock();
return level;
}
void PrintLog::logString( const char *inString, int inLevel ) {
logString( (char *)mDefaultLoggerName, inString, inLevel );
}
void PrintLog::logString( const char *inLoggerName, const char *inString,
int inLevel ) {
// not thread-safe to read mLoggingLevel here
// without synchronization.
// However, we want logging calls that are above
// our level to execute with nearly no overhead.
// mutex might be too much overhead....
// Besides, not being thread-safe in this case might
// (worst case) result in a missed log entry or
// an extra log entry... but setting the logging level should be rare.
if( inLevel <= mLoggingLevel ) {
char *message = generateLogMessage( inLoggerName,
inString,
inLevel );
threadPrintF( "%s\n", message );
delete [] message;
}
}
void PrintLog::logPrintf( int inLevel, const char* inFormatString, ... ) {
unsigned int bufferSize = 200;
va_list argList;
va_start( argList, inFormatString );
char *buffer = new char[ bufferSize ];
int stringLength =
vsnprintf( buffer, bufferSize, inFormatString, argList );
va_end( argList );
if( stringLength == -1 || stringLength >= (int)bufferSize ) {
// too long!
delete [] buffer;
buffer = stringDuplicate( "Message too long" );
}
logString( (char *)mDefaultLoggerName, buffer, inLevel );
delete [] buffer;
}
void PrintLog::logNPrintf( const char *inLoggerName,
int inLevel,
const char* inFormatString, ... ) {
unsigned int bufferSize = 200;
va_list argList;
va_start( argList, inFormatString );
char *buffer = new char[ bufferSize ];
int stringLength =
vsnprintf( buffer, bufferSize, inFormatString, argList );
va_end( argList );
if( stringLength == -1 || stringLength >= (int)bufferSize ) {
// too long!
delete [] buffer;
buffer = stringDuplicate( "Message too long" );
}
logString( inLoggerName, buffer, inLevel );
delete [] buffer;
}
char *PrintLog::generateLogMessage( const char *inLoggerName,
const char *inString,
int inLevel ) {
unsigned long seconds, milliseconds;
Time::getCurrentTime( &seconds, &milliseconds );
// lock around ctime call, since it returns a static buffer
mLock->lock();
char *dateString = stringDuplicate( ctime( (time_t *)( &seconds ) ) );
// done with static buffer, since we made a copy
mLock->unlock();
// this date string ends with a newline...
// get rid of it
dateString[ strlen(dateString) - 1 ] = '\0';
char *messageBuffer = autoSprintf( "L%d | %s (%ld ms) | %s | %s",
inLevel, dateString, milliseconds,
inLoggerName, inString );
delete [] dateString;
return messageBuffer;
}
|