diff --git a/include/logger/logger.h b/include/logger/logger.h new file mode 100644 index 0000000..b6751ea --- /dev/null +++ b/include/logger/logger.h @@ -0,0 +1,80 @@ +/** + * @file logger.h + * @brief cppSimpleLogger Header + * @author hendrik schutter + * @date 04.09.2020 + */ + +#ifndef LOGGER_H_ +#define LOGGER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +#define MENU_LINE_SIZE 110 //Size of menu lines + +#ifndef LOG_PATH +//#define LOG_PATH "./test.txt" +#endif + +#ifndef DESCRIPTION +#define DESCRIPTION "Software-Name - Copyright Company 2020" //use your values here +#endif + +#ifndef DEVICE_ID +#define DEVICE_ID "Device-Name" //use your values here +#endif + +#ifndef SOFTWARE_VERSION +#define SOFTWARE_VERSION "0.1.1.8" //use your values here +#endif + +#ifndef HARDWARE_VERSION +#define HARDWARE_VERSION "7.77.9" //use your values here +#endif + +class Logger +{ +private: + string logPath; + mutex mtxLog; + + static bool instanceFlag; + static Logger *single; + + string getTimestamp(); + void writeLog(string s); + string getMacAddress(); + string padStringMenu(char cBorder, string text, uint8_t u8LineLenght); + string menuLine(char cBorder, uint8_t u8LineLenght); + Logger(); + ~Logger(); + +public: + + void info(string s); + void warning(string s); + void error(string s); + void newLine(); + + static Logger* logThis(); +}; + +#endif // LOGGER_H_ \ No newline at end of file diff --git a/include/reHDD.h b/include/reHDD.h index 690959d..03643a0 100644 --- a/include/reHDD.h +++ b/include/reHDD.h @@ -18,6 +18,13 @@ #define READ 0 #define WRITE 1 +// Logger Settings +#define LOG_PATH "./reHDD.log" +#define DESCRIPTION "reHDD - Copyright Hendrik Schutter 2020" +#define DEVICE_ID "generic" +#define SOFTWARE_VERSION "alpha" +#define HARDWARE_VERSION "generic" + #include #include #include @@ -43,7 +50,9 @@ using namespace std; #include "shred/shred.h" #include "delete.h" #include "tui.h" +#include "logger/logger.h" +extern Logger* logging; template T* iterator_to_pointer(I i) { @@ -56,10 +65,12 @@ protected: public: reHDD(void); - void app_logic(); + static void app_logic(); private: + //static Logger* logging; + static void searchDrives(vector * pvecDrives); static void printDrives(vector * pvecDrives); static void filterIgnoredDrives(vector * pvecDrives); @@ -76,4 +87,4 @@ private: }; -#endif // REHDD_H_ \ No newline at end of file +#endif // REHDD_H_ diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp new file mode 100644 index 0000000..5708359 --- /dev/null +++ b/src/logger/logger.cpp @@ -0,0 +1,235 @@ +/** + * @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 + * \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 + } +} + + diff --git a/src/reHDD.cpp b/src/reHDD.cpp index 051ca08..185a347 100644 --- a/src/reHDD.cpp +++ b/src/reHDD.cpp @@ -32,7 +32,6 @@ static fd_set selectSet; */ reHDD::reHDD(void) { - cout << "created app" << endl; u8SelectedEntry = 0U; } @@ -43,7 +42,6 @@ reHDD::reHDD(void) */ void reHDD::app_logic(void) { - cout << "app logic" << endl; ui = new TUI(); ui->initTUI(); @@ -90,6 +88,7 @@ Drive* reHDD::getSelectedDrive() } else { + Logger::logThis()->warning("selected drive not present"); return {}; } } @@ -98,7 +97,6 @@ void reHDD::ThreadScannDevices() { while(true) { - // cout << "Thread" << endl; mxScannDrives.lock(); vecNewDrives.clear(); searchDrives(&vecNewDrives); //search for new drives and store them in list @@ -180,13 +178,13 @@ void reHDD::ThreadShred() if (getSelectedDrive() != nullptr) { Shred::shredDrive(getSelectedDrive(), &fdShredInformPipe[1]); + Logger::logThis()->info("Finished shred for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial()); ui->updateTUI(&vecDrives, u8SelectedEntry); } } void reHDD::filterNewDrives(vector * pvecOldDrives, vector * pvecNewDrives) { - vector ::iterator itOld; //Iterator for current (old) drive list vector ::iterator itNew; //Iterator for new drive list that was created from to scann thread @@ -209,6 +207,7 @@ void reHDD::filterNewDrives(vector * pvecOldDrives, vector * pvecN if(bOldDriveIsOffline == true) { //cout << "offline drive found: " << itOld->getPath() << endl; + Logger::logThis()->warning("offline drive found delete for: " + itOld->getPath()); itOld->state = Drive::NONE; } } @@ -217,6 +216,7 @@ void reHDD::filterNewDrives(vector * pvecOldDrives, vector * pvecN for (long unsigned int i=0; isize(); i++) { pvecOldDrives->push_back((*pvecNewDrives)[i]); + Logger::logThis()->info("Attached drive: " + i + string("-") + pvecNewDrives->at(i).getPath()); } } @@ -263,8 +263,6 @@ void reHDD::filterIgnoredDrives(vector * pvecDrives) vector> vtlIgnoredDevices; //store drives from ingnore file - //vector vecTmpDrives - ifstream input( "ignoreDrives.conf" ); //read ingnore file for(string sLine; getline( input, sLine );) @@ -280,8 +278,6 @@ void reHDD::filterIgnoredDrives(vector * pvecDrives) sLine.erase(0, pos + sDelimiter.length()); sIgnoredDriveUUID = sLine; } //end while - //cout << "Path: " << sIgnoredDrivePath << std::endl; - //cout << "UUID: " << sIgnoredDriveUUID << std::endl; vtlIgnoredDevices.emplace_back(sIgnoredDrivePath, sIgnoredDriveUUID); //add found path and uuid from ingnore file to vector } } @@ -322,14 +318,15 @@ void reHDD::filterIgnoredDrives(vector * pvecDrives) if (get<1>(row).compare(sUUID)) //compare uuid from ignore file and uuid from drive { cout << "[ERROR] different uuid found than in ignore file:" << it->getPath() << endl; + Logger::logThis()->error("[ERROR] different uuid found than in ignore file: " + it->getPath()); exit(EXIT_FAILURE); // exit to prevent accidentally shred a system drive } else { // same uuid found than in ignore file --> ignore this drive + Logger::logThis()->info("same uuid found than in ignore file --> ignore this drive: " + it->getPath()); it = pvecDrives->erase(it); it--; - //cout << "same uuid found than in ignore file --> ignore this drive:" << it->getPath() << endl; } } } @@ -402,6 +399,8 @@ void reHDD::handleArrowKey(TUI::UserInput userInput) u8SelectedEntry = 0; break; } + + Logger::logThis()->info("ArrowKey - selected drive: " + to_string(u8SelectedEntry)); } void reHDD::handleEnter() @@ -410,6 +409,7 @@ void reHDD::handleEnter() { if(getSelectedDrive()->state == Drive::TaskState::SHRED_SELECTED) { + Logger::logThis()->info("Started shred for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial()); getSelectedDrive()->state = Drive::TaskState::SHRED_ACTIVE; //task for drive is running --> don´t show more task options thread(ThreadShred).detach(); @@ -417,11 +417,13 @@ void reHDD::handleEnter() if(getSelectedDrive()->state == Drive::TaskState::DELETE_SELECTED) { + Logger::logThis()->info("Started delete for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial()); getSelectedDrive()->state = Drive::TaskState::DELETE_ACTIVE; //task for drive is running --> don´t show more task options Delete::deleteDrive(getSelectedDrive()); //blocking, no thread getSelectedDrive()->state = Drive::TaskState::NONE; //delete finished getSelectedDrive()->bWasDeleteted = true; + Logger::logThis()->info("Finished delete for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial()); } } } @@ -451,6 +453,7 @@ void reHDD::handleAbort() if(getSelectedDrive()->state == Drive::SHRED_ACTIVE || getSelectedDrive()->state == Drive::DELETE_ACTIVE ) { getSelectedDrive()->state = Drive::NONE; + Logger::logThis()->info("Abort-Shred for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial()); //task for drive is running --> remove selection } } diff --git a/src/tui.cpp b/src/tui.cpp index 2536b22..9c4cf8c 100644 --- a/src/tui.cpp +++ b/src/tui.cpp @@ -11,10 +11,8 @@ static std::mutex mxUIrefresh; TUI::TUI(void) { - } - /** * \brief wipe drive with shred * \param pointer of Drive instance @@ -33,6 +31,7 @@ void TUI::initTUI() else { printf("Your terminal does not support color\n"); + Logger::logThis()->error("Your terminal does not support color"); exit(1); } clear(); @@ -48,6 +47,7 @@ void TUI::initTUI() init_pair(COLOR_AREA_DETAIL, COLOR_BLACK, COLOR_WHITE); mvprintw(0, 2, "reHDD - HDD refurbishing tool - GPL 3.0 "); + Logger::logThis()->info("UI successfully initialized"); } void TUI::updateTUI(vector * pvecDrives, uint8_t u8SelectedEntry) @@ -122,6 +122,7 @@ void TUI::updateTUI(vector * pvecDrives, uint8_t u8SelectedEntry) if(pvecDrives->size() == 0) { //no selected drive present + Logger::logThis()->warning("no selected drive present"); struct MenuState menustate; menustate.bAbort = false; menustate.bConfirmDelete = false; @@ -195,7 +196,6 @@ WINDOW* TUI::createOverViewWindow( int iXSize, int iYSize) centerTitle(newWindow, "Detected Drives"); - //keypad(newWindow, TRUE); return newWindow; } @@ -261,7 +261,6 @@ WINDOW* TUI::createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive mvwaddstr(newWindow,u16Line++, 3, sErrorCount.c_str()); } - //keypad(newWindow, TRUE); return newWindow; } @@ -295,7 +294,6 @@ WINDOW* TUI::overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart) attroff(COLOR_PAIR(COLOR_AREA_DETAIL)); - //keypad(newWindow, TRUE); return newWindow; } @@ -325,14 +323,11 @@ WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, mvwaddstr(newWindow,2, iXSize-sState.length()-5, sState.c_str()); - //keypad(newWindow, TRUE); - return newWindow; } WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iYStart) { - WINDOW *newWindow; newWindow = newwin(iYSize, iXSize, iYStart, 2); @@ -351,7 +346,6 @@ WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iYStart) mvwaddstr(newWindow,2, 2, time.c_str()); - //keypad(newWindow, TRUE); return newWindow; } @@ -380,7 +374,7 @@ WINDOW* TUI::createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, st { mvwaddstr(newWindow,u16Line++, 3, "Press D for Delete"); } - //keypad(newWindow, TRUE); + return newWindow; } @@ -398,7 +392,6 @@ WINDOW* TUI::createDialog(int iXSize, int iYSize, int iXStart, int iYStart, stri mvwaddstr(newWindow,u16Line++, 3, optionA.c_str()); mvwaddstr(newWindow,u16Line++, 3, optionB.c_str()); - //keypad(newWindow, TRUE); return newWindow; }