Compare commits

..

1 Commits

Author SHA1 Message Date
mbandic
108e42ce1f Support grouped writing delayed by time 2025-04-04 12:37:39 +02:00
5 changed files with 95 additions and 58 deletions

View File

@ -6,7 +6,8 @@
"*.tcc": "cpp",
"ostream": "cpp",
"mutex": "cpp",
"functional": "cpp",
"iomanip": "cpp"
"queue": "cpp",
"array": "cpp",
"string_view": "cpp"
}
}

View File

@ -34,12 +34,6 @@ using namespace marcelb;
*/
log mylog("../log", Level::INFO);
// or use external writer callback (for occasional writing)
log mylog("../example", [](string log, string path) {
cout << log << " " << path << endl;
}, Level::INFO)
/**
* Put log in file
*/

View File

@ -9,7 +9,7 @@
#include <time.h>
#include <sys/stat.h>
#include <mutex>
#include <functional>
#include <queue>
#if _WIN32
typedef unsigned int uint;
@ -40,7 +40,9 @@ class log {
uint day;
string path;
mutex io;
function<void(string, string)> extWriter;
uint32_t groupedWriting;
time_t lastWriting;
queue<string> toWrite;
/**
* Checking if the path is in the string dir directory
@ -77,6 +79,18 @@ class log {
*/
void put(string logline, Level _level);
/**
* Write to log file
*/
void write(string logline);
void midnight();
void writeQueue();
bool writableQueue();
public:
/**
@ -85,11 +99,9 @@ class log {
* optional: a bool variable if it keeps the file open,
* and a bool variable if it prints log lines to the console
*/
log (string _dir, Level _loglevel = WARNING, bool _isKeepOpen = true, bool _printInConsole = false);
log (string _dir, Level loglevel = WARNING, bool _isKeepOpen = true, bool _printInConsole = false, uint32_t groupedWriting = 0);
log (string _dir, function<void(string, string)> _extWriter, Level _loglevel = WARNING, bool _printInConsole = false);
/**
* Debug log line
*/

View File

@ -3,11 +3,12 @@
namespace marcelb {
namespace logging {
log::log(string _dir, Level _loglevel, bool _isKeepOpen, bool _printInConsole) {
log::log(string _dir, Level _loglevel, bool _isKeepOpen, bool _printInConsole, uint32_t _groupedWriting) {
dir = _dir;
loglevel = _loglevel;
isKeepOpen = _isKeepOpen;
printInConsole = _printInConsole;
groupedWriting = _groupedWriting;
if (!isdir()) {
throw string("[ERROR] Log dir path invalid ");
@ -15,6 +16,9 @@ log::log(string _dir, Level _loglevel, bool _isKeepOpen, bool _printInConsole) {
setMoment();
day = moment->tm_mday;
if (groupedWriting) {
lastWriting = timelocal(moment);
}
setPath();
if (isKeepOpen) {
@ -25,35 +29,19 @@ log::log(string _dir, Level _loglevel, bool _isKeepOpen, bool _printInConsole) {
}
log::log (string _dir, function<void(string, string)> _extWriter, Level _loglevel, bool _printInConsole) {
dir = _dir;
loglevel = _loglevel;
extWriter = _extWriter;
printInConsole = _printInConsole;
setMoment();
day = moment->tm_mday;
setPath();
}
bool log::isdir() {
struct stat sb;
return stat(dir.c_str(), &sb) == 0;
}
bool log::open() {
if (extWriter) {
return false;
}
logfile = ofstream (path, ios_base::app);
return logfile.is_open();
}
void log::loose() {
if (!extWriter) {
logfile.close();
}
logfile.close();
}
void log::setMoment() {
@ -73,37 +61,75 @@ void log::put(string logline, Level _level) {
setMoment();
setPrefix(logline, _level);
midnight();
if (day != moment->tm_mday) {
if (!extWriter && isKeepOpen && logfile.is_open()) {
loose();
}
day = moment->tm_mday;
setPath();
if (!extWriter && isKeepOpen) {
if (!open()) {
throw string("[ERROR] Opening log file! ");
}
if (groupedWriting) {
toWrite.push(logline);
if (writableQueue()) {
writeQueue();
}
} else {
write(logline);
}
io.unlock();
}
if (!extWriter && (!isKeepOpen || !logfile.is_open())) {
void log::write(string logline) {
if (!isKeepOpen || !logfile.is_open()) {
if (!open()) {
throw string("[ERROR] Opening log file! ");
}
}
if (!extWriter) {
logfile << logline << endl;
} else {
extWriter(logline, path);
}
logfile << logline << endl;
if (!extWriter && !isKeepOpen && logfile.is_open()) {
if (!isKeepOpen && logfile.is_open()) {
loose();
}
io.unlock();
}
void log::midnight() {
if (day != moment->tm_mday) {
if (groupedWriting && !toWrite.empty()) {
writeQueue();
}
if (isKeepOpen && logfile.is_open()) {
loose();
}
day = moment->tm_mday;
setPath();
if (isKeepOpen) {
if (!open()) {
throw string("[ERROR] Opening log file! ");
}
}
}
}
void log::writeQueue() {
string lines;
bool notEmpty = !toWrite.empty();
while (notEmpty) {
lines += toWrite.front();
toWrite.pop();
notEmpty = !toWrite.empty();
if (notEmpty) lines += "\n";
}
write(lines);
}
bool log::writableQueue() {
bool _writable = false;
auto _time = timelocal(moment);
if (_time > lastWriting + groupedWriting) {
_writable = true;
lastWriting = _time;
}
return _writable;
}
void log::setPath() {

View File

@ -1,21 +1,25 @@
#include <iostream>
#include <unistd.h>
#include "../lib/log.hpp"
using namespace std;
using namespace marcelb::logging;
log mylog("../example", Level::INFO, false);
// log mylog("../example", [](string log, string path) {
// cout << log << " " << path << endl;
// }, Level::INFO);
log mylog("../example", Level::DEBUG, true, false, 5);
int main() {
mylog.debug("Start debug loging");
mylog.info("Start info loging");
mylog.warning("Start warning loging");
mylog.error("Start error loging");
mylog.fatal("Start fatal loging");
// mylog.debug("Start debug loging");
// mylog.info("Start info loging");
// mylog.warning("Start warning loging");
// mylog.error("Start error loging");
// mylog.fatal("Start fatal loging");
int i = 0;
while(true) {
mylog.fatal("Test fatal error: "+ to_string(i++));
sleep(2);
}
return 0;
}