threaded flusher
This commit is contained in:
parent
b78ffe90ce
commit
e9ca6a04e7
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
.cache/
|
||||
target/
|
||||
compile_commands.json
|
||||
test.log
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <stop_token>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
|
||||
namespace journal {
|
||||
namespace mutex {
|
||||
|
@ -176,10 +178,10 @@ struct Verbosity {
|
|||
}
|
||||
};
|
||||
|
||||
namespace sinks {
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace sinks {
|
||||
|
||||
struct BaseSink {
|
||||
Verbosity min_verbosity;
|
||||
Verbosity max_verbosity;
|
||||
|
@ -255,25 +257,44 @@ struct FileSink : public OStreamSink {
|
|||
: OStreamSink(std::make_shared<std::ofstream>(file_path, open_mode), min,
|
||||
max) {}
|
||||
};
|
||||
|
||||
} // namespace sinks
|
||||
|
||||
static auto try_flush_all_loop(std::stop_token) -> void;
|
||||
|
||||
class Journal {
|
||||
std::vector<std::unique_ptr<sinks::BaseSink>> sinks;
|
||||
std::jthread flush_thread;
|
||||
|
||||
public:
|
||||
Journal() {}
|
||||
auto log(const Verbosity &verbosity, source_location source,
|
||||
std::string_view msg) {
|
||||
const auto now = std::chrono::system_clock::now();
|
||||
for (auto &&sink : sinks) {
|
||||
if (sink->should_sink_verbosity(verbosity)) {
|
||||
(*sink) << format(msg, verbosity, source);
|
||||
}
|
||||
if (sink->should_flush()) {
|
||||
sink->flush();
|
||||
Journal() { flush_thread = std::jthread(&detail::try_flush_all_loop); }
|
||||
~Journal() {
|
||||
log(LogVerbosity::Trace, source_location::current(),
|
||||
"Requesting stop for flush thread");
|
||||
flush_thread.request_stop();
|
||||
log(LogVerbosity::Trace, source_location::current(),
|
||||
"Waiting for flush thread to join..");
|
||||
flush_thread.join();
|
||||
log(LogVerbosity::Trace, source_location::current(), "Flush thread joined");
|
||||
try_flush_all();
|
||||
}
|
||||
|
||||
auto try_flush_all() -> void {
|
||||
for (auto &&sink : sinks) {
|
||||
if (sink->should_flush()) {
|
||||
sink->flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto log(const Verbosity &verbosity, source_location source,
|
||||
std::string_view msg) -> void {
|
||||
for (auto &&sink : sinks) {
|
||||
if (sink->should_sink_verbosity(verbosity)) {
|
||||
(*sink) << format(msg, verbosity, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto format(std::string_view str, const Verbosity &verbosity,
|
||||
const source_location &source) -> std::string {
|
||||
|
@ -310,6 +331,16 @@ auto add_std_err() { add_sink(std::make_unique<sinks::StdErrSink>()); }
|
|||
|
||||
static mutex::Mutex<std::unique_ptr<Journal>> global_journal;
|
||||
|
||||
static auto try_flush_all_loop(std::stop_token stoken) -> void {
|
||||
while (!stoken.stop_requested()) {
|
||||
{
|
||||
auto &&[lock, ref] = global_journal.mut();
|
||||
ref->try_flush_all();
|
||||
}
|
||||
std::this_thread::sleep_for(5s);
|
||||
}
|
||||
}
|
||||
|
||||
auto log_internal(const LogVerbosity &verbosity, detail::source_location source,
|
||||
const std::string &msg) -> void {
|
||||
auto &&[lock, ref] = global_journal.ref();
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
#include <stdio.h>
|
||||
#include "journal.hpp"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
auto stream = std::make_shared<std::stringstream>();
|
||||
|
||||
journal::init_std_out_err();
|
||||
journal::add_sink(stream, journal::LogVerbosity::Warn);
|
||||
journal::add_file("test.log");
|
||||
journal::info("some info!");
|
||||
journal::error("something went wrong!");
|
||||
journal::warn("something went slightly wrong!");
|
||||
std::cin.get();
|
||||
std::cout << "stream content: \n" << stream->view() << "\n";
|
||||
journal::trace("just some very verbose stuff here");
|
||||
return 1;
|
||||
}
|
Loading…
Reference in a new issue