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/pretty_print.hpp>
|
||||
#include <psemek/log/log.hpp>
|
||||
#include <psemek/io/synchronized.hpp>
|
||||
#include <psemek/util/exception.hpp>
|
||||
|
||||
#undef main
|
||||
|
|
@ -22,8 +23,13 @@ int main(int argc, char ** argv) try
|
|||
log::level const stdio_log_level = log::level::debug;
|
||||
#endif
|
||||
|
||||
log::add_sink(log::default_sink(io::std_out(), stdio_log_level, log::level::info));
|
||||
log::add_sink(log::default_sink(io::std_err(), log::level::warning, log::level::error));
|
||||
std::vector<std::unique_ptr<io::ostream>> synchronized_stdout_stderr;
|
||||
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");
|
||||
|
||||
auto const factory = app::make_application_factory();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue