197 lines
6.8 KiB
C++
197 lines
6.8 KiB
C++
// --------------------------------------------------------------------------------------------------------------------
|
|
/// \file logger.cpp
|
|
/// \brief Description
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// vbchaos software design
|
|
//
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
/// $Revision: $
|
|
/// $Author: $
|
|
/// $Date: $
|
|
// (c) 2023 vbchaos
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
// Include files
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
#include <logger.h>
|
|
|
|
#include <algorithm>
|
|
#include <cstdio>
|
|
#include <cstdarg>
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
// Constant and macro definitions
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
// Type definitions
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
// File-scope variables
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
// Function declarations
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
// Function definitions
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
std::list<struct logger::LogQueueItem> logger::queue;
|
|
uint32_t logger::queuesize = 16;
|
|
uint32_t logger::numberOfLostMessages = 0;
|
|
bool logger::overflowRecovery = false;
|
|
|
|
logger::logger(uint32_t queuesize, ISerialBus<uint8_t>& serialPort) : port {serialPort}
|
|
{
|
|
numberOfLostMessages = 0;
|
|
// Compose the debug type level list
|
|
composeTypeParameterList();
|
|
}
|
|
|
|
|
|
FunctionStatus logger::log(const char* fileName, const char* functionName, int lineNumber, LogType logType, const char* format, ...)
|
|
{
|
|
FunctionStatus returnValue = FUNCTION_STATUS_OK;
|
|
|
|
#if defined(ENABLE_SERIAL_LOGGING)
|
|
int nrOfMessages;
|
|
struct LogQueueItem logQueueItem;
|
|
va_list ap;
|
|
|
|
nrOfMessages = queue.size();
|
|
|
|
if((nrOfMessages >= queuesize - 1) && !overflowRecovery)
|
|
{
|
|
// Queue almost full, only one entry left. Log a warning instead
|
|
composeLogQueueItem(&logQueueItem, __FILE__, __func__, __LINE__, LOGTYPE_WARNING, "Log queue overflow");
|
|
queue.push_back(logQueueItem);
|
|
|
|
overflowRecovery = true;
|
|
numberOfLostMessages = 1;
|
|
}
|
|
else if((nrOfMessages == 0) && overflowRecovery)
|
|
{
|
|
// Queue empty again after an overflow
|
|
std::string str = std::to_string(numberOfLostMessages) + " messages were lost in the logger due to QUEUE overflow";
|
|
composeLogQueueItem(&logQueueItem, __FILE__, __func__, __LINE__, LOGTYPE_WARNING, str);
|
|
queue.push_back(logQueueItem);
|
|
|
|
overflowRecovery = false;
|
|
}
|
|
else if(!overflowRecovery)
|
|
{
|
|
// Normal behaviour, queue not full
|
|
char str[128];
|
|
va_start(ap, format);
|
|
vsnprintf(str, sizeof(str) / sizeof(str[0]), format, ap);
|
|
va_end(ap);
|
|
|
|
composeLogQueueItem(&logQueueItem, fileName, functionName, lineNumber, logType, str);
|
|
queue.push_back(logQueueItem);
|
|
}
|
|
else
|
|
{
|
|
// Count number of lost messages
|
|
++numberOfLostMessages;
|
|
}
|
|
#endif
|
|
return returnValue;
|
|
}
|
|
|
|
|
|
void logger::composeTypeParameterList(void)
|
|
{
|
|
typeParameterList.clear();
|
|
// Add Debug information
|
|
typeParameterList.push_back({LOGTYPE_DEBUG, "\033[33m", "DBG", "\033[0m"});
|
|
// Add Warning information
|
|
typeParameterList.push_back({LOGTYPE_WARNING, "\033[35m", "WRN", "\033[0m"});
|
|
// Add Error information
|
|
typeParameterList.push_back({LOGTYPE_ERROR, "\033[31m", "ERR", "\033[0m"});
|
|
// Add Success information
|
|
typeParameterList.push_back({LOGTYPE_SUCCESS, "\033[32m", "SCS", "\033[0m"});
|
|
// Add Information information
|
|
typeParameterList.push_back({LOGTYPE_INFO, "\033[33m", "INF", "\033[0m"});
|
|
// Add Print information
|
|
typeParameterList.push_back({LOGTYPE_PRINT, "", "DBG", "\033[0m"});
|
|
|
|
}
|
|
|
|
|
|
#if defined(ENABLE_SERIAL_LOGGING)
|
|
void logger::composeLogQueueItem(struct LogQueueItem* logQueueItem, const std::string& fileName, const std::string& functionName,
|
|
int lineNumber, LogType logType, const std::string& context)
|
|
{
|
|
|
|
logQueueItem->logType = logType;
|
|
logQueueItem->context = context;
|
|
|
|
logQueueItem->fileName = fileName;
|
|
logQueueItem->functionName = functionName;
|
|
logQueueItem->lineNumber = lineNumber;
|
|
}
|
|
#endif
|
|
|
|
void logger::task()
|
|
{
|
|
struct LogQueueItem logQueueItem;
|
|
|
|
// Check if there is anything in the queue
|
|
// If queue is empty, return to scheduler
|
|
if (queue.empty())
|
|
{
|
|
return;
|
|
}
|
|
// Get the first log item from queue
|
|
logQueueItem = queue.front();
|
|
// Remove the item from the queue
|
|
queue.pop_front();
|
|
|
|
|
|
if(logQueueItem.logType == LOGTYPE_PRINT)
|
|
{
|
|
// Raw print
|
|
#if defined(ENABLE_SERIAL_LOGGING)
|
|
port.write(NO_DEVICE_ADDRESS, NO_REGISTER_ADDRESS, (uint8_t*)logQueueItem.context.c_str(), logQueueItem.context.length());
|
|
#endif
|
|
|
|
}
|
|
else
|
|
{
|
|
unsigned int seconds = 0;
|
|
|
|
#if defined(ENABLE_SERIAL_LOGGING)
|
|
// Formatted print
|
|
|
|
// Find the correct Log level type
|
|
auto it = std::find_if(typeParameterList.begin(), typeParameterList.end(), [&logQueueItem](const struct typeParameters& obj) {return obj.logType == logQueueItem.logType;});
|
|
|
|
std::string outputString = "\n\r"
|
|
+ it->vt100Prefix + " "
|
|
+ it->vt100Prefix + " "
|
|
+ std::to_string(seconds) + " "
|
|
+ logQueueItem.fileName + " "
|
|
+ logQueueItem.functionName + " "
|
|
+ "(line " + std::to_string(logQueueItem.lineNumber) + "): "
|
|
+ logQueueItem.context + " "
|
|
+ it->vt100Postfix;
|
|
|
|
port.write(NO_DEVICE_ADDRESS, NO_REGISTER_ADDRESS, (uint8_t*)outputString.c_str(), outputString.length() + 1);
|
|
#endif
|
|
|
|
}
|
|
}
|