From d12ef77ba5901051cd8dcd9e7e5094bc5ef0672e Mon Sep 17 00:00:00 2001 From: marcelb Date: Sun, 21 May 2023 11:03:18 +0200 Subject: [PATCH] Tested --- .vscode/settings.json | 8 ++++ example/2023-5-20.log | 5 +++ example/2023-5-21.log | 1 + lib/log.hpp | 36 +++++++++++++++ src/log.cpp | 101 ++++++++++++++++++++++++++++++++++++++++++ test/compile.sh | 1 + test/test.cpp | 14 ++++++ test/test.o | Bin 0 -> 36560 bytes 8 files changed, 166 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 example/2023-5-20.log create mode 100644 example/2023-5-21.log create mode 100644 lib/log.hpp create mode 100644 src/log.cpp create mode 100644 test/compile.sh create mode 100644 test/test.cpp create mode 100755 test/test.o diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..46602ed --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "files.associations": { + "iostream": "cpp", + "iosfwd": "cpp", + "fstream": "cpp", + "*.tcc": "cpp" + } +} \ No newline at end of file diff --git a/example/2023-5-20.log b/example/2023-5-20.log new file mode 100644 index 0000000..67c05ea --- /dev/null +++ b/example/2023-5-20.log @@ -0,0 +1,5 @@ +[EVENT] Start loging +[EVENT] Start loging +10:58:12 [EVENT] Start loging +10:59:19 [EVENT] Start loging +11:00:17 [EVENT] Start loging diff --git a/example/2023-5-21.log b/example/2023-5-21.log new file mode 100644 index 0000000..9999c2f --- /dev/null +++ b/example/2023-5-21.log @@ -0,0 +1 @@ +11:00:58 [EVENT] Start loging diff --git a/lib/log.hpp b/lib/log.hpp new file mode 100644 index 0000000..59fe485 --- /dev/null +++ b/lib/log.hpp @@ -0,0 +1,36 @@ +#ifndef _LOG_ +#define _LOG_ + +#include +#include +#include +#include +#include +#include + +using namespace std; + +class log { + public: + string dir; + bool isKeepOpen; + ofstream logfile; + struct tm * moment; + uint day; + string path; + + log (string _dir, bool _isKeepOpen = true); + + bool isdir(); + bool open(); + void loose(); + void setMoment(); + void setPath(); + void put(string logline); + void setPrefix(string &logline); + + ~log(); +}; + + +#endif \ No newline at end of file diff --git a/src/log.cpp b/src/log.cpp new file mode 100644 index 0000000..498aa5e --- /dev/null +++ b/src/log.cpp @@ -0,0 +1,101 @@ +#include "../lib/log.hpp" + +log::log(string _dir, bool _isKeepOpen) { + dir = _dir; + isKeepOpen = _isKeepOpen; + + if (!isdir()) { + cout << "Eror log dir path invalid!" << endl; + exit(1); + } + + setMoment(); + day = moment->tm_mday; + setPath(); + + if (isKeepOpen) { + if (!open()) { + cout << "Error opening log file!" << endl; + exit(2); + } + } + +} + +bool log::isdir() { + struct stat sb; + return stat(dir.c_str(), &sb) == 0; +} + +bool log::open() { + logfile = ofstream (path, ios_base::app); + return logfile.is_open(); +} + + +void log::loose() { + logfile.close(); +} + +void log::setMoment() { + time_t rawtime; + time (&rawtime); + moment = localtime (&rawtime); +} + +void log::put(string logline) { + setMoment(); + setPrefix(logline); + + if (day != moment->tm_mday) { + if (isKeepOpen && logfile.is_open()) { + loose(); + } + day = moment->tm_mday; + setPath(); + if (isKeepOpen) { + if (!open()) { + cout << "Error opening log file!" << endl; + exit(3); + } + } + } + + if (!isKeepOpen || !logfile.is_open()) { + if (!open()) { + cout << "Error opening log file!" << endl; + exit(4); + } + } + + cout << logline << endl; + logfile << logline << endl; + + + if (!isKeepOpen && logfile.is_open()) { + loose(); + } + +} + +void log::setPath() { + if (dir[dir.length()-1] != '/') { + dir.push_back('/'); + } + path = dir + to_string(moment->tm_year+1900) + '-' + to_string(moment->tm_mon+1) + '-' + to_string(moment->tm_mday) + ".log"; +} + +void log::setPrefix(string &logline) { + stringstream hour, min, sec; + hour << setw(2) << setfill('0') << moment->tm_hour; + min << setw(2) << setfill('0') << moment->tm_min; + sec << setw(2) << setfill('0') << moment->tm_sec; + + string _logline = hour.str() + ':' + min.str() + ':' + sec.str() + ' ' + logline; + logline = _logline; +} + +log::~log() { + loose(); +} + diff --git a/test/compile.sh b/test/compile.sh new file mode 100644 index 0000000..d78b604 --- /dev/null +++ b/test/compile.sh @@ -0,0 +1 @@ +g++ test.cpp ../src/* -o test.o -l sqlite3 \ No newline at end of file diff --git a/test/test.cpp b/test/test.cpp new file mode 100644 index 0000000..a955d42 --- /dev/null +++ b/test/test.cpp @@ -0,0 +1,14 @@ +#include + +#include "../lib/log.hpp" + +using namespace std; + +int main() { + + log mylog("../example", false); + + mylog.put("[EVENT] Start loging"); + + return 0; +} \ No newline at end of file diff --git a/test/test.o b/test/test.o new file mode 100755 index 0000000000000000000000000000000000000000..a8249535f09ac37dcd44a4c5763598bfea5c5288 GIT binary patch literal 36560 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 Q|9&f%pnWgZWI(n52YLto8vp