From f14919ed5de46a2927843e101d97f4d97778aee4 Mon Sep 17 00:00:00 2001 From: localhorst Date: Mon, 7 Sep 2020 15:31:09 +0200 Subject: [PATCH] changed to singelton --- MainExample.cpp | 15 +++------------ README.md | 2 +- logger.cpp | 39 +++++++++++++++++++++++++++++---------- logger.h | 42 ++++++++++++++++++++++++++++++++---------- myTest | Bin 0 -> 40424 bytes test.txt | 17 +++++++++++++++++ 6 files changed, 82 insertions(+), 33 deletions(-) create mode 100755 myTest create mode 100644 test.txt diff --git a/MainExample.cpp b/MainExample.cpp index 0ff0e98..6f555c4 100644 --- a/MainExample.cpp +++ b/MainExample.cpp @@ -19,20 +19,11 @@ int main(void) { cout << "Hello World!\n"; - struct sID id; - - id.description = "Software-Name - Copyright Company 2020"; //use your values here - id.deviceID = "Device-Name"; //use your values here - id.softwareID = "0.1.1.8"; //use your values here - id.hardwareID = "7.77.9"; //use your values here - - Logger* logging = new Logger("./test.txt", id); //use your path here - - logging->info("Alle Systeme laufen!"); //demo + Logger::logThis()->info("Alle Systeme laufen!"); //demo usleep(1465); - logging->warning("Alle Systeme laufen!"); //demo + Logger::logThis()->warning("Alle Systeme laufen!"); //demo usleep(51654); - logging->error("Alle Systeme laufen!"); //demo + Logger::logThis()->error("Alle Systeme laufen!"); //demo cout << "bye!\n"; diff --git a/README.md b/README.md index a53c328..66e74fb 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ ## build example -clear && g++ -Wall logger.cpp MainExample.cpp -o myTest && ./myTest +rm -f test.txt && clear && g++ -Wall logger.cpp MainExample.cpp -o myTest && ./myTest diff --git a/logger.cpp b/logger.cpp index 1744ad8..f5303da 100644 --- a/logger.cpp +++ b/logger.cpp @@ -9,7 +9,10 @@ using namespace std; -string version = "0.2"; //logger version +string version = "0.2.1"; //logger version + +bool Logger::instanceFlag = false; +Logger* Logger::single = NULL; /** * \brief create new logger instance @@ -17,21 +20,20 @@ string version = "0.2"; //logger version * \param struct with data * \return instance of Logger */ -Logger::Logger(string pLogPath,struct sID id) +Logger::Logger() { - this->logPath =pLogPath; + this->logPath = LOG_PATH; writeLog(menuLine('+', MENU_LINE_SIZE)); - writeLog(padStringMenu('+', " ", MENU_LINE_SIZE)); - writeLog(padStringMenu('+', ("Device: " + id.deviceID + " -- " + id.description), MENU_LINE_SIZE)); + writeLog(padStringMenu('+', ("Device: " + string(DEVICE_ID) + " -- " + string(DESCRIPTION)), MENU_LINE_SIZE)); writeLog(padStringMenu('+', " ", MENU_LINE_SIZE)); - writeLog(padStringMenu('+', ("Software ID: " + id.softwareID + " -- Build time: " + __DATE__ + " " + __TIME__), 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: " + id.hardwareID + " -- MAC: " + getMacAddress()), 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)); @@ -44,10 +46,12 @@ Logger::Logger(string pLogPath,struct sID id) } /** - * \brief deconctructor + * \brief deconstructor + * \return void */ Logger::~Logger() { + instanceFlag = false; } /** @@ -208,7 +212,22 @@ string Logger::menuLine(char cBorder, uint8_t u8LineLenght) 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/logger.h b/logger.h index 62c4bd0..0ce17d5 100644 --- a/logger.h +++ b/logger.h @@ -5,6 +5,9 @@ * @date 04.09.2020 */ +#ifndef LOGGER_H_ +#define LOGGER_H_ + #include #include #include @@ -27,32 +30,51 @@ using namespace std; #define MENU_LINE_SIZE 110 //Size of menu lines -struct sID -{ - string description; - string deviceID; - string softwareID; - string hardwareID; -}; +#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: - Logger(string pLogPath, struct sID id); - ~Logger(); + 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/myTest b/myTest new file mode 100755 index 0000000000000000000000000000000000000000..fb3e082297f2077d9876f91dc26bf40700f07da1 GIT binary patch literal 40424 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