diff --git a/src/base/log.cpp b/src/base/log.cpp index 989238007be..20b6af5e2c0 100644 --- a/src/base/log.cpp +++ b/src/base/log.cpp @@ -549,3 +549,38 @@ void CFutureLogger::OnFilterChange() pLogger->SetFilter(m_Filter); } } + +void CMemoryLogger::Log(const CLogMessage *pMessage) +{ + if(m_pParentLogger) + { + m_pParentLogger->Log(pMessage); + } + if(m_Filter.Filters(pMessage)) + { + return; + } + const CLockScope LockScope(m_MessagesMutex); + m_vMessages.push_back(*pMessage); +} + +std::vector CMemoryLogger::Lines() +{ + const CLockScope LockScope(m_MessagesMutex); + return m_vMessages; +} + +std::string CMemoryLogger::ConcatenatedLines() +{ + const CLockScope LockScope(m_MessagesMutex); + std::string Result; + for(const CLogMessage &Message : m_vMessages) + { + if(!Result.empty()) + { + Result += '\n'; + } + Result += Message.m_aLine; + } + return Result; +} diff --git a/src/base/logger.h b/src/base/logger.h index b43d0468c06..7365ba0b492 100644 --- a/src/base/logger.h +++ b/src/base/logger.h @@ -6,6 +6,7 @@ #include #include +#include #include typedef void *IOHANDLE; @@ -247,6 +248,30 @@ class CFutureLogger : public ILogger void OnFilterChange() override; }; +/** + * @ingroup Log + * + * Logger that collects messages in memory. This is useful to collect the log + * messages for a particular operation and show them in a user interface when + * the operation failed. Use only temporarily with @link CLogScope @endlink + * or it will result in excessive memory usage. + * + * Messages are also forwarded to the parent logger if it's set, regardless + * of this logger's filter. + */ +class CMemoryLogger : public ILogger +{ + ILogger *m_pParentLogger = nullptr; + std::vector m_vMessages GUARDED_BY(m_MessagesMutex); + CLock m_MessagesMutex; + +public: + void SetParent(ILogger *pParentLogger) { m_pParentLogger = pParentLogger; } + void Log(const CLogMessage *pMessage) override REQUIRES(!m_MessagesMutex); + std::vector Lines() REQUIRES(!m_MessagesMutex); + std::string ConcatenatedLines() REQUIRES(!m_MessagesMutex); +}; + /** * @ingroup Log *