Provides the means to log debug text to various log areas and at various severity levels and send it to a MODSERIAL serial port object for output.
cLogger.cpp
- Committer:
- paul_harris77
- Date:
- 2017-06-30
- Revision:
- 2:f1b41864f865
- Parent:
- 1:e1be56fa979a
File content as of revision 2:f1b41864f865:
//********************************************************************************************************************* // LOGGER LIBRARY - SOURCE FILE // PAUL HARRIS, OCTOBER 2016 // ********************************************************************************************************************* #include "cLogger.h" //Constructor cLogger::cLogger(MODSERIAL* std_out) { pStdOut = std_out; pStdOut->baud(38400); //Register the LOG area as the first log area for use by the cLogger itself registerLogArea(LOGGER, ERROR, "LOGGER>> "); //Register required log areas here and set default log levels: registerLogArea(MAIN, NORMAL, "MAIN>>"); registerLogArea(SYSTEM_CONTROL, DETAILED, "MAIN_CONTROL>>"); registerLogArea(LIDAR_IF, SUPPRESSED, "LIDAR_IF>>"); registerLogArea(LIDAR_CONTROL, SUPPRESSED, "LIDAR_CONTROL>>"); registerLogArea(MOTOR_CONTROL, SUPPRESSED, "MOTOR_CONTROL>>"); registerLogArea(ENCODER, SUPPRESSED, "ENCODER>>"); registerLogArea(EVENT, DETAILED, "EVENT>>"); registerLogArea(OBSERVER, DETAILED, "OBSERVER>>"); } //***********Begin public member functions************ void cLogger::registerLogArea(eLogArea area, eLogLevel defaultLevel, const char* log_prefix) { //Only add if log area not already registered if (getLogListIndex(area) <0){ log_list.push_back(log_t()); log_list[log_list.size()-1].area = area; log_list[log_list.size()-1].level = defaultLevel; log_list[log_list.size()-1].prefix = log_prefix; if(area != LOGGER) //Don't print anything about adding the cLogger area itself (not interested) { log(LOGGER, NORMAL, "Added new log area with area %s, level %s and prefix %s", sLogArea[log_list[log_list.size()-1].area], sLogLevel[log_list[log_list.size()-1].level], log_list[log_list.size()-1].prefix); log(LOGGER, NORMAL, "log_list now has %d entries", log_list.size()); } } else{ log(LOGGER, ERROR, "Attempt to register log area \"%s\" failed: Log area already registered!", sLogArea[area]); } } void cLogger::log(eLogArea area, eLogLevel text_level, char* log_text, ...) { //******N.B. Don't call the "log" function in any functions that are called as part of log - causes recursion issues!***** va_list args; va_start(args, log_text); int idx = getLogListIndex(area); //If log area fully registered if (idx >= 0) { //Implicitly cast the text log level and area log level to ints for comparison int intTextLevel = text_level; int intLogAreaLevel = log_list[idx].level; //Compare the text's log level to the area's current log level to work out if we should print log text if((intTextLevel <= intLogAreaLevel) && intLogAreaLevel != SUPPRESSED) { cLogger::printf(area, log_text, args); } } else //Log area not registered { log(LOGGER, ERROR, "Attempt to log to an un-registered log area!"); //This doesn't cause log recursion issues... } va_end(args); } void cLogger::plainText(char* log_text, ...) { char text_buffer[256]; //Extract arguments va_list args; va_start(args, log_text); //Lock the stdio mutex stdio_mutex.lock(); //Print formated log text vsprintf(text_buffer, log_text, args); pStdOut->printf(text_buffer); //Unlock the stdio mutex stdio_mutex.unlock(); } void cLogger::newLine(void) { pStdOut->printf("\n\r"); } void cLogger::setLogLevel(eLogArea area, eLogLevel level) { int idx = getLogListIndex(area); if (idx >= 0) { log_list[idx].level = level; } else { log(LOGGER, ERROR, "Attempt to set log level of un-registered log area!"); } } void cLogger::setLogPrefix(eLogArea area, const char* log_prefix) { int idx = getLogListIndex(area); if (idx >= 0) { log_list[idx].prefix = log_prefix; } else { log(LOGGER, ERROR, "Attempt to set log prefix of un-registered log area!"); } } void cLogger::setAllAreaLevels(eLogLevel level) { for(unsigned i=0; i<log_list.size(); i++) { log_list[i].level = level; } } //***********End public member functions************ //***********Begin private member functions************ int cLogger::getLogListIndex(eLogArea area) { int idx; bool match_found = false; for(idx=0; idx<log_list.size(); idx++) { if(log_list[idx].area == area) { match_found = true; break; } } if(match_found) { return idx; } else { return -1; } } void cLogger::printf(eLogArea area, char* log_text, va_list args) { char text_buffer[256]; int idx = getLogListIndex(area); if(idx >=0) { //Lock the stdio mutex stdio_mutex.lock(); //Print log area prefix pStdOut->printf("%s(0x%02x) ", log_list[idx].prefix, osThreadGetId()); //Print formated log text vsprintf(text_buffer, log_text, args); pStdOut->printf(text_buffer); //New line characters pStdOut->printf("\n\r"); //Unlock the stdio mutex stdio_mutex.unlock(); } else { log(LOGGER, ERROR, "Attempt to log to an un-registered log area!"); //This doesn't cause log recursion issues... } } //***********End private member functions************