/** * @file logger.cpp * @brief cppSimpleLogger implementation * @author hendrik schutter * @date 04.09.2020 */ #include "logger.h" using namespace std; string version = "0.2.1"; //logger version bool Logger::instanceFlag = false; Logger* Logger::single = NULL; /** * \brief create new logger instance * \param path to log file * \param struct with data * \return instance of Logger */ Logger::Logger() { this->logPath = LOG_PATH; writeLog(menuLine('+', MENU_LINE_SIZE)); writeLog(padStringMenu('+', " ", MENU_LINE_SIZE)); writeLog(padStringMenu('+', ("Device: " + string(DEVICE_ID) + " -- " + string(DESCRIPTION)), MENU_LINE_SIZE)); writeLog(padStringMenu('+', " ", MENU_LINE_SIZE)); writeLog(padStringMenu('+', ("Software ID: " + string(SOFTWARE_VERSION) + " -- Build time: " + __DATE__ + " " + __TIME__), MENU_LINE_SIZE)); writeLog(padStringMenu('+', " ", MENU_LINE_SIZE)); writeLog(padStringMenu('+', ("Hardware ID: " + string(HARDWARE_VERSION) + " -- MAC: " + getMacAddress()), MENU_LINE_SIZE)); writeLog(padStringMenu('+', " ", MENU_LINE_SIZE)); writeLog(padStringMenu('+', ("cppSimpleLogger -- available from https://git.mosad.xyz/localhorst/cppSimpleLogger -- Version: " + version), MENU_LINE_SIZE)); writeLog(padStringMenu('+', " ", MENU_LINE_SIZE)); writeLog(menuLine('+', MENU_LINE_SIZE)); newLine(); info("Created new log file"); newLine(); } /** * \brief deconstructor * \return void */ Logger::~Logger() { instanceFlag = false; } /** * \brief log info * \param log-text as string * \return void */ void Logger::info(string s) { string tmp = getTimestamp() + " [INFO] " + s; writeLog(tmp); } /** * \brief log warning * \param log-text as string * \return void */ void Logger::warning(string s) { string tmp = getTimestamp() + " [WARNING] " + s; writeLog(tmp); } /** * \brief log error * \param log-text as string * \return void */ void Logger::error(string s) { string tmp = getTimestamp() + " [ERROR] " + s; writeLog(tmp); } /** * \brief write to log file * \param log as string * \return void */ void Logger::writeLog(string s) { ofstream logFile; Logger::mtxLog.lock(); //lock this section for other threads logFile.open(this->logPath, ios_base::app); logFile << (s + "\n"); //append to existing file logFile.close(); Logger::mtxLog.unlock(); //unlock this section for other threads } /** * \brief write new line to log file * \return void */ void Logger::newLine() { writeLog(" "); } /** * \brief get timestamp (system time) as string * \param void * \return string timestamp (formatted) */ string Logger::getTimestamp() { struct tm * timeinfo; struct timeval tv; int millisec; char cpDate [80]; char buffer [120]; gettimeofday(&tv, NULL); millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec if (millisec>=1000) // Allow for rounding up to nearest second { millisec -=1000; tv.tv_sec++; } timeinfo = localtime(&tv.tv_sec); strftime (cpDate,80,"%d/%m/%Y %T",timeinfo); sprintf(buffer, "%s.%03d", cpDate, millisec); return buffer; } /** * \brief get MAC address (system first eth0 interface) as string * \param void * \return string MAC address (formatted) */ string Logger::getMacAddress() { struct ifreq ifr; int s = socket(AF_INET, SOCK_STREAM,0); strcpy(ifr.ifr_name, "eth0"); if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { strcpy(ifr.ifr_name, "eno1"); } unsigned char *hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data; char buffer [80]; sprintf(buffer,"%02X:%02X:%02X:%02X:%02X:%02X", hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); close(s); string tmp = buffer; return tmp; } /** * \brief format menu text in center * \param char for border * \param menu text * \param size of menu line * \return string menu line */ string Logger::padStringMenu(char cBorder, string text, uint8_t u8LineLenght) { string result(1,cBorder); uint8_t u8TextSize = text.length(); uint8_t u8Padding = ((u8LineLenght-u8TextSize)/2); for(uint8_t i = 0 ; i < u8Padding; i++) { result.append(" "); } result.append(text); while((uint8_t)result.length() < (u8LineLenght-1)) { result.append(" "); } result.append(string(1, cBorder)); return result; } /** * \brief format a separator * \param char for border * \param size of menu line * \return string menu line */ string Logger::menuLine(char cBorder, uint8_t u8LineLenght) { string result(1,cBorder); while((uint8_t)result.length() < u8LineLenght) { result.append(string(1, cBorder)); } return result; } /** * \brief return a instance of the logger * \return logger obj */ Logger* Logger::logThis() { if (!instanceFlag) { single = new Logger(); //create new obj instanceFlag = true; return single; } else { return single; //return existing obj } }