diff --git a/components/debug/debugging.cpp b/components/debug/debugging.cpp index 13a72c34dc..f828bfae62 100644 --- a/components/debug/debugging.cpp +++ b/components/debug/debugging.cpp @@ -223,6 +223,14 @@ namespace Debug namespace { + struct Record + { + std::string mValue; + Level mLevel; + }; + + std::vector globalBuffer; + Color getColor(Level level) { switch (level) @@ -303,6 +311,23 @@ namespace Debug bool mUseColor; }; + class Buffer + { + public: + explicit Buffer(std::vector& buffer) + : mBuffer(buffer) + { + } + + void write(const char* str, std::streamsize size, Level debugLevel) + { + mBuffer.push_back(Record{ std::string(str, size), debugLevel }); + } + + private: + std::vector& mBuffer; + }; + template class Tee : public DebugOutputBase { @@ -337,8 +362,10 @@ static std::ofstream logfile; #if defined(_WIN32) && defined(_DEBUG) static boost::iostreams::stream_buffer sb; #else -static boost::iostreams::stream_buffer> coutsb; -static boost::iostreams::stream_buffer> cerrsb; +static boost::iostreams::stream_buffer> standardOut; +static boost::iostreams::stream_buffer> standardErr; +static boost::iostreams::stream_buffer> bufferedOut; +static boost::iostreams::stream_buffer> bufferedErr; #endif std::ostream& getRawStdout() @@ -359,20 +386,22 @@ Misc::Locked getLockedRawStderr() // Redirect cout and cerr to the log file void setupLogging(const std::filesystem::path& logDir, std::string_view appName, std::ios_base::openmode mode) { -#if defined(_WIN32) && defined(_DEBUG) - // Redirect cout and cerr to VS debug output when running in debug mode - sb.open(Debug::DebugOutput()); - std::cout.rdbuf(&sb); - std::cerr.rdbuf(&sb); -#else +#if !(defined(_WIN32) && defined(_DEBUG)) const std::string logName = Misc::StringUtils::lowerCase(appName) + ".log"; logfile.open(logDir / logName, mode); - coutsb.open(Debug::Tee(Debug::Identity(logfile), Debug::Coloured(*rawStdout))); - cerrsb.open(Debug::Tee(Debug::Identity(logfile), Debug::Coloured(*rawStderr))); + Debug::Identity log(logfile); - std::cout.rdbuf(&coutsb); - std::cerr.rdbuf(&cerrsb); + for (const Debug::Record& v : Debug::globalBuffer) + log.write(v.mValue.data(), v.mValue.size(), v.mLevel); + + Debug::globalBuffer.clear(); + + standardOut.open(Debug::Tee(log, Debug::Coloured(*rawStdout))); + standardErr.open(Debug::Tee(log, Debug::Coloured(*rawStderr))); + + std::cout.rdbuf(&standardOut); + std::cerr.rdbuf(&standardErr); #endif #ifdef _WIN32 @@ -392,6 +421,19 @@ int wrapApplication(int (*innerApplication)(int argc, char* argv[]), int argc, c rawStderr = std::make_unique(std::cerr.rdbuf()); rawStderrMutex = std::make_unique(); +#if defined(_WIN32) && defined(_DEBUG) + // Redirect cout and cerr to VS debug output when running in debug mode + sb.open(Debug::DebugOutput()); + std::cout.rdbuf(&sb); + std::cerr.rdbuf(&sb); +#else + bufferedOut.open(Debug::Tee(Debug::Buffer(Debug::globalBuffer), Debug::Coloured(*rawStdout))); + bufferedErr.open(Debug::Tee(Debug::Buffer(Debug::globalBuffer), Debug::Coloured(*rawStderr))); + + std::cout.rdbuf(&bufferedOut); + std::cerr.rdbuf(&bufferedErr); +#endif + int ret = 0; try {