This source file includes following definitions.
- WriteSeverityToStream
- WriteLocationToStream
- GetTraceTypeString
- PrintTimeStamp
- PrintEventContext
- PrintBadEvent
- OnUnknownEvent
- OnUnparsableEvent
- OnFileHeader
- OnLogMessage
- OnLogMessageFull
- OnTraceEvent
- PrintLogFile
#include "chrome/test/logging/win/log_file_printer.h"
#include <windows.h>
#include <objbase.h>
#include <iomanip>
#include <ios>
#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/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
#include "chrome/test/logging/win/log_file_reader.h"
namespace {
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;
}
}
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 << ')';
}
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;
}
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_ << "] ";
}
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=0x" << std::hex << id << std::dec << ") " << extra
<< std::endl;
}
}
void logging_win::PrintLogFile(const base::FilePath& log_file,
std::ostream* out) {
EventPrinter printer(out);
logging_win::ReadLogFile(log_file, &printer);
}