blob: e3951cfbc1931b9a2ebcea2ea3517229c6716e9b [file] [log] [blame]
Ben Chanbc49ac72012-04-10 19:59:45 -07001// Copyright (c) 2012 The Chromium OS 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 "shill/scope_logger.h"
6
7#include <vector>
8
9#include <base/string_tokenizer.h>
10#include <base/string_util.h>
11
12using std::string;
13using std::vector;
14
15namespace shill {
16
17namespace {
18
19const int kDefaultVerboseLevel = 0;
20
21// Scope names corresponding to the scope defined by ScopeLogger::Scope.
22const char *const kScopeNames[] = {
23 "cellular",
24 "connection",
25 "crypto",
26 "dbus",
27 "device",
28 "dhclient",
29 "ethernet",
30 "inet",
31 "manager",
32 "metrics",
33 "modem",
34 "portal",
35 "profile",
36 "resolv",
37 "resolvfiles",
38 "rtnl",
39 "service",
40 "storage",
41 "task",
42 "vpn",
43 "wifi",
44};
45
46COMPILE_ASSERT(arraysize(kScopeNames) == ScopeLogger::kNumScopes,
47 scope_tags_does_not_have_expected_number_of_strings);
48
49// TODO(benchan): not using LAZY_INSTANCE_INITIALIZER
50// because of http://crbug.com/114828
51base::LazyInstance<ScopeLogger> g_scope_logger = {0, {{0}}};
52
53} // namespace
54
55// static
56ScopeLogger* ScopeLogger::GetInstance() {
57 return g_scope_logger.Pointer();
58}
59
60ScopeLogger::ScopeLogger()
61 : verbose_level_(kDefaultVerboseLevel) {
62}
63
64ScopeLogger::~ScopeLogger() {
65}
66
67bool ScopeLogger::IsLogEnabled(Scope scope, int verbose_level) const {
68 CHECK_GE(scope, 0);
69 CHECK_LT(scope, kNumScopes);
70
71 return scope_enabled_[scope] && verbose_level <= verbose_level_;
72}
73
74string ScopeLogger::GetAllScopeNames() const {
75 vector<string> names(kScopeNames, kScopeNames + arraysize(kScopeNames));
Ben Chan1c722602012-04-17 17:37:35 -070076 return JoinString(names, '+');
Ben Chanbc49ac72012-04-10 19:59:45 -070077}
78
79string ScopeLogger::GetEnabledScopeNames() const {
80 vector<string> names;
81 for (size_t i = 0; i < arraysize(kScopeNames); ++i) {
82 if (scope_enabled_[i])
83 names.push_back(kScopeNames[i]);
84 }
85 return JoinString(names, '+');
86}
87
88void ScopeLogger::EnableScopesByName(const string &expression) {
89 if (expression.empty()) {
90 DisableAllScopes();
91 return;
92 }
93
94 // As described in the header file, if the first scope name in the
95 // sequence specified by |expression| is not prefixed by a plus or
96 // minus sign, it indicates that all scopes are first disabled before
97 // enabled by |expression|.
98 if (expression[0] != '+' && expression[0] != '-')
99 DisableAllScopes();
100
101 bool enable_scope = true;
102 StringTokenizer tokenizer(expression, "+-");
103 tokenizer.set_options(StringTokenizer::RETURN_DELIMS);
104 while (tokenizer.GetNext()) {
105 if (tokenizer.token_is_delim()) {
106 enable_scope = (tokenizer.token() == "+");
107 continue;
108 }
109
110 if (tokenizer.token().empty())
111 continue;
112
113 size_t i;
114 for (i = 0; i < arraysize(kScopeNames); ++i) {
115 if (tokenizer.token() == kScopeNames[i]) {
116 SetScopeEnabled(static_cast<Scope>(i), enable_scope);
117 break;
118 }
119 }
120 LOG_IF(WARNING, i == arraysize(kScopeNames))
121 << "Unknown scope '" << tokenizer.token() << "'";
122 }
123}
124
125void ScopeLogger::DisableAllScopes() {
126 scope_enabled_.reset();
127}
128
129void ScopeLogger::SetScopeEnabled(Scope scope, bool enabled) {
130 CHECK_GE(scope, 0);
131 CHECK_LT(scope, kNumScopes);
132
133 scope_enabled_[scope] = enabled;
134}
135
136} // namespace shill