Commit 39ba84d4 authored by Joe Downing's avatar Joe Downing Committed by Commit Bot

[Windows][Host][Logging] Control event tracing via the registry

This CL adds a some logic to read registry key values to control
the logging state for the host.  I've also integrated the
EventTraceData class with the EtwTraceConsumer for parsing.

The WXS file creates the logging reg key but by default we don't
log anything.  If logging is enabled, then we will create the
ETW classes to control and consume the events.  Once we have
ensured that the functionality is stable and have worked out any
issues, we can consider whether to turn it on by default.

The next CL will add the file logging and event logging classes.
I'd like to land this first to keep the CLs small and get as much
in before branch point as possible.

Bug: 1144185
Change-Id: I5778e57651b6afc99819140c911c2ace79803d74
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2535011Reviewed-by: default avatarJamie Walch <jamiewalch@chromium.org>
Commit-Queue: Joe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826926}
parent 563743fa
...@@ -60,6 +60,15 @@ IPC::PlatformFileForTransit GetRegistryKeyForTransit( ...@@ -60,6 +60,15 @@ IPC::PlatformFileForTransit GetRegistryKeyForTransit(
return IPC::GetPlatformFileForTransit(handle, false); return IPC::GetPlatformFileForTransit(handle, false);
} }
#if defined(OFFICIAL_BUILD)
constexpr wchar_t kLoggingRegistryKeyName[] =
L"SOFTWARE\\Google\\Chrome Remote Desktop\\logging";
#else
constexpr wchar_t kLoggingRegistryKeyName[] = L"SOFTWARE\\Chromoting\\logging";
#endif
constexpr wchar_t kLoggingEnabledRegistryValue[] = L"EnableEventLogging";
} // namespace } // namespace
namespace remoting { namespace remoting {
...@@ -245,8 +254,7 @@ std::unique_ptr<DaemonProcess> DaemonProcess::Create( ...@@ -245,8 +254,7 @@ std::unique_ptr<DaemonProcess> DaemonProcess::Create(
caller_task_runner, io_task_runner, std::move(stopped_callback)); caller_task_runner, io_task_runner, std::move(stopped_callback));
// Initialize our ETW logger first so we can capture any subsequent events. // Initialize our ETW logger first so we can capture any subsequent events.
// TODO(joedow): Re-enable after we can control logging via the registry. daemon_process->StartEtwLogging();
// daemon_process->StartEtwLogging();
daemon_process->Initialize(); daemon_process->Initialize();
...@@ -398,12 +406,37 @@ bool DaemonProcessWin::OpenPairingRegistry() { ...@@ -398,12 +406,37 @@ bool DaemonProcessWin::OpenPairingRegistry() {
void DaemonProcessWin::StartEtwLogging() { void DaemonProcessWin::StartEtwLogging() {
DCHECK(!etw_trace_consumer_); DCHECK(!etw_trace_consumer_);
// TODO(joedow): Add some registry keys to control the behavior here. base::win::RegKey logging_reg_key;
// This will most likely include trace levels and output files/locations. LONG result = logging_reg_key.Open(HKEY_LOCAL_MACHINE,
kLoggingRegistryKeyName, KEY_READ);
if (result != ERROR_SUCCESS) {
::SetLastError(result);
PLOG(ERROR) << "Failed to open HKLM\\" << kLoggingRegistryKeyName;
return;
}
if (!logging_reg_key.HasValue(kLoggingEnabledRegistryValue)) {
VLOG(1) << "Event logging registry value does not exist. EtwTraceConsumer "
<< "not created.";
return;
}
DWORD enabled = 0;
result = logging_reg_key.ReadValueDW(kLoggingEnabledRegistryValue, &enabled);
if (result != ERROR_SUCCESS) {
::SetLastError(result);
PLOG(ERROR) << "Failed to read HKLM\\" << kLoggingRegistryKeyName << "\\"
<< kLoggingEnabledRegistryValue;
return;
}
if (!enabled) {
VLOG(1) << "Event logging is not enabled. EtwTraceConsumer not created.";
return;
}
etw_trace_consumer_ = EtwTraceConsumer::Create(AutoThread::CreateWithType( etw_trace_consumer_ = EtwTraceConsumer::Create(AutoThread::CreateWithType(
kEtwTracingThreadName, caller_task_runner(), base::MessagePumpType::IO)); kEtwTracingThreadName, caller_task_runner(), base::MessagePumpType::IO));
LOG_IF(ERROR, !etw_trace_consumer_) << "Failed to create EtwTraceConsumer.";
} }
} // namespace remoting } // namespace remoting
...@@ -503,7 +503,7 @@ ...@@ -503,7 +503,7 @@
<!-- Gives full access to SYSTEM only. --> <!-- Gives full access to SYSTEM only. -->
<!-- Cannot use the builtin PermissionEx element because it maps <!-- Cannot use the builtin PermissionEx element because it maps
to the MsiLockPermissionsEx table which is not supported on to the MsiLockPermissionsEx table which is not supported on
Windows Installer version 4.5 or lower. Also Cannot use Windows Installer version 4.5 or lower. Also cannot use
PermissionEx in WixUtilExtension because it automatically PermissionEx in WixUtilExtension because it automatically
inherits all the ACLs from the parent. --> inherits all the ACLs from the parent. -->
<Permission User="[WIX_ACCOUNT_LOCALSYSTEM]" <Permission User="[WIX_ACCOUNT_LOCALSYSTEM]"
...@@ -613,6 +613,15 @@ ...@@ -613,6 +613,15 @@
<CreateFolder/> <CreateFolder/>
</Component> </Component>
<Component Id="remoting_logging_registry"
Guid="b640a025-18dd-49b9-b26d-b31252a12f8a">
<RegistryKey Root="HKLM"
Key="SOFTWARE\$(var.ChromotingKeyPath)\logging"
Action="create">
</RegistryKey>
<CreateFolder/>
</Component>
<!-- Delete the usagestats flag to reset the crash dump reporting settings <!-- Delete the usagestats flag to reset the crash dump reporting settings
for existing users. --> for existing users. -->
<Component Id="delete_usagestats" <Component Id="delete_usagestats"
...@@ -731,6 +740,7 @@ ...@@ -731,6 +740,7 @@
<ComponentRef Id="remoting_desktop"/> <ComponentRef Id="remoting_desktop"/>
<ComponentRef Id="remoting_host"/> <ComponentRef Id="remoting_host"/>
<ComponentRef Id="remoting_lib"/> <ComponentRef Id="remoting_lib"/>
<ComponentRef Id="remoting_logging_registry"/>
<ComponentRef Id="remoting_pairing_registry"/> <ComponentRef Id="remoting_pairing_registry"/>
<ComponentRef Id="remoting_start_host"/> <ComponentRef Id="remoting_start_host"/>
<ComponentRef Id="sawbuck_provider"/> <ComponentRef Id="sawbuck_provider"/>
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "remoting/base/auto_thread_task_runner.h" #include "remoting/base/auto_thread_task_runner.h"
#include "remoting/host/logging.h" #include "remoting/host/logging.h"
#include "remoting/host/win/etw_trace_controller.h" #include "remoting/host/win/etw_trace_controller.h"
#include "remoting/host/win/event_trace_data.h"
namespace remoting { namespace remoting {
...@@ -40,7 +41,7 @@ class EtwTraceConsumerImpl : public EtwTraceConsumer { ...@@ -40,7 +41,7 @@ class EtwTraceConsumerImpl : public EtwTraceConsumer {
Core& operator=(const Core&) = delete; Core& operator=(const Core&) = delete;
~Core(); ~Core();
static VOID WINAPI ProcessEvent(PEVENT_TRACE event); static VOID WINAPI ProcessEvent(EVENT_TRACE* event);
bool Start(); bool Start();
void Stop(); void Stop();
...@@ -52,11 +53,11 @@ class EtwTraceConsumerImpl : public EtwTraceConsumer { ...@@ -52,11 +53,11 @@ class EtwTraceConsumerImpl : public EtwTraceConsumer {
private: private:
// Parses an event and passes it along to the delegate for processing. // Parses an event and passes it along to the delegate for processing.
void DispatchEvent(PEVENT_TRACE event); void DispatchEvent(EVENT_TRACE* event);
// Handlers which parse and log an ETW event. // Handlers which parse and log an ETW event.
void HandleFullMessage(PEVENT_TRACE event); void HandleFullMessage(const EventTraceData& data);
void HandleMessage(PEVENT_TRACE event); void HandleMessage(const EventTraceData& data);
static Core* instance_; static Core* instance_;
...@@ -74,7 +75,7 @@ class EtwTraceConsumerImpl : public EtwTraceConsumer { ...@@ -74,7 +75,7 @@ class EtwTraceConsumerImpl : public EtwTraceConsumer {
EtwTraceConsumerImpl::Core* EtwTraceConsumerImpl::Core::instance_ = nullptr; EtwTraceConsumerImpl::Core* EtwTraceConsumerImpl::Core::instance_ = nullptr;
// static // static
void EtwTraceConsumerImpl::Core::ProcessEvent(PEVENT_TRACE event) { void EtwTraceConsumerImpl::Core::ProcessEvent(EVENT_TRACE* event) {
// This method is called on the same thread as Consume(). // This method is called on the same thread as Consume().
EtwTraceConsumerImpl::Core* instance = instance_; EtwTraceConsumerImpl::Core* instance = instance_;
if (instance) { if (instance) {
...@@ -129,7 +130,7 @@ void EtwTraceConsumerImpl::Core::ConsumeEvents() { ...@@ -129,7 +130,7 @@ void EtwTraceConsumerImpl::Core::ConsumeEvents() {
Consume(); Consume();
} }
void EtwTraceConsumerImpl::Core::DispatchEvent(PEVENT_TRACE event) { void EtwTraceConsumerImpl::Core::DispatchEvent(EVENT_TRACE* event) {
// This method is called on the same thread as Consume(). // This method is called on the same thread as Consume().
DCHECK_CALLED_ON_VALID_THREAD(consume_thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(consume_thread_checker_);
if (!event) { if (!event) {
...@@ -141,23 +142,21 @@ void EtwTraceConsumerImpl::Core::DispatchEvent(PEVENT_TRACE event) { ...@@ -141,23 +142,21 @@ void EtwTraceConsumerImpl::Core::DispatchEvent(PEVENT_TRACE event) {
return; return;
} }
uint8_t event_type = event->Header.Class.Type; EventTraceData data = EventTraceData::Create(event);
if (event_type == logging::LOG_MESSAGE_FULL) { if (data.event_type == logging::LOG_MESSAGE_FULL) {
HandleFullMessage(event); HandleFullMessage(data);
} else if (event_type != logging::LOG_MESSAGE) { } else if (data.event_type == logging::LOG_MESSAGE) {
HandleMessage(event); HandleMessage(data);
} else {
NOTREACHED() << "Unknown event type.";
} }
} }
void EtwTraceConsumerImpl::Core::HandleFullMessage(PEVENT_TRACE event) { void EtwTraceConsumerImpl::Core::HandleFullMessage(const EventTraceData& data) {
// TODO(joedow): Implement parsing and logging for this event type. // TODO(joedow): Implement logging for this event type.
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
void EtwTraceConsumerImpl::Core::HandleMessage(PEVENT_TRACE event) { void EtwTraceConsumerImpl::Core::HandleMessage(const EventTraceData& data) {
// TODO(joedow): Implement parsing and logging for this event type. // TODO(joedow): Implement logging for this event type.
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
...@@ -208,6 +207,7 @@ std::unique_ptr<EtwTraceConsumer> EtwTraceConsumer::Create( ...@@ -208,6 +207,7 @@ std::unique_ptr<EtwTraceConsumer> EtwTraceConsumer::Create(
auto etw_trace_consumer = std::make_unique<EtwTraceConsumerImpl>(); auto etw_trace_consumer = std::make_unique<EtwTraceConsumerImpl>();
if (!etw_trace_consumer->StartLogging(task_runner)) { if (!etw_trace_consumer->StartLogging(task_runner)) {
LOG(ERROR) << "Failed to start EtwTraceConsumer instance.";
return nullptr; return nullptr;
} }
......
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