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************