Chitika

Thursday, October 20, 2011

C++: Logging Format Consistency

Log message should be consistent and pleasant/easy to view along with compatible with text processing tools like awk/sed and perl for data mining.

During creating of logging it was observed that function fully qualified names (FQN) have average length of 30 and log message have average length of 60, so this width is selected for narrow width strings respectively.

Time stamp was generated as YYYYMMDDHHMMSS.
The log message format was [YYYYMMDDHHMMSS][Function FQN][Log_Level][Log Message][file name, line number]

e.g.: [20091005203159][ABCModInit ][info ][Initializing system... ][Abc.cpp,49]

The code is as follows:

void CLog::LogMessageToFD(FILE *fd, char *msg, int logLevel, char *fileName,
char *funcName, int lineNum,) {

.........................

if(logLevel <= CLog::GlobalLogLevel) {

int szFunc = max(30, strlen(funcName));
int szMsg = max(60, strlen(msg));

time_t tm_t=time(NULL);
tm t;
memcpy(&t, localtime(&tm_t), sizeof(tm));

fprintf(fd, "[%04d%02d%02d%02d%02d%02d][%-*s][%-5s][%-*s]",
t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
szFunc, funcName, CLog::GetLogLevelStr(logLevel), szMsg, msg
);

if(CLog::PrintFileNNum || logLevel == LogLevel::LogLevelError) {

fprintf(fd, "[%s,%d]", fileName, lineNum);

}

fprintf(fd, "\n");

}

.........................

}

GetLogLevelStr is an static method in CLog class as follows:

char *CLog::GetLogLevelStr(int logLevel) {
switch(logLevel) {
case LogLevelError:
return "error";
case LogLevelWarn:
return "warn";
case LogLevelInfo:
return "info";

default:
static char buf[255];
sprintf(buf, "Unknown:(%d)", logLevel);
return buf;
}
}

No comments:

Post a Comment