1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef SHILL_SCOPE_LOGGER_H_
18 #define SHILL_SCOPE_LOGGER_H_
19 
20 #include <bitset>
21 #include <string>
22 #include <vector>
23 
24 #include <base/lazy_instance.h>
25 #include <base/macros.h>
26 #include <gtest/gtest_prod.h>
27 
28 #include "shill/callbacks.h"
29 
30 namespace shill {
31 
32 // A class that enables logging based on scope and verbose level. It is not
33 // intended to be used directly but via the SLOG() macros in shill/logging.h
34 class ScopeLogger {
35  public:
36   // Logging scopes.
37   //
38   // Update kScopeNames in scope_logger.cc after changing this enumerated type.
39   // These scope identifiers are sorted by their scope names alphabetically.
40   enum Scope {
41     kBinder = 0,
42     kCellular,
43     kConnection,
44     kCrypto,
45     kDaemon,
46     kDBus,
47     kDevice,
48     kDHCP,
49     kDNS,
50     kEthernet,
51     kHTTP,
52     kHTTPProxy,
53     kInet,
54     kLink,
55     kManager,
56     kMetrics,
57     kModem,
58     kPortal,
59     kPower,
60     kPPP,
61     kPPPoE,
62     kProfile,
63     kProperty,
64     kResolver,
65     kRoute,
66     kRTNL,
67     kService,
68     kStorage,
69     kTask,
70     kVPN,
71     kWiFi,
72     kWiMax,
73     kNumScopes
74   };
75 
76   typedef base::Callback<void(bool)> ScopeEnableChangedCallback;
77   typedef std::vector<ScopeEnableChangedCallback>ScopeEnableChangedCallbacks;
78 
79   // Returns a singleton of this class.
80   static ScopeLogger* GetInstance();
81 
82   ScopeLogger();
83   ~ScopeLogger();
84 
85   // Returns true if logging is enabled for |scope| and |verbose_level|, i.e.
86   // scope_enable_[|scope|] is true and |verbose_level| <= |verbose_level_|
87   bool IsLogEnabled(Scope scope, int verbose_level) const;
88 
89   // Returns true if logging is enabled for |scope| at any verbosity level.
90   bool IsScopeEnabled(Scope scope) const;
91 
92   // Returns a string comprising the names, separated by commas, of all scopes.
93   std::string GetAllScopeNames() const;
94 
95   // Returns a string comprising the names, separated by plus signs, of all
96   // scopes that are enabled for logging.
97   std::string GetEnabledScopeNames() const;
98 
99   // Enables/disables scopes as specified by |expression|.
100   //
101   // |expression| is a string comprising a sequence of scope names, each
102   // prefixed by a plus '+' or minus '-' sign. A scope prefixed by a plus
103   // sign is enabled for logging, whereas a scope prefixed by a minus sign
104   // is disabled for logging. Scopes that are not mentioned in |expression|
105   // remain the same state.
106   //
107   // To allow resetting the state of all scopes, an exception is made for the
108   // first scope name in the sequence, which may not be prefixed by any sign.
109   // That is considered as an implicit plus sign for that scope and also
110   // indicates that all scopes are first disabled before enabled by
111   // |expression|.
112   //
113   // If |expression| is an empty string, all scopes are disabled. Any unknown
114   // scope name found in |expression| is ignored.
115   void EnableScopesByName(const std::string& expression);
116 
117   // Register for log scope enable/disable state changes for |scope|.
118   void RegisterScopeEnableChangedCallback(
119       Scope scope, ScopeEnableChangedCallback callback);
120 
121   // Sets the verbose level for all scopes to |verbose_level|.
set_verbose_level(int verbose_level)122   void set_verbose_level(int verbose_level) { verbose_level_ = verbose_level; }
123 
124  private:
125   // Required for constructing LazyInstance<ScopeLogger>.
126   friend struct base::DefaultLazyInstanceTraits<ScopeLogger>;
127   friend class ScopeLoggerTest;
128   FRIEND_TEST(ScopeLoggerTest, GetEnabledScopeNames);
129   FRIEND_TEST(ScopeLoggerTest, SetScopeEnabled);
130   FRIEND_TEST(ScopeLoggerTest, SetVerboseLevel);
131 
132   // Disables logging for all scopes.
133   void DisableAllScopes();
134 
135   // Enables or disables logging for |scope|.
136   void SetScopeEnabled(Scope scope, bool enabled);
137 
138   // Boolean values to indicate whether logging is enabled for each scope.
139   std::bitset<kNumScopes> scope_enabled_;
140 
141   // Verbose level that is applied to all scopes.
142   int verbose_level_;
143 
144   // Hooks to notify interested parties of changes to log scopes.
145   ScopeEnableChangedCallbacks log_scope_callbacks_[kNumScopes];
146 
147   DISALLOW_COPY_AND_ASSIGN(ScopeLogger);
148 };
149 
150 }  // namespace shill
151 
152 #endif  // SHILL_SCOPE_LOGGER_H_
153