Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8320)

Unified Diff: chrome/test/logging/win/log_file_printer.cc

Issue 9584017: New test infrastructure for producing verbose logs in failing tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: moved logging_win to logging/win so regular filename_rules work Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/test/logging/win/log_file_printer.h ('k') | chrome/test/logging/win/log_file_reader.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/test/logging/win/log_file_printer.cc
diff --git a/chrome/test/logging/win/log_file_printer.cc b/chrome/test/logging/win/log_file_printer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..02d525511e426745087d26c67da902de6abb012b
--- /dev/null
+++ b/chrome/test/logging/win/log_file_printer.cc
@@ -0,0 +1,248 @@
+// Copyright (c) 2012 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 "chrome/test/logging/win/log_file_printer.h"
+
+#include <windows.h>
+#include <objbase.h>
+
+#include <ios>
+#include <iomanip>
+#include <ostream>
+#include <sstream>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/debug/trace_event.h"
+#include "base/logging.h"
+#include "base/string_number_conversions.h"
+#include "base/string_piece.h"
+#include "base/time.h"
+#include "chrome/test/logging/win/log_file_reader.h"
+
+namespace {
+
+// TODO(grt) This duplicates private behavior in base/logging.cc's
+// LogMessage::Init. That behavior should be exposed and used here (possibly
+// by moving this function to logging.cc, making it use log_severity_names, and
+// publishing it in logging.h with BASE_EXPORT).
+void WriteSeverityToStream(logging::LogSeverity severity, std::ostream* out) {
+ switch (severity) {
+ case logging::LOG_INFO:
+ *out << "INFO";
+ break;
+ case logging::LOG_WARNING:
+ *out << "WARNING";
+ break;
+ case logging::LOG_ERROR:
+ *out << "ERROR";
+ break;
+ case logging::LOG_ERROR_REPORT:
+ *out << "ERROR_REPORT";
+ break;
+ case logging::LOG_FATAL:
+ *out << "FATAL";
+ break;
+ default:
+ if (severity < 0)
+ *out << "VERBOSE" << -severity;
+ else
+ NOTREACHED();
+ break;
+ }
+}
+
+// TODO(grt) This duplicates private behavior in base/logging.cc's
+// LogMessage::Init. That behavior should be exposed and used here (possibly
+// by moving this function to logging.cc and publishing it in logging.h with
+// BASE_EXPORT).
+void WriteLocationToStream(const base::StringPiece& file,
+ int line,
+ std::ostream* out) {
+ base::StringPiece filename(file);
+ size_t last_slash_pos = filename.find_last_of("\\/");
+ if (last_slash_pos != base::StringPiece::npos)
+ filename.remove_prefix(last_slash_pos + 1);
+
+ *out << filename << '(' << line << ')';
+}
+
+// Returns a pretty string for the trace event types that appear in ETW logs.
+const char* GetTraceTypeString(char event_type) {
+ switch (event_type) {
+ case TRACE_EVENT_PHASE_BEGIN:
+ return "BEGIN";
+ break;
+ case TRACE_EVENT_PHASE_END:
+ return "END";
+ break;
+ case TRACE_EVENT_PHASE_INSTANT:
+ return "INSTANT";
+ break;
+ default:
+ NOTREACHED();
+ return "";
+ break;
+ }
+}
+
+class EventPrinter : public logging_win::LogFileDelegate {
+ public:
+ explicit EventPrinter(std::ostream* out);
+ virtual ~EventPrinter();
+
+ virtual void OnUnknownEvent(const EVENT_TRACE* event) OVERRIDE;
+
+ virtual void OnUnparsableEvent(const EVENT_TRACE* event) OVERRIDE;
+
+ virtual void OnFileHeader(const EVENT_TRACE* event,
+ const TRACE_LOGFILE_HEADER* header) OVERRIDE;
+
+ virtual void OnLogMessage(const EVENT_TRACE* event,
+ logging::LogSeverity severity,
+ const base::StringPiece& message) OVERRIDE;
+
+ virtual void OnLogMessageFull(const EVENT_TRACE* event,
+ logging::LogSeverity severity,
+ DWORD stack_depth,
+ const intptr_t* backtrace,
+ int line,
+ const base::StringPiece& file,
+ const base::StringPiece& message) OVERRIDE;
+
+ virtual void OnTraceEvent(const EVENT_TRACE* event,
+ const base::StringPiece& name,
+ char type,
+ intptr_t id,
+ const base::StringPiece& extra,
+ DWORD stack_depth,
+ const intptr_t* backtrace) OVERRIDE;
+
+ private:
+ void PrintTimeStamp(LARGE_INTEGER time_stamp);
+ void PrintEventContext(const EVENT_TRACE* event,
+ const base::StringPiece& level,
+ const base::StringPiece& context);
+ void PrintBadEvent(const EVENT_TRACE* event, const base::StringPiece& error);
+
+ std::ostream* out_;
+ DISALLOW_COPY_AND_ASSIGN(EventPrinter);
+};
+
+EventPrinter::EventPrinter(std::ostream* out)
+ : out_(out) {
+}
+
+EventPrinter::~EventPrinter() {
+}
+
+void EventPrinter::PrintTimeStamp(LARGE_INTEGER time_stamp) {
+ FILETIME event_time = {};
+ base::Time::Exploded time_exploded = {};
+ event_time.dwLowDateTime = time_stamp.LowPart;
+ event_time.dwHighDateTime = time_stamp.HighPart;
+ base::Time::FromFileTime(event_time).LocalExplode(&time_exploded);
+
+ *out_ << std::setfill('0')
+ << std::setw(2) << time_exploded.month
+ << std::setw(2) << time_exploded.day_of_month
+ << '/'
+ << std::setw(2) << time_exploded.hour
+ << std::setw(2) << time_exploded.minute
+ << std::setw(2) << time_exploded.second
+ << '.'
+ << std::setw(3) << time_exploded.millisecond;
+}
+
+// Prints the context info at the start of each line: pid, tid, time, etc.
+void EventPrinter::PrintEventContext(const EVENT_TRACE* event,
+ const base::StringPiece& level,
+ const base::StringPiece& context) {
+ *out_ << '[' << event->Header.ProcessId << ':'
+ << event->Header.ThreadId << ':';
+ PrintTimeStamp(event->Header.TimeStamp);
+ if (!level.empty())
+ *out_ << ':' << level;
+ if (!context.empty())
+ *out_ << ':' << context;
+ *out_ << "] ";
+}
+
+// Prints a useful message for events that can't be otherwise printed.
+void EventPrinter::PrintBadEvent(const EVENT_TRACE* event,
+ const base::StringPiece& error) {
+ wchar_t guid[64];
+ StringFromGUID2(event->Header.Guid, &guid[0], arraysize(guid));
+ *out_ << error << " (class=" << guid << ", type="
+ << static_cast<int>(event->Header.Class.Type) << ")";
+}
+
+void EventPrinter::OnUnknownEvent(const EVENT_TRACE* event) {
+ base::StringPiece empty;
+ PrintEventContext(event, empty, empty);
+ PrintBadEvent(event, "unsupported event");
+}
+
+void EventPrinter::OnUnparsableEvent(const EVENT_TRACE* event) {
+ base::StringPiece empty;
+ PrintEventContext(event, empty, empty);
+ PrintBadEvent(event, "parse error");
+}
+
+void EventPrinter::OnFileHeader(const EVENT_TRACE* event,
+ const TRACE_LOGFILE_HEADER* header) {
+ base::StringPiece empty;
+ PrintEventContext(event, empty, empty);
+
+ *out_ << "Log captured from Windows "
+ << static_cast<int>(header->VersionDetail.MajorVersion) << '.'
+ << static_cast<int>(header->VersionDetail.MinorVersion) << '.'
+ << static_cast<int>(header->VersionDetail.SubVersion) << '.'
+ << static_cast<int>(header->VersionDetail.SubMinorVersion)
+ << ". " << header->EventsLost << " events lost, "
+ << header->BuffersLost << " buffers lost." << std::endl;
+}
+
+void EventPrinter::OnLogMessage(const EVENT_TRACE* event,
+ logging::LogSeverity severity,
+ const base::StringPiece& message) {
+ std::ostringstream level_stream;
+ WriteSeverityToStream(severity, &level_stream);
+ PrintEventContext(event, level_stream.str(), base::StringPiece());
+ *out_ << message << std::endl;
+}
+
+void EventPrinter::OnLogMessageFull(const EVENT_TRACE* event,
+ logging::LogSeverity severity,
+ DWORD stack_depth,
+ const intptr_t* backtrace,
+ int line,
+ const base::StringPiece& file,
+ const base::StringPiece& message) {
+ std::ostringstream level_stream;
+ std::ostringstream location_stream;
+ WriteSeverityToStream(severity, &level_stream);
+ WriteLocationToStream(file, line, &location_stream);
+ PrintEventContext(event, level_stream.str(), location_stream.str());
+ *out_ << message << std::endl;
+}
+
+void EventPrinter::OnTraceEvent(const EVENT_TRACE* event,
+ const base::StringPiece& name,
+ char type,
+ intptr_t id,
+ const base::StringPiece& extra,
+ DWORD stack_depth,
+ const intptr_t* backtrace) {
+ PrintEventContext(event, GetTraceTypeString(type), base::StringPiece());
+ *out_ << name << " (id=" << std::hex << id << ") " << extra << std::endl;
+}
+
+} // namespace
+
+void logging_win::PrintLogFile(const FilePath& log_file,
+ std::ostream* out) {
+ EventPrinter printer(out);
+ logging_win::ReadLogFile(log_file, &printer);
+}
« no previous file with comments | « chrome/test/logging/win/log_file_printer.h ('k') | chrome/test/logging/win/log_file_reader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698