blob: 76c541d441f889435265b4f277d7e83fa1fef34e [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
Paul Stewart5ad16062013-02-21 18:10:48 -08009#include <base/strings/string_tokenizer.h>
Ben Chana0ddf462014-02-06 11:32:42 -080010#include <base/strings/string_util.h>
Ben Chanbc49ac72012-04-10 19:59:45 -070011
Paul Stewart5ad16062013-02-21 18:10:48 -080012using base::StringTokenizer;
Ben Chanbc49ac72012-04-10 19:59:45 -070013using std::string;
14using std::vector;
15
16namespace shill {
17
18namespace {
19
20const int kDefaultVerboseLevel = 0;
21
22// Scope names corresponding to the scope defined by ScopeLogger::Scope.
Paul Stewart1a212a62015-06-16 13:13:10 -070023const char* const kScopeNames[] = {
Ben Chanbc49ac72012-04-10 19:59:45 -070024 "cellular",
25 "connection",
26 "crypto",
Ben Chanfad4a0b2012-04-18 15:49:59 -070027 "daemon",
Ben Chanbc49ac72012-04-10 19:59:45 -070028 "dbus",
29 "device",
Ben Chanfad4a0b2012-04-18 15:49:59 -070030 "dhcp",
31 "dns",
Ben Chanbc49ac72012-04-10 19:59:45 -070032 "ethernet",
Ben Chanfad4a0b2012-04-18 15:49:59 -070033 "http",
34 "httpproxy",
Ben Chanbc49ac72012-04-10 19:59:45 -070035 "inet",
Paul Stewart6c72c972012-07-27 11:29:20 -070036 "link",
Ben Chanbc49ac72012-04-10 19:59:45 -070037 "manager",
38 "metrics",
39 "modem",
40 "portal",
Ben Chanfad4a0b2012-04-18 15:49:59 -070041 "power",
mukesh agrawal9da07772013-05-15 14:15:17 -070042 "ppp",
Garret Kelly2dc218e2015-01-30 11:16:34 -050043 "pppoe",
Ben Chanbc49ac72012-04-10 19:59:45 -070044 "profile",
Ben Chanfad4a0b2012-04-18 15:49:59 -070045 "property",
46 "resolver",
47 "route",
Ben Chanbc49ac72012-04-10 19:59:45 -070048 "rtnl",
49 "service",
50 "storage",
51 "task",
52 "vpn",
53 "wifi",
Darin Petkov096b3472012-05-15 10:26:22 +020054 "wimax",
Ben Chanbc49ac72012-04-10 19:59:45 -070055};
56
57COMPILE_ASSERT(arraysize(kScopeNames) == ScopeLogger::kNumScopes,
58 scope_tags_does_not_have_expected_number_of_strings);
59
Ben Chanfdfdc872012-04-24 08:31:36 -070060// ScopeLogger needs to be a 'leaky' singleton as it needs to survive to
61// handle logging till the very end of the shill process. Making ScopeLogger
62// leaky is fine as it does not need to clean up or release any resource at
63// destruction.
64base::LazyInstance<ScopeLogger>::Leaky g_scope_logger =
65 LAZY_INSTANCE_INITIALIZER;
Ben Chanbc49ac72012-04-10 19:59:45 -070066
67} // namespace
68
69// static
70ScopeLogger* ScopeLogger::GetInstance() {
71 return g_scope_logger.Pointer();
72}
73
74ScopeLogger::ScopeLogger()
75 : verbose_level_(kDefaultVerboseLevel) {
76}
77
78ScopeLogger::~ScopeLogger() {
79}
80
81bool ScopeLogger::IsLogEnabled(Scope scope, int verbose_level) const {
Paul Stewart5581d072012-12-17 17:30:20 -080082 return IsScopeEnabled(scope) && verbose_level <= verbose_level_;
83}
84
85bool ScopeLogger::IsScopeEnabled(Scope scope) const {
Ben Chanbc49ac72012-04-10 19:59:45 -070086 CHECK_GE(scope, 0);
87 CHECK_LT(scope, kNumScopes);
88
Paul Stewart5581d072012-12-17 17:30:20 -080089 return scope_enabled_[scope];
Ben Chanbc49ac72012-04-10 19:59:45 -070090}
91
92string ScopeLogger::GetAllScopeNames() const {
93 vector<string> names(kScopeNames, kScopeNames + arraysize(kScopeNames));
Ben Chan1c722602012-04-17 17:37:35 -070094 return JoinString(names, '+');
Ben Chanbc49ac72012-04-10 19:59:45 -070095}
96
97string ScopeLogger::GetEnabledScopeNames() const {
98 vector<string> names;
99 for (size_t i = 0; i < arraysize(kScopeNames); ++i) {
100 if (scope_enabled_[i])
101 names.push_back(kScopeNames[i]);
102 }
103 return JoinString(names, '+');
104}
105
Paul Stewart1a212a62015-06-16 13:13:10 -0700106void ScopeLogger::EnableScopesByName(const string& expression) {
Ben Chanbc49ac72012-04-10 19:59:45 -0700107 if (expression.empty()) {
108 DisableAllScopes();
109 return;
110 }
111
112 // As described in the header file, if the first scope name in the
113 // sequence specified by |expression| is not prefixed by a plus or
114 // minus sign, it indicates that all scopes are first disabled before
115 // enabled by |expression|.
116 if (expression[0] != '+' && expression[0] != '-')
117 DisableAllScopes();
118
119 bool enable_scope = true;
120 StringTokenizer tokenizer(expression, "+-");
121 tokenizer.set_options(StringTokenizer::RETURN_DELIMS);
122 while (tokenizer.GetNext()) {
123 if (tokenizer.token_is_delim()) {
124 enable_scope = (tokenizer.token() == "+");
125 continue;
126 }
127
128 if (tokenizer.token().empty())
129 continue;
130
131 size_t i;
132 for (i = 0; i < arraysize(kScopeNames); ++i) {
133 if (tokenizer.token() == kScopeNames[i]) {
134 SetScopeEnabled(static_cast<Scope>(i), enable_scope);
135 break;
136 }
137 }
138 LOG_IF(WARNING, i == arraysize(kScopeNames))
139 << "Unknown scope '" << tokenizer.token() << "'";
140 }
141}
142
Paul Stewart5581d072012-12-17 17:30:20 -0800143void ScopeLogger::RegisterScopeEnableChangedCallback(
144 Scope scope, ScopeEnableChangedCallback callback) {
145 CHECK_GE(scope, 0);
146 CHECK_LT(scope, kNumScopes);
147 log_scope_callbacks_[scope].push_back(callback);
148}
149
Ben Chanbc49ac72012-04-10 19:59:45 -0700150void ScopeLogger::DisableAllScopes() {
Paul Stewart5581d072012-12-17 17:30:20 -0800151 // Iterate over all scopes so the notification side-effect occurs.
152 for (size_t i = 0; i < arraysize(kScopeNames); ++i) {
153 SetScopeEnabled(static_cast<Scope>(i), false);
154 }
Ben Chanbc49ac72012-04-10 19:59:45 -0700155}
156
157void ScopeLogger::SetScopeEnabled(Scope scope, bool enabled) {
158 CHECK_GE(scope, 0);
159 CHECK_LT(scope, kNumScopes);
160
Paul Stewart5581d072012-12-17 17:30:20 -0800161 if (scope_enabled_[scope] != enabled) {
Paul Stewart1a212a62015-06-16 13:13:10 -0700162 for (const auto& callback : log_scope_callbacks_[scope]) {
Paul Stewart6db7b242014-05-02 15:34:21 -0700163 callback.Run(enabled);
Paul Stewart5581d072012-12-17 17:30:20 -0800164 }
165 }
166
Ben Chanbc49ac72012-04-10 19:59:45 -0700167 scope_enabled_[scope] = enabled;
168}
169
170} // namespace shill