15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/logging/win/log_file_reader.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event_win.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging_win.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/event_trace_consumer.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/logging/win/mof_data_parser.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace logging_win {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(grt) This reverses a mapping produced by base/logging_win.cc's
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LogEventProvider::LogMessage.  LogEventProvider should expose a way to map an
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// event level back to a log severity.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)logging::LogSeverity EventLevelToSeverity(uint8 level) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (level) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case TRACE_LEVEL_NONE:
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return logging::LOG_ERROR;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case TRACE_LEVEL_FATAL:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return logging::LOG_FATAL;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case TRACE_LEVEL_ERROR:
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return logging::LOG_ERROR;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case TRACE_LEVEL_WARNING:
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return logging::LOG_WARNING;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case TRACE_LEVEL_INFORMATION:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return logging::LOG_INFO;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Trace levels above information correspond to negative severity levels,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // which are used for VLOG verbosity levels.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRACE_LEVEL_INFORMATION - level;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(grt) This reverses a mapping produced by base/debug/trace_event_win.cc's
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceEventETWProvider::TraceEvent.  TraceEventETWProvider should expose a way
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to map an event type back to a trace type.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char EventTypeToTraceType(uint8 event_type) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event_type) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::debug::kTraceEventTypeBegin:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return TRACE_EVENT_PHASE_BEGIN;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::debug::kTraceEventTypeEnd:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return TRACE_EVENT_PHASE_END;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::debug::kTraceEventTypeInstant:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return TRACE_EVENT_PHASE_INSTANT;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return '\0';
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LogFileReader {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit LogFileReader(LogFileDelegate* delegate);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~LogFileReader();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void ReadFile(const base::FilePath& log_file,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       LogFileDelegate* delegate);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An implementation of a trace consumer that delegates to a given (at
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // compile-time) event processing function.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<void (*ProcessEventFn)(EVENT_TRACE*)>
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class TraceConsumer
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : public base::win::EtwTraceConsumerBase<TraceConsumer<ProcessEventFn> > {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TraceConsumer() { }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static void ProcessEvent(EVENT_TRACE* event) { (*ProcessEventFn)(event); }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(TraceConsumer);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delegates to DispatchEvent() of the current LogDumper instance.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void ProcessEvent(EVENT_TRACE* event);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handlers for the supported event types.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool OnLogMessageEvent(const EVENT_TRACE* event);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool OnLogMessageFullEvent(const EVENT_TRACE* event);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool OnTraceEvent(const EVENT_TRACE* event);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool OnFileHeader(const EVENT_TRACE* event);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parses an event and passes it along to the delegate for processing.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DispatchEvent(const EVENT_TRACE* event);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reads the file using a trace consumer.  |ProcessEvent| will be invoked for
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // each event in the file.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Read(const base::FilePath& log_file);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Protects use of the class; only one instance may be live at a time.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static base::LazyInstance<base::Lock>::Leaky reader_lock_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The currently living instance.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static LogFileReader* instance_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delegate to be notified of events.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogFileDelegate* delegate_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<base::Lock>::Leaky LogFileReader::reader_lock_ =
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LogFileReader* LogFileReader::instance_ = NULL;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LogFileReader::LogFileReader(LogFileDelegate* delegate)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : delegate_(delegate) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(instance_ == NULL);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate != NULL);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance_ = this;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LogFileReader::~LogFileReader() {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(instance_, this);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance_ = NULL;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LogFileReader::ProcessEvent(EVENT_TRACE* event) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (instance_ != NULL)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instance_->DispatchEvent(event);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LogFileReader::OnLogMessageEvent(const EVENT_TRACE* event) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::StringPiece message;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MofDataParser parser(event);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See LogEventProvider::LogMessage where ENABLE_LOG_MESSAGE_ONLY is set.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parser.ReadString(&message) && parser.empty()) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnLogMessage(event,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            EventLevelToSeverity(event->Header.Class.Level),
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            message);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LogFileReader::OnLogMessageFullEvent(const EVENT_TRACE* event) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD stack_depth = 0;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const intptr_t* backtrace = NULL;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int line = 0;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::StringPiece file;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::StringPiece message;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MofDataParser parser(event);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See LogEventProvider::LogMessage where ENABLE_LOG_MESSAGE_ONLY is not set.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parser.ReadDWORD(&stack_depth) &&
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parser.ReadPointerArray(stack_depth, &backtrace) &&
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parser.ReadInt(&line) &&
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parser.ReadString(&file) &&
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parser.ReadString(&message) &&
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parser.empty()) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnLogMessageFull(event,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EventLevelToSeverity(event->Header.Class.Level), stack_depth, backtrace,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        line, file, message);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LogFileReader::OnTraceEvent(const EVENT_TRACE* event) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MofDataParser parser(event);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::StringPiece name;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  intptr_t id = 0;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::StringPiece extra;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD stack_depth = 0;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const intptr_t* backtrace = NULL;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See TraceEventETWProvider::TraceEvent.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parser.ReadString(&name) &&
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parser.ReadPointer(&id) &&
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parser.ReadString(&extra) &&
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (parser.empty() ||
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       parser.ReadDWORD(&stack_depth) &&
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       parser.ReadPointerArray(stack_depth, &backtrace) &&
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       parser.empty())) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnTraceEvent(event, name,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EventTypeToTraceType(event->Header.Class.Type), id, extra, stack_depth,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        backtrace);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LogFileReader::OnFileHeader(const EVENT_TRACE* event) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MofDataParser parser(event);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TRACE_LOGFILE_HEADER* header = NULL;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parser.ReadStructure(&header)) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnFileHeader(event, header);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LogFileReader::DispatchEvent(const EVENT_TRACE* event) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool parsed = true;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsEqualGUID(event->Header.Guid, logging::kLogEventId)) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->Header.Class.Type == logging::LOG_MESSAGE)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parsed = OnLogMessageEvent(event);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (event->Header.Class.Type == logging::LOG_MESSAGE_FULL)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parsed = OnLogMessageFullEvent(event);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (IsEqualGUID(event->Header.Guid, base::debug::kTraceEventClass32)) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed = OnTraceEvent(event);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (IsEqualGUID(event->Header.Guid, EventTraceGuid)) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed = OnFileHeader(event);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(parsed);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnUnknownEvent(event);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!parsed)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnUnparsableEvent(event);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LogFileReader::Read(const base::FilePath& log_file) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceConsumer<&ProcessEvent> consumer;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = S_OK;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = consumer.OpenFileSession(log_file.value().c_str());
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr)) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to open session for log file " << log_file.value()
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "; hr=" << std::hex << hr;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    consumer.Consume();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    consumer.Close();
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LogFileReader::ReadFile(const base::FilePath& log_file,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LogFileDelegate* delegate) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(reader_lock_.Get());
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogFileReader(delegate).Read(log_file);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LogFileDelegate::LogFileDelegate() {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LogFileDelegate::~LogFileDelegate() {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReadLogFile(const base::FilePath& log_file, LogFileDelegate* delegate) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogFileReader::ReadFile(log_file, delegate);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // logging_win
263