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

Side by Side Diff: blimp/common/logging.cc

Issue 2026053002: Blimp: change logger to use switch/case for types. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « blimp/common/logging.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "blimp/common/logging.h" 5 #include "blimp/common/logging.h"
6 6
7 #include <iostream> 7 #include <iostream>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/format_macros.h" 11 #include "base/format_macros.h"
12 #include "base/json/string_escape.h" 12 #include "base/json/string_escape.h"
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
18 #include "blimp/common/create_blimp_message.h" 18 #include "blimp/common/create_blimp_message.h"
19 #include "blimp/common/proto/blimp_message.pb.h" 19 #include "blimp/common/proto/blimp_message.pb.h"
20 20
21 namespace blimp { 21 namespace blimp {
22 namespace { 22 namespace {
23 23
24 static base::LazyInstance<BlimpMessageLogger> g_logger = 24 typedef std::vector<std::pair<std::string, std::string>> LogFields;
25 LAZY_INSTANCE_INITIALIZER;
26 25
27 // The AddField() suite of functions are used to convert KV pairs with 26 // The AddField() suite of functions are used to convert KV pairs with
28 // arbitrarily typed values into string/string KV pairs for logging. 27 // arbitrarily typed values into string/string KV pairs for logging.
29 28
30 // Specialization for string values, surrounding them with quotes and escaping 29 // Specialization for string values, surrounding them with quotes and escaping
31 // characters as necessary. 30 // characters as necessary.
32 void AddField(const std::string& key, 31 void AddField(const std::string& key,
33 const std::string& value, 32 const std::string& value,
34 LogFields* output) { 33 LogFields* output) {
35 std::string escaped_value; 34 std::string escaped_value;
(...skipping 26 matching lines...) Expand all
62 // Uses std::to_string() to serialize |value|. 61 // Uses std::to_string() to serialize |value|.
63 template <typename T> 62 template <typename T>
64 void AddField(const std::string& key, const T& value, LogFields* output) { 63 void AddField(const std::string& key, const T& value, LogFields* output) {
65 output->push_back(std::make_pair(key, std::to_string(value))); 64 output->push_back(std::make_pair(key, std::to_string(value)));
66 } 65 }
67 66
68 // The following LogExtractor subclasses contain logic for extracting loggable 67 // The following LogExtractor subclasses contain logic for extracting loggable
69 // fields from BlimpMessages. 68 // fields from BlimpMessages.
70 69
71 // Logs fields from COMPOSITOR messages. 70 // Logs fields from COMPOSITOR messages.
72 class CompositorLogExtractor : public LogExtractor { 71 class CompositorLogExtractor {
73 void ExtractFields(const BlimpMessage& message, 72 public:
74 LogFields* output) const override { 73 static void ExtractFields(const BlimpMessage& message, LogFields* output) {
Wez 2016/06/01 21:35:15 Looks like this, and the other static member metho
Kevin M 2016/06/02 18:05:00 Done.
75 AddField("render_widget_id", message.compositor().render_widget_id(), 74 AddField("render_widget_id", message.compositor().render_widget_id(),
76 output); 75 output);
77 } 76 }
78 }; 77 };
79 78
80 // Logs fields from INPUT messages. 79 // Logs fields from INPUT messages.
81 class InputLogExtractor : public LogExtractor { 80 class InputLogExtractor {
82 void ExtractFields(const BlimpMessage& message, 81 public:
83 LogFields* output) const override { 82 static void ExtractFields(const BlimpMessage& message, LogFields* output) {
84 AddField("render_widget_id", message.input().render_widget_id(), output); 83 AddField("render_widget_id", message.input().render_widget_id(), output);
85 AddField("timestamp_seconds", message.input().timestamp_seconds(), output); 84 AddField("timestamp_seconds", message.input().timestamp_seconds(), output);
86 switch (message.input().type()) { 85 switch (message.input().type()) {
87 case InputMessage::Type_GestureScrollBegin: 86 case InputMessage::Type_GestureScrollBegin:
88 AddField("subtype", "GestureScrollBegin", output); 87 AddField("subtype", "GestureScrollBegin", output);
89 break; 88 break;
90 case InputMessage::Type_GestureScrollEnd: 89 case InputMessage::Type_GestureScrollEnd:
91 AddField("subtype", "GestureScrollEnd", output); 90 AddField("subtype", "GestureScrollEnd", output);
92 break; 91 break;
93 case InputMessage::Type_GestureScrollUpdate: 92 case InputMessage::Type_GestureScrollUpdate:
(...skipping 20 matching lines...) Expand all
114 case InputMessage::Type_GesturePinchUpdate: 113 case InputMessage::Type_GesturePinchUpdate:
115 AddField("subtype", "GesturePinchUpdate", output); 114 AddField("subtype", "GesturePinchUpdate", output);
116 break; 115 break;
117 default: // unknown 116 default: // unknown
118 break; 117 break;
119 } 118 }
120 } 119 }
121 }; 120 };
122 121
123 // Logs fields from NAVIGATION messages. 122 // Logs fields from NAVIGATION messages.
124 class NavigationLogExtractor : public LogExtractor { 123 class NavigationLogExtractor {
125 void ExtractFields(const BlimpMessage& message, 124 public:
126 LogFields* output) const override { 125 static void ExtractFields(const BlimpMessage& message, LogFields* output) {
127 switch (message.navigation().type()) { 126 switch (message.navigation().type()) {
128 case NavigationMessage::NAVIGATION_STATE_CHANGED: 127 case NavigationMessage::NAVIGATION_STATE_CHANGED:
129 AddField("subtype", "NAVIGATION_STATE_CHANGED", output); 128 AddField("subtype", "NAVIGATION_STATE_CHANGED", output);
130 if (message.navigation().navigation_state_changed().has_url()) { 129 if (message.navigation().navigation_state_changed().has_url()) {
131 AddField("url", message.navigation().navigation_state_changed().url(), 130 AddField("url", message.navigation().navigation_state_changed().url(),
132 output); 131 output);
133 } 132 }
134 if (message.navigation().navigation_state_changed().has_favicon()) { 133 if (message.navigation().navigation_state_changed().has_favicon()) {
135 AddField( 134 AddField(
136 "favicon_size", 135 "favicon_size",
(...skipping 24 matching lines...) Expand all
161 case NavigationMessage::RELOAD: 160 case NavigationMessage::RELOAD:
162 AddField("subtype", "RELOAD", output); 161 AddField("subtype", "RELOAD", output);
163 break; 162 break;
164 default: 163 default:
165 break; 164 break;
166 } 165 }
167 } 166 }
168 }; 167 };
169 168
170 // Logs fields from PROTOCOL_CONTROL messages. 169 // Logs fields from PROTOCOL_CONTROL messages.
171 class ProtocolControlLogExtractor : public LogExtractor { 170 class ProtocolControlLogExtractor {
172 void ExtractFields(const BlimpMessage& message, 171 public:
173 LogFields* output) const override { 172 static void ExtractFields(const BlimpMessage& message, LogFields* output) {
174 switch (message.protocol_control().connection_message_case()) { 173 switch (message.protocol_control().connection_message_case()) {
175 case ProtocolControlMessage::kStartConnection: 174 case ProtocolControlMessage::kStartConnection:
176 AddField("subtype", "START_CONNECTION", output); 175 AddField("subtype", "START_CONNECTION", output);
177 AddField("client_token", 176 AddField("client_token",
178 message.protocol_control().start_connection().client_token(), 177 message.protocol_control().start_connection().client_token(),
179 output); 178 output);
180 AddField( 179 AddField(
181 "protocol_version", 180 "protocol_version",
182 message.protocol_control().start_connection().protocol_version(), 181 message.protocol_control().start_connection().protocol_version(),
183 output); 182 output);
184 break; 183 break;
185 case ProtocolControlMessage::kCheckpointAck: 184 case ProtocolControlMessage::kCheckpointAck:
186 AddField("subtype", "CHECKPOINT_ACK", output); 185 AddField("subtype", "CHECKPOINT_ACK", output);
187 AddField("checkpoint_id", 186 AddField("checkpoint_id",
188 message.protocol_control().checkpoint_ack().checkpoint_id(), 187 message.protocol_control().checkpoint_ack().checkpoint_id(),
189 output); 188 output);
190 break; 189 break;
191 default: 190 default:
192 break; 191 break;
193 } 192 }
194 } 193 }
195 }; 194 };
196 195
197 // Logs fields from RENDER_WIDGET messages. 196 // Logs fields from RENDER_WIDGET messages.
198 class RenderWidgetLogExtractor : public LogExtractor { 197 class RenderWidgetLogExtractor {
199 void ExtractFields(const BlimpMessage& message, 198 public:
200 LogFields* output) const override { 199 static void ExtractFields(const BlimpMessage& message, LogFields* output) {
201 switch (message.render_widget().type()) { 200 switch (message.render_widget().type()) {
202 case RenderWidgetMessage::INITIALIZE: 201 case RenderWidgetMessage::INITIALIZE:
203 AddField("subtype", "INITIALIZE", output); 202 AddField("subtype", "INITIALIZE", output);
204 break; 203 break;
205 case RenderWidgetMessage::CREATED: 204 case RenderWidgetMessage::CREATED:
206 AddField("subtype", "CREATED", output); 205 AddField("subtype", "CREATED", output);
207 break; 206 break;
208 case RenderWidgetMessage::DELETED: 207 case RenderWidgetMessage::DELETED:
209 AddField("subtype", "DELETED", output); 208 AddField("subtype", "DELETED", output);
210 break; 209 break;
211 } 210 }
212 AddField("render_widget_id", message.render_widget().render_widget_id(), 211 AddField("render_widget_id", message.render_widget().render_widget_id(),
213 output); 212 output);
214 } 213 }
215 }; 214 };
216 215
217 // Logs fields from SETTINGS messages. 216 // Logs fields from SETTINGS messages.
218 class SettingsLogExtractor : public LogExtractor { 217 class SettingsLogExtractor {
219 void ExtractFields(const BlimpMessage& message, 218 public:
220 LogFields* output) const override { 219 static void ExtractFields(const BlimpMessage& message, LogFields* output) {
221 if (message.settings().has_engine_settings()) { 220 if (message.settings().has_engine_settings()) {
222 const EngineSettingsMessage& engine_settings = 221 const EngineSettingsMessage& engine_settings =
223 message.settings().engine_settings(); 222 message.settings().engine_settings();
224 AddField("subtype", "ENGINE_SETTINGS", output); 223 AddField("subtype", "ENGINE_SETTINGS", output);
225 AddField("record_whole_document", engine_settings.record_whole_document(), 224 AddField("record_whole_document", engine_settings.record_whole_document(),
226 output); 225 output);
227 AddField("client_os_info", engine_settings.client_os_info(), output); 226 AddField("client_os_info", engine_settings.client_os_info(), output);
228 } 227 }
229 } 228 }
230 }; 229 };
231 230
232 // Logs fields from TAB_CONTROL messages. 231 // Logs fields from TAB_CONTROL messages.
233 class TabControlLogExtractor : public LogExtractor { 232 class TabControlLogExtractor {
234 void ExtractFields(const BlimpMessage& message, 233 public:
235 LogFields* output) const override { 234 static void ExtractFields(const BlimpMessage& message, LogFields* output) {
236 switch (message.tab_control().tab_control_case()) { 235 switch (message.tab_control().tab_control_case()) {
237 case TabControlMessage::kCreateTab: 236 case TabControlMessage::kCreateTab:
238 AddField("subtype", "CREATE_TAB", output); 237 AddField("subtype", "CREATE_TAB", output);
239 break; 238 break;
240 case TabControlMessage::kCloseTab: 239 case TabControlMessage::kCloseTab:
241 AddField("subtype", "CLOSE_TAB", output); 240 AddField("subtype", "CLOSE_TAB", output);
242 break; 241 break;
243 case TabControlMessage::kSize: 242 case TabControlMessage::kSize:
244 AddField("subtype", "SIZE", output); 243 AddField("subtype", "SIZE", output);
245 AddField("size", message.tab_control().size(), output); 244 AddField("size", message.tab_control().size(), output);
246 break; 245 break;
247 default: // unknown 246 default: // unknown
248 break; 247 break;
249 } 248 }
250 } 249 }
251 }; 250 };
252 251
253 // Logs fields from BLOB_CHANNEL messages. 252 // Logs fields from BLOB_CHANNEL messages.
254 class BlobChannelLogExtractor : public LogExtractor { 253 class BlobChannelLogExtractor {
255 void ExtractFields(const BlimpMessage& message, 254 public:
256 LogFields* output) const override { 255 static void ExtractFields(const BlimpMessage& message, LogFields* output) {
257 switch (message.blob_channel().type_case()) { 256 switch (message.blob_channel().type_case()) {
258 case BlobChannelMessage::TypeCase::kTransferBlob: 257 case BlobChannelMessage::TypeCase::kTransferBlob:
259 AddField("subtype", "TRANSFER_BLOB", output); 258 AddField("subtype", "TRANSFER_BLOB", output);
260 AddField("id", 259 AddField("id",
261 base::HexEncode( 260 base::HexEncode(
262 message.blob_channel().transfer_blob().blob_id().data(), 261 message.blob_channel().transfer_blob().blob_id().data(),
263 message.blob_channel().transfer_blob().blob_id().size()), 262 message.blob_channel().transfer_blob().blob_id().size()),
264 output); 263 output);
265 AddField("payload_size", 264 AddField("payload_size",
266 message.blob_channel().transfer_blob().payload().size(), 265 message.blob_channel().transfer_blob().payload().size(),
267 output); 266 output);
268 break; 267 break;
269 case BlobChannelMessage::TypeCase::TYPE_NOT_SET: // unknown 268 case BlobChannelMessage::TypeCase::TYPE_NOT_SET: // unknown
270 break; 269 break;
271 } 270 }
272 } 271 }
273 }; 272 };
274 273
275 // No fields are extracted from |message|. 274 void LogMessageToStream(const BlimpMessage& message, std::ostream* out) {
276 class NullLogExtractor : public LogExtractor {
277 void ExtractFields(const BlimpMessage& message,
278 LogFields* output) const override {}
279 };
280
281 } // namespace
282
283 BlimpMessageLogger::BlimpMessageLogger() {
284 AddHandler("COMPOSITOR", BlimpMessage::kCompositor,
285 base::WrapUnique(new CompositorLogExtractor));
286 AddHandler("INPUT", BlimpMessage::kInput,
287 base::WrapUnique(new InputLogExtractor));
288 AddHandler("NAVIGATION", BlimpMessage::kNavigation,
289 base::WrapUnique(new NavigationLogExtractor));
290 AddHandler("PROTOCOL_CONTROL", BlimpMessage::kProtocolControl,
291 base::WrapUnique(new ProtocolControlLogExtractor));
292 AddHandler("RENDER_WIDGET", BlimpMessage::kRenderWidget,
293 base::WrapUnique(new RenderWidgetLogExtractor));
294 AddHandler("SETTINGS", BlimpMessage::kSettings,
295 base::WrapUnique(new SettingsLogExtractor));
296 AddHandler("TAB_CONTROL", BlimpMessage::kTabControl,
297 base::WrapUnique(new TabControlLogExtractor));
298 AddHandler("BLOB_CHANNEL", BlimpMessage::kBlobChannel,
299 base::WrapUnique(new BlobChannelLogExtractor));
300 }
301
302 BlimpMessageLogger::~BlimpMessageLogger() {}
303
304 void BlimpMessageLogger::AddHandler(const std::string& feature_name,
305 BlimpMessage::FeatureCase feature_case,
306 std::unique_ptr<LogExtractor> extractor) {
307 DCHECK(extractors_.find(feature_case) == extractors_.end());
308 DCHECK(!feature_name.empty());
309 extractors_[feature_case] = make_pair(feature_name, std::move(extractor));
310 }
311
312 void BlimpMessageLogger::LogMessageToStream(const BlimpMessage& message,
313 std::ostream* out) const {
314 LogFields fields; 275 LogFields fields;
315 276
316 auto extractor = extractors_.find(message.feature_case()); 277 switch (message.feature_case()) {
317 if (extractor != extractors_.end()) { 278 case BlimpMessage::kCompositor:
318 // An extractor is registered for |message|. 279 fields.push_back(std::make_pair("type", "COMPOSITOR"));
319 // Add the human-readable name of |message.type|. 280 CompositorLogExtractor::ExtractFields(message, &fields);
320 fields.push_back(make_pair("type", extractor->second.first)); 281 break;
321 extractor->second.second->ExtractFields(message, &fields); 282 case BlimpMessage::kInput:
322 } else { 283 fields.push_back(std::make_pair("type", "INPUT"));
323 // Don't know the human-readable name of |message.type|. 284 InputLogExtractor::ExtractFields(message, &fields);
324 // Just represent it using its numeric form instead. 285 break;
325 AddField("type", message.feature_case(), &fields); 286 case BlimpMessage::kNavigation:
287 fields.push_back(std::make_pair("type", "NAVIGATION"));
288 NavigationLogExtractor::ExtractFields(message, &fields);
289 break;
290 case BlimpMessage::kProtocolControl:
291 fields.push_back(std::make_pair("type", "PROTOCOL_CONTROL"));
292 ProtocolControlLogExtractor::ExtractFields(message, &fields);
293 break;
294 case BlimpMessage::kRenderWidget:
295 fields.push_back(std::make_pair("type", "RENDER_WIDGET"));
296 RenderWidgetLogExtractor::ExtractFields(message, &fields);
297 break;
298 case BlimpMessage::kSettings:
299 fields.push_back(std::make_pair("type", "SETTINGS"));
300 SettingsLogExtractor::ExtractFields(message, &fields);
301 break;
302 case BlimpMessage::kTabControl:
303 fields.push_back(std::make_pair("type", "TAB_CONTROL"));
304 TabControlLogExtractor::ExtractFields(message, &fields);
305 break;
306 case BlimpMessage::kBlobChannel:
307 fields.push_back(std::make_pair("type", "BLOB_CHANNEL"));
308 BlobChannelLogExtractor::ExtractFields(message, &fields);
309 break;
310 case BlimpMessage::kIme:
311 fields.push_back(std::make_pair("type", "IME"));
312 break;
313 case BlimpMessage::FEATURE_NOT_SET:
314 fields.push_back(std::make_pair("type", "<UNKNOWN>"));
315 break;
326 } 316 }
327 317
328 // Append "target_tab_id" (if present) and "byte_size" to the field set. 318 // Append "target_tab_id" (if present) and "byte_size" to the field set.
329 if (message.has_target_tab_id()) { 319 if (message.has_target_tab_id()) {
330 AddField("target_tab_id", message.target_tab_id(), &fields); 320 AddField("target_tab_id", message.target_tab_id(), &fields);
331 } 321 }
332 AddField("byte_size", message.ByteSize(), &fields); 322 AddField("byte_size", message.ByteSize(), &fields);
333 323
334 // Format message using the syntax: 324 // Format message using the syntax:
335 // <BlimpMessage field1=value1 field2="value 2"> 325 // <BlimpMessage field1=value1 field2="value 2">
336 *out << "<BlimpMessage "; 326 *out << "<BlimpMessage ";
337 for (size_t i = 0; i < fields.size(); ++i) { 327 for (size_t i = 0; i < fields.size(); ++i) {
338 *out << fields[i].first << "=" << fields[i].second 328 *out << fields[i].first << "=" << fields[i].second
339 << (i != fields.size() - 1 ? " " : ""); 329 << (i != fields.size() - 1 ? " " : "");
340 } 330 }
341 *out << ">"; 331 *out << ">";
342 } 332 }
343 333
334 } // namespace
335
344 std::ostream& operator<<(std::ostream& out, const BlimpMessage& message) { 336 std::ostream& operator<<(std::ostream& out, const BlimpMessage& message) {
345 g_logger.Get().LogMessageToStream(message, &out); 337 LogMessageToStream(message, &out);
346 return out; 338 return out;
347 } 339 }
348 340
349 } // namespace blimp 341 } // namespace blimp
OLDNEW
« no previous file with comments | « blimp/common/logging.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698