OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // Trace events are for tracking application performance. | 5 // Trace events are for tracking application performance. |
6 // | 6 // |
7 // Events are issued against categories. Whereas LOG's | 7 // Events are issued against categories. Whereas LOG's |
8 // categories are statically defined, TRACE categories are created | 8 // categories are statically defined, TRACE categories are created |
9 // implicitly with a string. For example: | 9 // implicitly with a string. For example: |
10 // TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent") | 10 // TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent") |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
89 #include <string> | 89 #include <string> |
90 #include <vector> | 90 #include <vector> |
91 | 91 |
92 #include "base/callback.h" | 92 #include "base/callback.h" |
93 #include "base/hash_tables.h" | 93 #include "base/hash_tables.h" |
94 #include "base/memory/singleton.h" | 94 #include "base/memory/singleton.h" |
95 #include "base/string_util.h" | 95 #include "base/string_util.h" |
96 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 96 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
97 #include "base/timer.h" | 97 #include "base/timer.h" |
98 | 98 |
99 // Short hand convenience macro for specifying unscoped strings as argument | |
100 // values to avoid allocating/copying. The string pointer must remain valid | |
101 // until tracing is disabled. | |
102 #define TRACE_STATIC_STR(str) base::debug::TraceValue::StaticString(str) | |
103 | |
99 // Older style trace macros with explicit id and extra data | 104 // Older style trace macros with explicit id and extra data |
100 // Only these macros result in publishing data to ETW as currently implemented. | 105 // Only these macros result in publishing data to ETW as currently implemented. |
101 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ | 106 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ |
102 base::debug::TraceLog::AddTraceEventEtw( \ | 107 base::debug::TraceLog::AddTraceEventEtw( \ |
103 base::debug::TRACE_EVENT_PHASE_BEGIN, \ | 108 base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
104 name, reinterpret_cast<const void*>(id), extra); | 109 name, reinterpret_cast<const void*>(id), extra); |
105 | 110 |
106 #define TRACE_EVENT_END_ETW(name, id, extra) \ | 111 #define TRACE_EVENT_END_ETW(name, id, extra) \ |
107 base::debug::TraceLog::AddTraceEventEtw( \ | 112 base::debug::TraceLog::AddTraceEventEtw( \ |
108 base::debug::TRACE_EVENT_PHASE_END, \ | 113 base::debug::TRACE_EVENT_PHASE_END, \ |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
306 // low, we want constant size storage here. | 311 // low, we want constant size storage here. |
307 class BASE_EXPORT TraceValue { | 312 class BASE_EXPORT TraceValue { |
308 public: | 313 public: |
309 enum Type { | 314 enum Type { |
310 TRACE_TYPE_UNDEFINED, | 315 TRACE_TYPE_UNDEFINED, |
311 TRACE_TYPE_BOOL, | 316 TRACE_TYPE_BOOL, |
312 TRACE_TYPE_UINT, | 317 TRACE_TYPE_UINT, |
313 TRACE_TYPE_INT, | 318 TRACE_TYPE_INT, |
314 TRACE_TYPE_DOUBLE, | 319 TRACE_TYPE_DOUBLE, |
315 TRACE_TYPE_POINTER, | 320 TRACE_TYPE_POINTER, |
316 TRACE_TYPE_STRING | 321 TRACE_TYPE_STRING, |
322 TRACE_TYPE_STATIC_STRING | |
317 }; | 323 }; |
318 | 324 |
319 TraceValue() : type_(TRACE_TYPE_UNDEFINED) { | 325 TraceValue() : type_(TRACE_TYPE_UNDEFINED) { |
320 value_.as_uint = 0ull; | 326 value_.as_uint = 0ull; |
321 } | 327 } |
322 TraceValue(bool rhs) : type_(TRACE_TYPE_BOOL) { | 328 TraceValue(bool rhs) : type_(TRACE_TYPE_BOOL) { |
323 value_.as_bool = rhs; | 329 value_.as_bool = rhs; |
324 } | 330 } |
325 TraceValue(uint64 rhs) : type_(TRACE_TYPE_UINT) { | 331 TraceValue(uint64 rhs) : type_(TRACE_TYPE_UINT) { |
326 value_.as_uint = rhs; | 332 value_.as_uint = rhs; |
(...skipping 21 matching lines...) Expand all Loading... | |
348 } | 354 } |
349 TraceValue(double rhs) : type_(TRACE_TYPE_DOUBLE) { | 355 TraceValue(double rhs) : type_(TRACE_TYPE_DOUBLE) { |
350 value_.as_double = rhs; | 356 value_.as_double = rhs; |
351 } | 357 } |
352 TraceValue(const void* rhs) : type_(TRACE_TYPE_POINTER) { | 358 TraceValue(const void* rhs) : type_(TRACE_TYPE_POINTER) { |
353 value_.as_pointer = rhs; | 359 value_.as_pointer = rhs; |
354 } | 360 } |
355 TraceValue(const char* rhs) : type_(TRACE_TYPE_STRING) { | 361 TraceValue(const char* rhs) : type_(TRACE_TYPE_STRING) { |
356 value_.as_string = rhs; | 362 value_.as_string = rhs; |
357 } | 363 } |
364 // User this if your string is already global and does not need to be copied. | |
365 static TraceValue StaticString(const char* rhs) { | |
366 return TraceValue(rhs, 0); | |
scheib
2011/08/29 21:46:09
nit: Can you just call the string constructor and
jbates
2011/08/29 22:22:20
Done.
| |
367 } | |
358 | 368 |
359 void AppendAsJSON(std::string* out) const; | 369 void AppendAsJSON(std::string* out) const; |
360 | 370 |
361 Type type() const { | 371 Type type() const { |
362 return type_; | 372 return type_; |
363 } | 373 } |
364 uint64 as_uint() const { | 374 uint64 as_uint() const { |
365 DCHECK_EQ(TRACE_TYPE_UINT, type_); | 375 DCHECK_EQ(TRACE_TYPE_UINT, type_); |
366 return value_.as_uint; | 376 return value_.as_uint; |
367 } | 377 } |
368 bool as_bool() const { | 378 bool as_bool() const { |
369 DCHECK_EQ(TRACE_TYPE_BOOL, type_); | 379 DCHECK_EQ(TRACE_TYPE_BOOL, type_); |
370 return value_.as_bool; | 380 return value_.as_bool; |
371 } | 381 } |
372 int64 as_int() const { | 382 int64 as_int() const { |
373 DCHECK_EQ(TRACE_TYPE_INT, type_); | 383 DCHECK_EQ(TRACE_TYPE_INT, type_); |
374 return value_.as_int; | 384 return value_.as_int; |
375 } | 385 } |
376 double as_double() const { | 386 double as_double() const { |
377 DCHECK_EQ(TRACE_TYPE_DOUBLE, type_); | 387 DCHECK_EQ(TRACE_TYPE_DOUBLE, type_); |
378 return value_.as_double; | 388 return value_.as_double; |
379 } | 389 } |
380 const void* as_pointer() const { | 390 const void* as_pointer() const { |
381 DCHECK_EQ(TRACE_TYPE_POINTER, type_); | 391 DCHECK_EQ(TRACE_TYPE_POINTER, type_); |
382 return value_.as_pointer; | 392 return value_.as_pointer; |
383 } | 393 } |
384 const char* as_string() const { | 394 const char* as_string() const { |
385 DCHECK_EQ(TRACE_TYPE_STRING, type_); | 395 DCHECK(type_ == TRACE_TYPE_STRING || type_ == TRACE_TYPE_STATIC_STRING); |
386 return value_.as_string; | 396 return value_.as_string; |
387 } | 397 } |
388 const char** as_assignable_string() { | 398 const char** as_assignable_string() { |
389 DCHECK_EQ(TRACE_TYPE_STRING, type_); | 399 DCHECK_EQ(TRACE_TYPE_STRING, type_); |
390 return &value_.as_string; | 400 return &value_.as_string; |
391 } | 401 } |
392 | 402 |
393 private: | 403 private: |
394 union Value { | 404 union Value { |
395 bool as_bool; | 405 bool as_bool; |
396 uint64 as_uint; | 406 uint64 as_uint; |
397 int64 as_int; | 407 int64 as_int; |
398 double as_double; | 408 double as_double; |
399 const void* as_pointer; | 409 const void* as_pointer; |
400 const char* as_string; | 410 const char* as_string; |
401 }; | 411 }; |
402 | 412 |
413 TraceValue(const char* rhs, int ignore) : type_(TRACE_TYPE_STATIC_STRING) { | |
414 (void)ignore; | |
415 value_.as_string = rhs; | |
416 } | |
417 | |
403 Type type_; | 418 Type type_; |
404 Value value_; | 419 Value value_; |
405 }; | 420 }; |
406 | 421 |
407 // Output records are "Events" and can be obtained via the | 422 // Output records are "Events" and can be obtained via the |
408 // OutputCallback whenever the tracing system decides to flush. This | 423 // OutputCallback whenever the tracing system decides to flush. This |
409 // can happen at any time, on any thread, or you can programatically | 424 // can happen at any time, on any thread, or you can programatically |
410 // force it to happen. | 425 // force it to happen. |
411 class TraceEvent { | 426 class TraceEvent { |
412 public: | 427 public: |
(...skipping 11 matching lines...) Expand all Loading... | |
424 | 439 |
425 // Serialize event data to JSON | 440 // Serialize event data to JSON |
426 static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, | 441 static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, |
427 size_t start, | 442 size_t start, |
428 size_t count, | 443 size_t count, |
429 std::string* out); | 444 std::string* out); |
430 void AppendAsJSON(std::string* out) const; | 445 void AppendAsJSON(std::string* out) const; |
431 | 446 |
432 TimeTicks timestamp() const { return timestamp_; } | 447 TimeTicks timestamp() const { return timestamp_; } |
433 | 448 |
449 // Exposed for unittesting: | |
450 | |
451 const base::RefCountedString* parameter_copy_storage() const { | |
452 return parameter_copy_storage_.get(); | |
453 } | |
454 | |
455 const char* name() const { return name_; } | |
456 | |
434 private: | 457 private: |
435 unsigned long process_id_; | 458 unsigned long process_id_; |
436 unsigned long thread_id_; | 459 unsigned long thread_id_; |
437 TimeTicks timestamp_; | 460 TimeTicks timestamp_; |
438 TraceEventPhase phase_; | 461 TraceEventPhase phase_; |
439 const TraceCategory* category_; | 462 const TraceCategory* category_; |
440 const char* name_; | 463 const char* name_; |
441 const char* arg_names_[kTraceMaxNumArgs]; | 464 const char* arg_names_[kTraceMaxNumArgs]; |
442 TraceValue arg_values_[kTraceMaxNumArgs]; | 465 TraceValue arg_values_[kTraceMaxNumArgs]; |
443 scoped_refptr<base::RefCountedString> parameter_copy_storage_; | 466 scoped_refptr<base::RefCountedString> parameter_copy_storage_; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
495 const char* name, | 518 const char* name, |
496 const void* id, | 519 const void* id, |
497 const char* extra); | 520 const char* extra); |
498 static void AddTraceEventEtw(TraceEventPhase phase, | 521 static void AddTraceEventEtw(TraceEventPhase phase, |
499 const char* name, | 522 const char* name, |
500 const void* id, | 523 const void* id, |
501 const std::string& extra) { | 524 const std::string& extra) { |
502 AddTraceEventEtw(phase, name, id, extra.c_str()); | 525 AddTraceEventEtw(phase, name, id, extra.c_str()); |
503 } | 526 } |
504 | 527 |
505 // Exposed for unittesting only, allows resurrecting our | 528 // Exposed for unittesting: |
506 // singleton instance post-AtExit processing. | 529 |
530 // Allows resurrecting our singleton instance post-AtExit processing. | |
507 static void Resurrect(); | 531 static void Resurrect(); |
508 | 532 |
533 // Allow tests to inspect TraceEvents. | |
534 size_t GetEventsSize() const { return logged_events_.size(); } | |
535 const TraceEvent& GetEventAt(size_t index) const { | |
536 DCHECK(index < logged_events_.size()); | |
537 return logged_events_[index]; | |
538 } | |
539 | |
509 private: | 540 private: |
510 // This allows constructor and destructor to be private and usable only | 541 // This allows constructor and destructor to be private and usable only |
511 // by the Singleton class. | 542 // by the Singleton class. |
512 friend struct StaticMemorySingletonTraits<TraceLog>; | 543 friend struct StaticMemorySingletonTraits<TraceLog>; |
513 | 544 |
514 TraceLog(); | 545 TraceLog(); |
515 ~TraceLog(); | 546 ~TraceLog(); |
516 const TraceCategory* GetCategoryInternal(const char* name); | 547 const TraceCategory* GetCategoryInternal(const char* name); |
517 void AddCurrentMetadataEvents(); | 548 void AddCurrentMetadataEvents(); |
518 | 549 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
594 Data* p_data_; | 625 Data* p_data_; |
595 Data data_; | 626 Data data_; |
596 }; | 627 }; |
597 | 628 |
598 } // namespace internal | 629 } // namespace internal |
599 | 630 |
600 } // namespace debug | 631 } // namespace debug |
601 } // namespace base | 632 } // namespace base |
602 | 633 |
603 #endif // BASE_DEBUG_TRACE_EVENT_H_ | 634 #endif // BASE_DEBUG_TRACE_EVENT_H_ |
OLD | NEW |