Synchronize stdout & stderr for logging
This commit is contained in:
parent
85d7a0ca33
commit
04243db779
3 changed files with 83 additions and 2 deletions
15
libs/io/include/psemek/io/synchronized.hpp
Normal file
15
libs/io/include/psemek/io/synchronized.hpp
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/io/stream.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace psemek::io
|
||||||
|
{
|
||||||
|
|
||||||
|
// Convert a set of output streams to a set of mutually
|
||||||
|
// synchronized streams: writing to any of the streams
|
||||||
|
// flushes all the other streams
|
||||||
|
std::vector<std::unique_ptr<ostream>> synchronized(std::vector<std::unique_ptr<ostream>> streams);
|
||||||
|
|
||||||
|
}
|
||||||
60
libs/io/source/synchronized.cpp
Normal file
60
libs/io/source/synchronized.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
#include <psemek/io/synchronized.hpp>
|
||||||
|
|
||||||
|
namespace psemek::io
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct synchronized_stream_impl
|
||||||
|
: ostream
|
||||||
|
{
|
||||||
|
synchronized_stream_impl(std::shared_ptr<ostream> stream, std::vector<std::weak_ptr<ostream>> others)
|
||||||
|
: stream_(std::move(stream))
|
||||||
|
, others_(std::move(others))
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::size_t write(char const * p, std::size_t size) override
|
||||||
|
{
|
||||||
|
for (auto const & ptr : others_)
|
||||||
|
if (auto stream = ptr.lock())
|
||||||
|
stream->flush();
|
||||||
|
return stream_->write(p, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush() override
|
||||||
|
{
|
||||||
|
stream_->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<ostream> stream_;
|
||||||
|
std::vector<std::weak_ptr<ostream>> others_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a set of output streams to a set of mutually
|
||||||
|
// synchronized streams: writing to any of the streams
|
||||||
|
// flushes all the other streams
|
||||||
|
std::vector<std::unique_ptr<ostream>> synchronized(std::vector<std::unique_ptr<ostream>> streams)
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<ostream>> shared_streams(streams.size());
|
||||||
|
for (std::size_t i = 0; i < streams.size(); ++i)
|
||||||
|
shared_streams[i] = std::move(streams[i]);
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<ostream>> result;
|
||||||
|
for (std::size_t i = 0; i < streams.size(); ++i)
|
||||||
|
{
|
||||||
|
std::vector<std::weak_ptr<ostream>> others;
|
||||||
|
for (std::size_t j = 0; j < streams.size(); ++j)
|
||||||
|
if (i != j)
|
||||||
|
others.push_back(shared_streams[i]);
|
||||||
|
|
||||||
|
result.push_back(std::make_unique<synchronized_stream_impl>(shared_streams[i], std::move(others)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <psemek/util/clock.hpp>
|
#include <psemek/util/clock.hpp>
|
||||||
#include <psemek/util/pretty_print.hpp>
|
#include <psemek/util/pretty_print.hpp>
|
||||||
#include <psemek/log/log.hpp>
|
#include <psemek/log/log.hpp>
|
||||||
|
#include <psemek/io/synchronized.hpp>
|
||||||
#include <psemek/util/exception.hpp>
|
#include <psemek/util/exception.hpp>
|
||||||
|
|
||||||
#undef main
|
#undef main
|
||||||
|
|
@ -22,8 +23,13 @@ int main(int argc, char ** argv) try
|
||||||
log::level const stdio_log_level = log::level::debug;
|
log::level const stdio_log_level = log::level::debug;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
log::add_sink(log::default_sink(io::std_out(), stdio_log_level, log::level::info));
|
std::vector<std::unique_ptr<io::ostream>> synchronized_stdout_stderr;
|
||||||
log::add_sink(log::default_sink(io::std_err(), log::level::warning, log::level::error));
|
synchronized_stdout_stderr.push_back(io::std_out());
|
||||||
|
synchronized_stdout_stderr.push_back(io::std_err());
|
||||||
|
synchronized_stdout_stderr = io::synchronized(std::move(synchronized_stdout_stderr));
|
||||||
|
|
||||||
|
log::add_sink(log::default_sink(std::move(synchronized_stdout_stderr[0]), stdio_log_level, log::level::info));
|
||||||
|
log::add_sink(log::default_sink(std::move(synchronized_stdout_stderr[1]), log::level::warning, log::level::error));
|
||||||
log::register_thread("main");
|
log::register_thread("main");
|
||||||
|
|
||||||
auto const factory = app::make_application_factory();
|
auto const factory = app::make_application_factory();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue