/** * @file logger.cpp * @brief cppSimpleLogger implementation * @author hendrik schutter * @date 04.09.2020 */ #include "../../include/reHDD.h" //for logger settings #include "../../include/logger/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 * \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); snprintf(buffer, sizeof(buffer), "%s.%03d", cpDate, millisec); return buffer; } /** * \brief get MAC address (system first eth0 interface) as string * \param void * \return string MAC address (formatted) */ std::string Logger::getMacAddress() { struct ifaddrs *ifaddr, *ifa; // default MAC if none found std::string result = "00:00:00:00:00:00"; if (getifaddrs(&ifaddr) == -1) return result; for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { if (!ifa->ifa_addr) continue; // We want AF_PACKET interfaces (Ethernet) if (ifa->ifa_addr->sa_family == AF_PACKET && !(ifa->ifa_flags & IFF_LOOPBACK) && // skip loopback interface (ifa->ifa_flags & IFF_UP)) // must be up { struct sockaddr_ll *s = (struct sockaddr_ll *)ifa->ifa_addr; if (s->sll_halen == 6) { char buf[32]; snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X", s->sll_addr[0], s->sll_addr[1], s->sll_addr[2], s->sll_addr[3], s->sll_addr[4], s->sll_addr[5]); freeifaddrs(ifaddr); return std::string(buf); } } } freeifaddrs(ifaddr); return result; } /** * \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 } }