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

Side by Side Diff: content/browser/tracing/tracing_consumer_win.cc

Issue 171143002: Implements Windows system tracing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@tracing
Patch Set: rebase on ToT Created 6 years, 10 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/tracing/tracing_consumer_win.h"
6
7 #include "base/base64.h"
8 #include "base/lazy_instance.h"
9 #include "base/json/json_string_value_serializer.h"
10 #include "base/strings/stringprintf.h"
11 #include "content/public/browser/browser_thread.h"
12
13 namespace content {
14
15 namespace {
16
17 const int kEtwBufferSizeInKBytes = 16;
18 const int kEtwBufferFlushTimeoutInSeconds = 1;
19
20 std::string GuidToString(const GUID& guid) {
21 return base::StringPrintf("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
22 guid.Data1, guid.Data2, guid.Data3,
23 guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
24 guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
25 }
26
27 base::LazyInstance<EtwSystemEventConsumer>::Leaky g_etw_consumer =
28 LAZY_INSTANCE_INITIALIZER;
29
30 } // namespace
31
32 EtwSystemEventConsumer::EtwSystemEventConsumer()
33 : thread_("EtwConsumerThread") {
34 thread_.Start();
35 }
36
37 bool EtwSystemEventConsumer::StartKernelSessionTracing() {
nduca 2014/02/20 07:04:54 lets match the class name of this to the file, so
etienneb 2014/02/20 19:08:03 Done.
38 // Enabled flags (tracing facilities).
39 uint32 enabled_flags = EVENT_TRACE_FLAG_IMAGE_LOAD |
40 EVENT_TRACE_FLAG_PROCESS |
41 EVENT_TRACE_FLAG_THREAD |
42 EVENT_TRACE_FLAG_CSWITCH;
43
44 EVENT_TRACE_PROPERTIES& p = *properties_.get();
45 p.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
46 p.FlushTimer = kEtwBufferFlushTimeoutInSeconds;
47 p.BufferSize = kEtwBufferSizeInKBytes;
48 p.LogFileNameOffset = 0;
49 p.EnableFlags = enabled_flags;
50
51 HRESULT hr = base::win::EtwTraceController::Start(
52 KERNEL_LOGGER_NAME, &properties_, &session_handle_);
53 if (FAILED(hr)) {
54 VLOG(1) << "StartRealtimeSession() failed with " << hr << ".";
55 return false;
56 }
57
58 return true;
59 }
60
61 bool EtwSystemEventConsumer::StopKernelSessionTracing() {
62 HRESULT hr = base::win::EtwTraceController::Stop(
63 KERNEL_LOGGER_NAME, &properties_);
64 return SUCCEEDED(hr);
65 }
66
67 void EtwSystemEventConsumer::RequestStartTraceConsuming() {
68 events_.reset(new base::ListValue());
69 thread_.message_loop()->PostTask(
70 FROM_HERE,
71 base::Bind(&EtwSystemEventConsumer::TraceAndConsumeOnThread,
72 base::Unretained(this)));
73 }
74
75 void EtwSystemEventConsumer::RequestStopTraceConsuming(
76 const OutputCallback& callback) {
77 thread_.message_loop()->PostTask(FROM_HERE,
78 base::Bind(&EtwSystemEventConsumer::StopAndFlushOnThread,
79 base::Unretained(this), callback));
80 }
81
82 EtwSystemEventConsumer* EtwSystemEventConsumer::Get() {
83 return g_etw_consumer.Pointer();
84 }
85
86 void EtwSystemEventConsumer::ProcessEvent(EVENT_TRACE* event) {
87 EtwSystemEventConsumer::Get()->AppendEventToBuffer(event);
88 }
89
90 void EtwSystemEventConsumer::AppendEventToBuffer(EVENT_TRACE* event) {
91 using base::FundamentalValue;
92 using base::StringPrintf;
93
94 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
95
96 // Add header fields to the event.
97 value->Set("ts", new base::StringValue(
98 StringPrintf("%08X%08X",
99 event->Header.TimeStamp.HighPart,
100 event->Header.TimeStamp.LowPart)));
101
102 value->Set("guid", new base::StringValue(GuidToString(event->Header.Guid)));
103
104 value->Set("op", new FundamentalValue(event->Header.Class.Type));
105 value->Set("ver", new FundamentalValue(event->Header.Class.Version));
106 value->Set("pid",
107 new FundamentalValue(static_cast<int>(event->Header.ProcessId)));
108 value->Set("tid",
109 new FundamentalValue(static_cast<int>(event->Header.ThreadId)));
110 value->Set("cpu", new FundamentalValue(event->BufferContext.ProcessorNumber));
111
112 // Base64 encode the payload bytes.
113 base::StringPiece buffer(static_cast<const char*>(event->MofData),
114 event->MofLength);
115 std::string payload;
116 base::Base64Encode(buffer, &payload);
117 value->Set("payload", new base::StringValue(payload));
118
119 // Append it to the events buffer.
120 events_->Append(value.release());
121 }
122
123 void EtwSystemEventConsumer::TraceAndConsumeOnThread() {
124 HRESULT hr = OpenRealtimeSession(KERNEL_LOGGER_NAME);
125 if (FAILED(hr))
126 return;
127 Consume();
128 Close();
129 }
130
131 void EtwSystemEventConsumer::StopAndFlushOnThread(
132 const OutputCallback& callback) {
133 // Add the header information to the stream.
134 scoped_ptr<base::DictionaryValue> header(new base::DictionaryValue());
135 header->Set("name", base::Value::CreateStringValue("ETW"));
136 header->Set("content", events_.release());
137
138 // Serialize the results as a JSon string.
139 std::string output;
140 JSONStringValueSerializer serializer(&output);
141 serializer.set_pretty_print(true);
142 serializer.Serialize(*header.get());
143
144 // Pass the result to the UI Thread.
145 scoped_refptr<base::RefCountedString> result =
146 base::RefCountedString::TakeString(&output);
147 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
148 base::Bind(callback, result));
149 }
150
151 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698