#include "logging.h" #include #include #include #include #include "tools.h" using std::string; using std::lock_guard; using boost::log::sinks::text_ostream_backend; using boost::log::record_view; using boost::log::sinks::unlocked_sink; namespace expr = boost::log::expressions; string toString(LogLevel level) { constexpr size_t levelCount = static_cast(LogLevel::EndSentinel); static const std::array strings = { "Trace", "Debug", "Info", "Warning", "Error", "Fatal" }; return strings.at(static_cast(level)); } PausableBackendAdapter::PausableBackendAdapter(boost::shared_ptr backend) : backend(backend) {} void PausableBackendAdapter::consume(const record_view& recordView, const string message) { lock_guard lock(mutex); if (isPaused) { buffer.push_back(std::make_tuple(recordView, message)); } else { backend->consume(recordView, message); } } void PausableBackendAdapter::pause() { lock_guard lock(mutex); isPaused = true; } void PausableBackendAdapter::resume() { lock_guard lock(mutex); isPaused = false; for (const auto& tuple : buffer) { backend->consume(std::get(tuple), std::get(tuple)); } buffer.clear(); } boost::shared_ptr initLogging() { // Create logging backend that logs to stderr auto streamBackend = boost::make_shared(); streamBackend->add_stream(boost::shared_ptr(&std::cerr, [](std::ostream*) {})); streamBackend->auto_flush(true); // Create an adapter that allows us to pause, buffer, and resume log output auto pausableAdapter = boost::make_shared(streamBackend); // Create a sink that feeds into the adapter auto sink = boost::make_shared>(pausableAdapter); // Set output formatting sink->set_formatter(expr::stream << "[" << expr::attr("Severity") << "] " << expr::smessage); boost::log::core::get()->add_sink(sink); return pausableAdapter; } void logTimedEvent(const string& eventName, centiseconds start, centiseconds end, const string& value) { LOG_DEBUG << "##" << eventName << "[" << formatDuration(start) << "-" << formatDuration(end) << "]: " << value; }