#include "remoting/client/in_memory_log_handler.h"
#include "base/check.h"
#include "base/containers/ring_buffer.h"
#include "base/logging.h"
#include "base/synchronization/lock.h"
namespace remoting {
namespace {
constexpr size_t kMaxNumberOfLogs = 1000;
struct LogHandlerContext {
base::Lock lock;
base::RingBuffer<std::string, kMaxNumberOfLogs> buffer;
};
LogHandlerContext* g_log_handler_context = nullptr;
bool HandleLogMessage(int severity,
const char* file,
int line,
size_t message_start,
const std::string& str) {
base::AutoLock auto_lock(g_log_handler_context->lock);
g_log_handler_context->buffer.SaveToBuffer(str);
return false;
}
}
void InMemoryLogHandler::Register() {
DCHECK(!g_log_handler_context);
DCHECK(!logging::GetLogMessageHandler())
<< "Log message handler has already been set.";
g_log_handler_context = new LogHandlerContext();
base::AutoLock auto_lock(g_log_handler_context->lock);
logging::SetLogMessageHandler(&HandleLogMessage);
}
std::string InMemoryLogHandler::GetInMemoryLogs() {
std::string output;
base::AutoLock auto_lock(g_log_handler_context->lock);
for (auto iter = g_log_handler_context->buffer.Begin(); iter; ++iter) {
if (iter != g_log_handler_context->buffer.Begin()) {
output += '\n';
}
output += **iter;
}
return output;
}
}