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

Side by Side Diff: base/debug/trace_event_impl.cc

Issue 11823016: Trace category groups and category filter. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Category group and category filter basics. Created 7 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
« no previous file with comments | « base/debug/trace_event_impl.h ('k') | base/debug/trace_event_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/debug/trace_event_impl.h" 5 #include "base/debug/trace_event_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/leak_annotations.h" 10 #include "base/debug/leak_annotations.h"
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_enabled); 389 uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_enabled);
390 DCHECK(category_ptr >= category_begin && 390 DCHECK(category_ptr >= category_begin &&
391 category_ptr < reinterpret_cast<uintptr_t>(g_category_enabled + 391 category_ptr < reinterpret_cast<uintptr_t>(g_category_enabled +
392 TRACE_EVENT_MAX_CATEGORIES)) << 392 TRACE_EVENT_MAX_CATEGORIES)) <<
393 "out of bounds category pointer"; 393 "out of bounds category pointer";
394 uintptr_t category_index = 394 uintptr_t category_index =
395 (category_ptr - category_begin) / sizeof(g_category_enabled[0]); 395 (category_ptr - category_begin) / sizeof(g_category_enabled[0]);
396 return g_categories[category_index]; 396 return g_categories[category_index];
397 } 397 }
398 398
399 static void EnableMatchingCategory(int category_index, 399 void TraceLog::EnableIncludedCategoryGroup(int category_index,
400 const std::vector<std::string>& patterns, 400 const CategoryFilter& category_filter) {
401 unsigned char matched_value, 401 bool is_enabled =
402 unsigned char unmatched_value) { 402 category_filter.IsCategoryGroupEnabled(g_categories[category_index]);
403 std::vector<std::string>::const_iterator ci = patterns.begin(); 403 g_category_enabled[category_index] = is_enabled ?
404 bool is_match = false; 404 TraceLog::CATEGORY_ENABLED : 0;
405 for (; ci != patterns.end(); ++ci) {
406 is_match = MatchPattern(g_categories[category_index], ci->c_str());
407 if (is_match)
408 break;
409 }
410 g_category_enabled[category_index] = is_match ?
411 matched_value : unmatched_value;
412 } 405 }
413 406
414 // Enable/disable each category based on the category filters in |patterns|. 407 void TraceLog::EnableIncludedCategoryGroups(
415 // If the category name matches one of the patterns, its enabled status is set 408 const CategoryFilter& category_filter) {
416 // to |matched_value|. Otherwise its enabled status is set to |unmatched_value|.
417 static void EnableMatchingCategories(const std::vector<std::string>& patterns,
418 unsigned char matched_value,
419 unsigned char unmatched_value) {
420 for (int i = 0; i < g_category_index; i++) 409 for (int i = 0; i < g_category_index; i++)
421 EnableMatchingCategory(i, patterns, matched_value, unmatched_value); 410 EnableIncludedCategoryGroup(i, category_filter);
422 } 411 }
423 412
424 const unsigned char* TraceLog::GetCategoryEnabledInternal(const char* name) { 413 const unsigned char* TraceLog::GetCategoryEnabledInternal(const char* name) {
425 AutoLock lock(lock_); 414 AutoLock lock(lock_);
426 DCHECK(!strchr(name, '"')) << "Category names may not contain double quote"; 415 DCHECK(!strchr(name, '"')) << "Category names may not contain double quote";
427 416
428 unsigned char* category_enabled = NULL; 417 unsigned char* category_enabled = NULL;
429 // Search for pre-existing category matching this name 418 // Search for pre-existing category matching this name
430 for (int i = 0; i < g_category_index; i++) { 419 for (int i = 0; i < g_category_index; i++) {
431 if (strcmp(g_categories[i], name) == 0) { 420 if (strcmp(g_categories[i], name) == 0) {
432 category_enabled = &g_category_enabled[i]; 421 category_enabled = &g_category_enabled[i];
433 break; 422 break;
434 } 423 }
435 } 424 }
436 425
437 if (!category_enabled) { 426 if (!category_enabled) {
438 // Create a new category 427 // Create a new category
439 DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) << 428 DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) <<
440 "must increase TRACE_EVENT_MAX_CATEGORIES"; 429 "must increase TRACE_EVENT_MAX_CATEGORIES";
441 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { 430 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) {
442 int new_index = g_category_index++; 431 int new_index = g_category_index++;
443 // Don't hold on to the name pointer, so that we can create categories 432 // Don't hold on to the name pointer, so that we can create categories
444 // with strings not known at compile time (this is required by 433 // with strings not known at compile time (this is required by
445 // SetWatchEvent). 434 // SetWatchEvent).
446 const char* new_name = strdup(name); 435 const char* new_name = strdup(name);
447 ANNOTATE_LEAKING_OBJECT_PTR(new_name); 436 ANNOTATE_LEAKING_OBJECT_PTR(new_name);
448 g_categories[new_index] = new_name; 437 g_categories[new_index] = new_name;
449 DCHECK(!g_category_enabled[new_index]); 438 DCHECK(!g_category_enabled[new_index]);
450 if (enable_count_) { 439 if (enable_count_) {
451 // Note that if both included and excluded_categories are empty, the 440 // Note that if both included and excluded patterns in the
452 // else clause below excludes nothing, thereby enabling this category. 441 // CategoryFilter are empty, we exclude nothing,
453 if (!included_categories_.empty()) { 442 // thereby enabling this category group.
454 EnableMatchingCategory(new_index, included_categories_, 443 EnableIncludedCategoryGroup(new_index, category_filter_);
455 CATEGORY_ENABLED, 0);
456 } else {
457 EnableMatchingCategory(new_index, excluded_categories_,
458 0, CATEGORY_ENABLED);
459 }
460 } else { 444 } else {
461 g_category_enabled[new_index] = 0; 445 g_category_enabled[new_index] = 0;
462 } 446 }
463 category_enabled = &g_category_enabled[new_index]; 447 category_enabled = &g_category_enabled[new_index];
464 } else { 448 } else {
465 category_enabled = &g_category_enabled[g_category_categories_exhausted]; 449 category_enabled = &g_category_enabled[g_category_categories_exhausted];
466 } 450 }
467 } 451 }
468 #if defined(OS_ANDROID) 452 #if defined(OS_ANDROID)
469 ApplyATraceEnabledFlag(category_enabled); 453 ApplyATraceEnabledFlag(category_enabled);
470 #endif 454 #endif
471 return category_enabled; 455 return category_enabled;
472 } 456 }
473 457
474 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { 458 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) {
475 AutoLock lock(lock_); 459 AutoLock lock(lock_);
476 for (int i = 0; i < g_category_index; i++) 460 for (int i = 0; i < g_category_index; i++)
477 categories->push_back(g_categories[i]); 461 categories->push_back(g_categories[i]);
478 } 462 }
479 463
480 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, 464 static bool DoesCategoryGroupContainCategory(const char* category_group,
481 const std::vector<std::string>& excluded_categories) { 465 const char* category) {
rterrazas 2013/02/21 04:08:05 So...I was thinking, I'd like to change this to so
nduca 2013/02/22 19:55:19 This sounds like a metho don the CategoryFilter ob
466 DCHECK(category);
467 CStringTokenizer category_group_tokens(category_group,
468 category_group + strlen(category_group), ",");
469 while (category_group_tokens.GetNext()) {
470 std::string category_group_token = category_group_tokens.token();
471 // Don't allow empty tokens, nor tokens with leading or trailing space.
472 DCHECK(!category_group_token.empty() &&
473 category_group_token.at(0) != ' '&&
474 category_group_token.at(category_group_token.length() - 1) != ' ')
475 << "Disallowed category string";
476 if (MatchPattern(category_group_token.c_str(), category))
477 return true;
478 }
479 return false;
480 }
481
482 const char* CategoryFilter::kDefaultCategoryFilterString = "-*Debug,-*Test";
483
484 CategoryFilter::CategoryFilter() {
485 Initialize(CategoryFilter::kDefaultCategoryFilterString);
486 }
487
488 CategoryFilter::CategoryFilter(const std::string& filter_string) {
489 Initialize(filter_string);
490 }
491
492 void CategoryFilter::Initialize(const std::string& filter_string) {
493 // Pass 1: Tokenize list of categories, delimited by ','.
494 StringTokenizer tokens(filter_string, ",");
495 while (tokens.GetNext()) {
496 bool is_included = true;
497 std::string category = tokens.token();
498 // Ignore empty categories.
499 if(category.empty())
500 continue;
501 // Excluded categories start with '-'.
502 if (category.at(0) == '-') {
503 // Remove '-' from category string.
504 category = category.substr(1);
505 is_included = false;
506 }
507 if (is_included)
508 included_.push_back(category);
509 else
510 excluded_.push_back(category);
511 }
512 }
513
514 void CategoryFilter::WriteString(std::string* out,
515 bool included) const {
516 std::vector<std::string>::const_iterator ci;
517 std::vector<std::string>::const_iterator end;
518 if (included) {
519 ci = included_.begin();
520 end = included_.end();
521 } else {
522 ci = excluded_.begin();
523 end = excluded_.end();
524 }
525
526 for (; ci != end; ++ci) {
527 if (included)
528 StringAppendF(out, "%s,", ci->c_str());
529 else
530 StringAppendF(out, "-%s,", ci->c_str());
531 }
532 }
533
534 void CategoryFilter::ToString(std::string* filter_string) const {
535 WriteString(filter_string, true);
536 WriteString(filter_string, false);
537 }
538
539 bool CategoryFilter::IsCategoryGroupEnabled(const char* category_group_name)
rterrazas 2013/02/20 02:40:06 This does a lot of the work that was done through
540 const {
541 // TraceLog should call this method only as part of enabling/disabling
542 // categories.
543 std::vector<std::string>::const_iterator ci = included_.begin();
544 for (; ci != included_.end(); ++ci) {
545 if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str()))
546 return true;
547 }
548 ci = excluded_.begin();
549 for (; ci != excluded_.end(); ++ci) {
550 if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str()))
551 return false;
552 }
553 // If the category group is not excluded, and there are no included patterns
554 // we consider this pattern enabled.
555 return included_.empty();
556 }
557
558 void CategoryFilter::Merge(const CategoryFilter& nested_filter) {
559 included_.insert(included_.end(),
560 nested_filter.included_.begin(),
561 nested_filter.included_.end());
562 excluded_.insert(excluded_.end(),
563 nested_filter.excluded_.begin(),
564 nested_filter.excluded_.end());
565 }
566
567 bool CategoryFilter::HasIncludedCategories() const {
568 return !included_.empty();
569 }
570
571 void CategoryFilter::Clear() {
572 included_.clear();
573 excluded_.clear();
574 }
575
576 void TraceLog::SetEnabled(const CategoryFilter& category_filter) {
577
578 // Actually enable/disable the categories.
482 AutoLock lock(lock_); 579 AutoLock lock(lock_);
483 580
484 if (enable_count_++ > 0) { 581 if (enable_count_++ > 0) {
485 // Tracing is already enabled, so just merge in enabled categories. 582 // Tracing is already enabled, so just merge in enabled categories.
486 // We only expand the set of enabled categories upon nested SetEnable(). 583 // We only expand the set of enabled categories upon nested SetEnable().
487 if (!included_categories_.empty() && !included_categories.empty()) { 584 if (category_filter_.HasIncludedCategories() &&
488 included_categories_.insert(included_categories_.end(), 585 category_filter.HasIncludedCategories()) {
489 included_categories.begin(), 586 category_filter_.Merge(category_filter);
490 included_categories.end());
491 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0);
492 } else { 587 } else {
493 // If either old or new included categories are empty, allow all events. 588 // If either old or new included categories are empty, allow all not
494 included_categories_.clear(); 589 // excluded events.
495 excluded_categories_.clear(); 590 category_filter_.Clear();
496 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED);
497 } 591 }
592 EnableIncludedCategoryGroups(category_filter_);
498 return; 593 return;
499 } 594 }
500 595
501 if (dispatching_to_observer_list_) { 596 if (dispatching_to_observer_list_) {
502 DLOG(ERROR) << 597 DLOG(ERROR) <<
503 "Cannot manipulate TraceLog::Enabled state from an observer."; 598 "Cannot manipulate TraceLog::Enabled state from an observer.";
504 return; 599 return;
505 } 600 }
506 601
507 dispatching_to_observer_list_ = true; 602 dispatching_to_observer_list_ = true;
508 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, 603 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_,
509 OnTraceLogWillEnable()); 604 OnTraceLogWillEnable());
510 dispatching_to_observer_list_ = false; 605 dispatching_to_observer_list_ = false;
511 606
512 logged_events_.reserve(1024); 607 logged_events_.reserve(1024);
513 included_categories_ = included_categories; 608 category_filter_ = CategoryFilter(category_filter);
514 excluded_categories_ = excluded_categories; 609 EnableIncludedCategoryGroups(category_filter_);
515 // Note that if both included and excluded_categories are empty, the else
516 // clause below excludes nothing, thereby enabling all categories.
517 if (!included_categories_.empty())
518 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0);
519 else
520 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED);
521 } 610 }
522 611
523 void TraceLog::SetEnabled(const std::string& categories) { 612 CategoryFilter& TraceLog::GetCurrentCategoryFilter() {
524 std::vector<std::string> included, excluded;
525 // Tokenize list of categories, delimited by ','.
526 StringTokenizer tokens(categories, ",");
527 while (tokens.GetNext()) {
528 bool is_included = true;
529 std::string category = tokens.token();
530 // Excluded categories start with '-'.
531 if (category.at(0) == '-') {
532 // Remove '-' from category string.
533 category = category.substr(1);
534 is_included = false;
535 }
536 if (is_included)
537 included.push_back(category);
538 else
539 excluded.push_back(category);
540 }
541 SetEnabled(included, excluded);
542 }
543
544 void TraceLog::GetEnabledTraceCategories(
545 std::vector<std::string>* included_out,
546 std::vector<std::string>* excluded_out) {
547 AutoLock lock(lock_); 613 AutoLock lock(lock_);
548 if (enable_count_) { 614 DCHECK(enable_count_ > 0);
549 *included_out = included_categories_; 615 return category_filter_;
550 *excluded_out = excluded_categories_;
551 }
552 } 616 }
553 617
554 void TraceLog::SetDisabled() { 618 void TraceLog::SetDisabled() {
555 AutoLock lock(lock_); 619 AutoLock lock(lock_);
556 DCHECK(enable_count_ > 0); 620 DCHECK(enable_count_ > 0);
557 if (--enable_count_ != 0) 621 if (--enable_count_ != 0)
558 return; 622 return;
559 623
560 if (dispatching_to_observer_list_) { 624 if (dispatching_to_observer_list_) {
561 DLOG(ERROR) 625 DLOG(ERROR)
562 << "Cannot manipulate TraceLog::Enabled state from an observer."; 626 << "Cannot manipulate TraceLog::Enabled state from an observer.";
563 return; 627 return;
564 } 628 }
565 629
566 dispatching_to_observer_list_ = true; 630 dispatching_to_observer_list_ = true;
567 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, 631 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_,
568 OnTraceLogWillDisable()); 632 OnTraceLogWillDisable());
569 dispatching_to_observer_list_ = false; 633 dispatching_to_observer_list_ = false;
570 634
571 included_categories_.clear(); 635 category_filter_.Clear();
572 excluded_categories_.clear();
573 watch_category_ = NULL; 636 watch_category_ = NULL;
574 watch_event_name_ = ""; 637 watch_event_name_ = "";
575 for (int i = 0; i < g_category_index; i++) 638 for (int i = 0; i < g_category_index; i++)
576 g_category_enabled[i] = 0; 639 g_category_enabled[i] = 0;
577 AddThreadNameMetadataEvents(); 640 AddThreadNameMetadataEvents();
578 } 641 }
579 642
580 void TraceLog::SetEnabled(bool enabled) {
581 if (enabled)
582 SetEnabled(std::vector<std::string>(), std::vector<std::string>());
583 else
584 SetDisabled();
585 }
586
587 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { 643 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) {
588 enabled_state_observer_list_.AddObserver(listener); 644 enabled_state_observer_list_.AddObserver(listener);
589 } 645 }
590 646
591 void TraceLog::RemoveEnabledStateObserver( 647 void TraceLog::RemoveEnabledStateObserver(
592 EnabledStateChangedObserver* listener) { 648 EnabledStateChangedObserver* listener) {
593 enabled_state_observer_list_.RemoveObserver(listener); 649 enabled_state_observer_list_.RemoveObserver(listener);
594 } 650 }
595 651
596 float TraceLog::GetBufferPercentFull() const { 652 float TraceLog::GetBufferPercentFull() const {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 0, // num_args 918 0, // num_args
863 NULL, // arg_names 919 NULL, // arg_names
864 NULL, // arg_types 920 NULL, // arg_types
865 NULL, // arg_values 921 NULL, // arg_values
866 TRACE_EVENT_FLAG_NONE); // flags 922 TRACE_EVENT_FLAG_NONE); // flags
867 } 923 }
868 } 924 }
869 925
870 } // namespace trace_event_internal 926 } // namespace trace_event_internal
871 927
OLDNEW
« no previous file with comments | « base/debug/trace_event_impl.h ('k') | base/debug/trace_event_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698