This source file includes following definitions.
- EnableProviders
- DisableProviders
- Initialize
- Initialize
- StartLogging
- StopLogging
#include "chrome/test/logging/win/file_logger.h"
#include <windows.h>
#include <guiddef.h>
#include <objbase.h>
#include <ios>
#include "base/debug/trace_event_win.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/logging_win.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/event_trace_consumer.h"
#include "base/win/registry.h"
namespace logging_win {
namespace {
const wchar_t kChromeTestSession[] = L"chrome_tests";
const GUID kChromeFrameProvider =
{ 0x562bfc3, 0x2550, 0x45b4,
{ 0xbd, 0x8e, 0xa3, 0x10, 0x58, 0x3d, 0x3a, 0x6f } };
const GUID kChromeTraceProviderName =
{ 0x7fe69228, 0x633e, 0x4f06,
{ 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } };
const GUID kChromeTestsProvider =
{ 0x81729947, 0xcd2a, 0x49e6,
{ 0x88, 0x85, 0x78, 0x54, 0x29, 0xf3, 0x39, 0xf5 } };
const struct {
const GUID* provider_name;
uint8 level;
uint32 flags;
} kProviders[] = {
{ &kChromeTraceProviderName, 255, 0 },
{ &kChromeFrameProvider, 255, 0 },
{ &kChromeTestsProvider, 255, 0 },
{ &base::debug::kChromeTraceProviderName, 255, 0 }
};
COMPILE_ASSERT((1 << arraysize(kProviders)) - 1 ==
FileLogger::kAllEventProviders,
size_of_kProviders_is_inconsistent_with_kAllEventProviders);
}
bool FileLogger::is_initialized_ = false;
FileLogger::FileLogger()
: event_provider_mask_() {
}
FileLogger::~FileLogger() {
if (is_logging()) {
LOG(ERROR)
<< __FUNCTION__ << " don't forget to call FileLogger::StopLogging()";
StopLogging();
}
is_initialized_ = false;
}
bool FileLogger::EnableProviders() {
bool result = (event_provider_mask_ == 0);
if (event_provider_mask_ & CHROME_TESTS_LOG_PROVIDER)
logging::LogEventProvider::Initialize(kChromeTestsProvider);
HRESULT hr = S_OK;
for (size_t i = 0; i < arraysize(kProviders); ++i) {
if (event_provider_mask_ & (1 << i)) {
hr = controller_.EnableProvider(*kProviders[i].provider_name,
kProviders[i].level,
kProviders[i].flags);
if (FAILED(hr)) {
LOG(ERROR) << "Failed to enable event provider " << i
<< "; hr=" << std::hex << hr;
} else {
result = true;
}
}
}
return result;
}
void FileLogger::DisableProviders() {
HRESULT hr = S_OK;
for (size_t i = 0; i < arraysize(kProviders); ++i) {
if (event_provider_mask_ & (1 << i)) {
hr = controller_.DisableProvider(*kProviders[i].provider_name);
LOG_IF(ERROR, FAILED(hr)) << "Failed to disable event provider "
<< i << "; hr=" << std::hex << hr;
}
}
if (event_provider_mask_ & CHROME_TESTS_LOG_PROVIDER)
logging::LogEventProvider::Uninitialize();
}
void FileLogger::Initialize() {
Initialize(kAllEventProviders);
}
void FileLogger::Initialize(uint32 event_provider_mask) {
CHECK(!is_initialized_);
base::win::EtwTraceProperties ignore;
HRESULT hr = base::win::EtwTraceController::Stop(kChromeTestSession,
&ignore);
LOG_IF(ERROR, FAILED(hr) &&
hr != HRESULT_FROM_WIN32(ERROR_WMI_INSTANCE_NOT_FOUND))
<< "Failed to stop a previous trace session; hr=" << std::hex << hr;
event_provider_mask_ = event_provider_mask;
is_initialized_ = true;
}
bool FileLogger::StartLogging(const base::FilePath& log_file) {
HRESULT hr =
controller_.StartFileSession(kChromeTestSession,
log_file.value().c_str(), false);
if (SUCCEEDED(hr)) {
if (!EnableProviders()) {
LOG(ERROR) << "Failed to enable any provider.";
controller_.Stop(NULL);
return false;
}
} else {
if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) {
LOG(WARNING) << "Access denied while trying to start trace session. "
"This is expected when not running as an administrator.";
} else {
LOG(ERROR) << "Failed to start trace session to file " << log_file.value()
<< "; hr=" << std::hex << hr;
}
return false;
}
return true;
}
void FileLogger::StopLogging() {
HRESULT hr = S_OK;
DisableProviders();
hr = controller_.Flush(NULL);
LOG_IF(ERROR, FAILED(hr))
<< "Failed to flush events; hr=" << std::hex << hr;
hr = controller_.Stop(NULL);
LOG_IF(ERROR, FAILED(hr))
<< "Failed to stop ETW session; hr=" << std::hex << hr;
}
}