Commit 8a4d8066 authored by Yuwei Huang's avatar Yuwei Huang Committed by Commit Bot

[CRD iOS] Store logs in memory

The iOS logger by default will only write logs to OSLog. However, there
is no API for us to retrieve logs sent to OSLog.

This CL implements a log handler to store logs in memory before they
get printed out.

Bug: 814863
Change-Id: Ic7f30df45f3879370e2e9d93ef771f10df4dbeb3
Reviewed-on: https://chromium-review.googlesource.com/933364
Commit-Queue: Yuwei Huang <yuweih@chromium.org>
Reviewed-by: default avatarJoe Downing <joedow@chromium.org>
Reviewed-by: default avatarJamie Walch <jamiewalch@chromium.org>
Cr-Commit-Position: refs/heads/master@{#538998}
parent 256ae53c
...@@ -21,6 +21,8 @@ static_library("client") { ...@@ -21,6 +21,8 @@ static_library("client") {
"empty_cursor_filter.h", "empty_cursor_filter.h",
"host_experiment_sender.cc", "host_experiment_sender.cc",
"host_experiment_sender.h", "host_experiment_sender.h",
"in_memory_log_handler.cc",
"in_memory_log_handler.h",
"queued_task_poster.cc", "queued_task_poster.cc",
"queued_task_poster.h", "queued_task_poster.h",
"software_video_renderer.cc", "software_video_renderer.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/client/in_memory_log_handler.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;
};
// Leaky.
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);
// Pass log messages through the default logging pipeline.
return false;
}
} // namespace
// static
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);
}
// static
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';
}
// *iter returns a const std::string*.
output += **iter;
}
return output;
}
} // namespace remoting
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_CLIENT_IN_MEMORY_LOG_HANDLER_H_
#define REMOTING_CLIENT_IN_MEMORY_LOG_HANDLER_H_
#include <string>
#include "base/macros.h"
namespace remoting {
// Class for capturing logs in memory before printing out.
class InMemoryLogHandler {
public:
// Registers the log handler. This is not thread safe and should be called
// exactly once in the main function.
static void Register();
// Returns most recently captured logs (#lines <= kMaxNumberOfLogs) since the
// app is launched. This must be called after Register() is called.
static std::string GetInMemoryLogs();
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(InMemoryLogHandler);
};
} // namespace remoting
#endif // REMOTING_CLIENT_IN_MEMORY_LOG_HANDLER_H_
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/at_exit.h" #include "base/at_exit.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/i18n/icu_util.h" #include "base/i18n/icu_util.h"
#include "remoting/client/in_memory_log_handler.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
...@@ -28,6 +29,8 @@ int main(int argc, char* argv[]) { ...@@ -28,6 +29,8 @@ int main(int argc, char* argv[]) {
// Required to find the ICU data file, used by some file_util routines. // Required to find the ICU data file, used by some file_util routines.
base::i18n::InitializeICU(); base::i18n::InitializeICU();
remoting::InMemoryLogHandler::Register();
#ifdef DEBUG #ifdef DEBUG
// Set min log level for debug builds. For some reason this has to be // Set min log level for debug builds. For some reason this has to be
// negative. // negative.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment