Wed, 31 Dec 2014 07:16:47 +0100
Revert simplistic fix pending revisit of Mozilla integration attempt.
michael@0 | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
michael@0 | 2 | // Use of this source code is governed by a BSD-style license that can be |
michael@0 | 3 | // found in the LICENSE file. |
michael@0 | 4 | |
michael@0 | 5 | #include "base/logging_win.h" |
michael@0 | 6 | #include "base/memory/singleton.h" |
michael@0 | 7 | #include <initguid.h> // NOLINT |
michael@0 | 8 | |
michael@0 | 9 | namespace logging { |
michael@0 | 10 | |
michael@0 | 11 | using base::win::EtwEventLevel; |
michael@0 | 12 | using base::win::EtwMofEvent; |
michael@0 | 13 | |
michael@0 | 14 | DEFINE_GUID(kLogEventId, |
michael@0 | 15 | 0x7fe69228, 0x633e, 0x4f06, 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7); |
michael@0 | 16 | |
michael@0 | 17 | LogEventProvider::LogEventProvider() : old_log_level_(LOG_NONE) { |
michael@0 | 18 | } |
michael@0 | 19 | |
michael@0 | 20 | LogEventProvider* LogEventProvider::GetInstance() { |
michael@0 | 21 | return Singleton<LogEventProvider, |
michael@0 | 22 | StaticMemorySingletonTraits<LogEventProvider> >::get(); |
michael@0 | 23 | } |
michael@0 | 24 | |
michael@0 | 25 | bool LogEventProvider::LogMessage(logging::LogSeverity severity, |
michael@0 | 26 | const char* file, int line, size_t message_start, |
michael@0 | 27 | const std::string& message) { |
michael@0 | 28 | EtwEventLevel level = TRACE_LEVEL_NONE; |
michael@0 | 29 | |
michael@0 | 30 | // Convert the log severity to the most appropriate ETW trace level. |
michael@0 | 31 | if (severity >= 0) { |
michael@0 | 32 | switch (severity) { |
michael@0 | 33 | case LOG_INFO: |
michael@0 | 34 | level = TRACE_LEVEL_INFORMATION; |
michael@0 | 35 | break; |
michael@0 | 36 | case LOG_WARNING: |
michael@0 | 37 | level = TRACE_LEVEL_WARNING; |
michael@0 | 38 | break; |
michael@0 | 39 | case LOG_ERROR: |
michael@0 | 40 | case LOG_ERROR_REPORT: |
michael@0 | 41 | level = TRACE_LEVEL_ERROR; |
michael@0 | 42 | break; |
michael@0 | 43 | case LOG_FATAL: |
michael@0 | 44 | level = TRACE_LEVEL_FATAL; |
michael@0 | 45 | break; |
michael@0 | 46 | } |
michael@0 | 47 | } else { // severity < 0 is VLOG verbosity levels. |
michael@0 | 48 | level = TRACE_LEVEL_INFORMATION - severity; |
michael@0 | 49 | } |
michael@0 | 50 | |
michael@0 | 51 | // Bail if we're not logging, not at that level, |
michael@0 | 52 | // or if we're post-atexit handling. |
michael@0 | 53 | LogEventProvider* provider = LogEventProvider::GetInstance(); |
michael@0 | 54 | if (provider == NULL || level > provider->enable_level()) |
michael@0 | 55 | return false; |
michael@0 | 56 | |
michael@0 | 57 | // And now log the event. |
michael@0 | 58 | if (provider->enable_flags() & ENABLE_LOG_MESSAGE_ONLY) { |
michael@0 | 59 | EtwMofEvent<1> event(kLogEventId, LOG_MESSAGE, level); |
michael@0 | 60 | event.SetField(0, message.length() + 1 - message_start, |
michael@0 | 61 | message.c_str() + message_start); |
michael@0 | 62 | |
michael@0 | 63 | provider->Log(event.get()); |
michael@0 | 64 | } else { |
michael@0 | 65 | const size_t kMaxBacktraceDepth = 32; |
michael@0 | 66 | void* backtrace[kMaxBacktraceDepth]; |
michael@0 | 67 | DWORD depth = 0; |
michael@0 | 68 | |
michael@0 | 69 | // Capture a stack trace if one is requested. |
michael@0 | 70 | // requested per our enable flags. |
michael@0 | 71 | if (provider->enable_flags() & ENABLE_STACK_TRACE_CAPTURE) |
michael@0 | 72 | depth = CaptureStackBackTrace(2, kMaxBacktraceDepth, backtrace, NULL); |
michael@0 | 73 | |
michael@0 | 74 | EtwMofEvent<5> event(kLogEventId, LOG_MESSAGE_FULL, level); |
michael@0 | 75 | if (file == NULL) |
michael@0 | 76 | file = ""; |
michael@0 | 77 | |
michael@0 | 78 | // Add the stack trace. |
michael@0 | 79 | event.SetField(0, sizeof(depth), &depth); |
michael@0 | 80 | event.SetField(1, sizeof(backtrace[0]) * depth, &backtrace); |
michael@0 | 81 | // The line. |
michael@0 | 82 | event.SetField(2, sizeof(line), &line); |
michael@0 | 83 | // The file. |
michael@0 | 84 | event.SetField(3, strlen(file) + 1, file); |
michael@0 | 85 | // And finally the message. |
michael@0 | 86 | event.SetField(4, message.length() + 1 - message_start, |
michael@0 | 87 | message.c_str() + message_start); |
michael@0 | 88 | |
michael@0 | 89 | provider->Log(event.get()); |
michael@0 | 90 | } |
michael@0 | 91 | |
michael@0 | 92 | // Don't increase verbosity in other log destinations. |
michael@0 | 93 | if (severity < provider->old_log_level_) |
michael@0 | 94 | return true; |
michael@0 | 95 | |
michael@0 | 96 | return false; |
michael@0 | 97 | } |
michael@0 | 98 | |
michael@0 | 99 | void LogEventProvider::Initialize(const GUID& provider_name) { |
michael@0 | 100 | LogEventProvider* provider = LogEventProvider::GetInstance(); |
michael@0 | 101 | |
michael@0 | 102 | provider->set_provider_name(provider_name); |
michael@0 | 103 | provider->Register(); |
michael@0 | 104 | |
michael@0 | 105 | // Register our message handler with logging. |
michael@0 | 106 | SetLogMessageHandler(LogMessage); |
michael@0 | 107 | } |
michael@0 | 108 | |
michael@0 | 109 | void LogEventProvider::Uninitialize() { |
michael@0 | 110 | LogEventProvider::GetInstance()->Unregister(); |
michael@0 | 111 | } |
michael@0 | 112 | |
michael@0 | 113 | void LogEventProvider::OnEventsEnabled() { |
michael@0 | 114 | // Grab the old log level so we can restore it later. |
michael@0 | 115 | old_log_level_ = GetMinLogLevel(); |
michael@0 | 116 | |
michael@0 | 117 | // Convert the new trace level to a logging severity |
michael@0 | 118 | // and enable logging at that level. |
michael@0 | 119 | EtwEventLevel level = enable_level(); |
michael@0 | 120 | if (level == TRACE_LEVEL_NONE || level == TRACE_LEVEL_FATAL) { |
michael@0 | 121 | SetMinLogLevel(LOG_FATAL); |
michael@0 | 122 | } else if (level == TRACE_LEVEL_ERROR) { |
michael@0 | 123 | SetMinLogLevel(LOG_ERROR); |
michael@0 | 124 | } else if (level == TRACE_LEVEL_WARNING) { |
michael@0 | 125 | SetMinLogLevel(LOG_WARNING); |
michael@0 | 126 | } else if (level == TRACE_LEVEL_INFORMATION) { |
michael@0 | 127 | SetMinLogLevel(LOG_INFO); |
michael@0 | 128 | } else if (level >= TRACE_LEVEL_VERBOSE) { |
michael@0 | 129 | // Above INFO, we enable verbose levels with negative severities. |
michael@0 | 130 | SetMinLogLevel(TRACE_LEVEL_INFORMATION - level); |
michael@0 | 131 | } |
michael@0 | 132 | } |
michael@0 | 133 | |
michael@0 | 134 | void LogEventProvider::OnEventsDisabled() { |
michael@0 | 135 | // Restore the old log level. |
michael@0 | 136 | SetMinLogLevel(old_log_level_); |
michael@0 | 137 | } |
michael@0 | 138 | |
michael@0 | 139 | } // namespace logging |