blob: f46a8bd7389b14057b81bd2fff4d528e91e8c440 [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#ifndef SHILL_SCOPE_LOGGER_H_
6#define SHILL_SCOPE_LOGGER_H_
7
8#include <bitset>
9#include <string>
10
11#include <base/basictypes.h>
12#include <base/lazy_instance.h>
13#include <base/logging.h>
14#include <gtest/gtest_prod.h>
15
16// Helper macros to enable logging based on scope and verbose level.
17//
18// The SLOG macro and its variants are similar to the LOG and VLOG macros
19// defined in base/logging.h, except that the SLOG macros take an additional
20// |scope| argument to enable logging only if |scope| is enabled.
21//
22// Like VLOG, SLOG macros internally map verbosity to LOG severity using
23// negative values, i.e. SLOG(scope, 1) corresponds to LOG(-1).
24//
25// Example usages:
26// SLOG(Service, 1) << "Printed when the 'service' scope is enabled and "
27// "the verbose level is greater than or equal to 1";
28//
29// SLOG_IF(Service, 1, (size > 1024))
30// << "Printed when the 'service' scope is enabled, the verbose level "
31// "is greater than or equal to 1, and size is more than 1024";
32//
33// SPLOG and SPLOG_IF are similar to SLOG and SLOG_IF, respectively, but
34// append the last system error to the message in string form, which is
35// taken from errno.
36
37#define SLOG_IS_ON(scope, verbose_level) \
38 ::shill::ScopeLogger::GetInstance()->IsLogEnabled( \
39 ::shill::ScopeLogger::k##scope, -verbose_level)
40
41#define SLOG_STREAM(verbose_level) \
42 ::logging::LogMessage(__FILE__, __LINE__, -verbose_level).stream()
43
44#define SLOG(scope, verbose_level) \
45 LAZY_STREAM(SLOG_STREAM(verbose_level), SLOG_IS_ON(scope, verbose_level))
46
47#define SLOG_IF(scope, verbose_level, condition) \
48 LAZY_STREAM(SLOG_STREAM(verbose_level), \
49 SLOG_IS_ON(scope, verbose_level) && (condition))
50
51#define SPLOG_STREAM(verbose_level) \
52 ::logging::ErrnoLogMessage(__FILE__, __LINE__, -verbose_level, \
53 ::logging::GetLastSystemErrorCode()).stream()
54
55#define SPLOG(scope, verbose_level) \
56 LAZY_STREAM(SPLOG_STREAM(verbose_level), SLOG_IS_ON(scope, verbose_level))
57
58#define SPLOG_IF(scope, verbose_level, condition) \
59 LAZY_STREAM(SPLOG_STREAM(verbose_level), \
60 SLOG_IS_ON(scope, verbose_level) && (condition))
61
62namespace shill {
63
64// A class that enables logging based on scope and verbose level. It is not
65// intended to be used directly but via the SLOG() macros.
66class ScopeLogger {
67 public:
68 // Logging scopes.
69 //
70 // Update kScopeNames in scope_logger.cc after changing this enumerated type.
Ben Chanfad4a0b2012-04-18 15:49:59 -070071 // These scope identifiers are sorted by their scope names alphabetically.
Ben Chanbc49ac72012-04-10 19:59:45 -070072 enum Scope {
73 kCellular = 0,
74 kConnection,
75 kCrypto,
Ben Chanfad4a0b2012-04-18 15:49:59 -070076 kDaemon,
Ben Chanbc49ac72012-04-10 19:59:45 -070077 kDBus,
78 kDevice,
Ben Chanfad4a0b2012-04-18 15:49:59 -070079 kDHCP,
80 kDNS,
Ben Chanbc49ac72012-04-10 19:59:45 -070081 kEthernet,
Ben Chanfad4a0b2012-04-18 15:49:59 -070082 kHTTP,
83 kHTTPProxy,
Ben Chanbc49ac72012-04-10 19:59:45 -070084 kInet,
85 kManager,
86 kMetrics,
87 kModem,
88 kPortal,
Ben Chanfad4a0b2012-04-18 15:49:59 -070089 kPower,
Ben Chanbc49ac72012-04-10 19:59:45 -070090 kProfile,
Ben Chanfad4a0b2012-04-18 15:49:59 -070091 kProperty,
92 kResolver,
93 kRoute,
Ben Chanbc49ac72012-04-10 19:59:45 -070094 kRTNL,
95 kService,
96 kStorage,
97 kTask,
98 kVPN,
99 kWiFi,
Darin Petkov096b3472012-05-15 10:26:22 +0200100 kWiMax,
Ben Chanbc49ac72012-04-10 19:59:45 -0700101 kNumScopes
102 };
103
104 // Returns a singleton of this class.
105 static ScopeLogger *GetInstance();
106
107 ~ScopeLogger();
108
109 // Returns true if logging is enabled for |scope| and |verbose_level|, i.e.
110 // scope_enable_[|scope|] is true and |verbose_level| <= |verbose_level_|
111 bool IsLogEnabled(Scope scope, int verbose_level) const;
112
113 // Returns a string comprising the names, separated by commas, of all scopes.
114 std::string GetAllScopeNames() const;
115
116 // Returns a string comprising the names, separated by plus signs, of all
117 // scopes that are enabled for logging.
118 std::string GetEnabledScopeNames() const;
119
120 // Enables/disables scopes as specified by |expression|.
121 //
122 // |expression| is a string comprising a sequence of scope names, each
123 // prefixed by a plus '+' or minus '-' sign. A scope prefixed by a plus
124 // sign is enabled for logging, whereas a scope prefixed by a minus sign
125 // is disabled for logging. Scopes that are not mentioned in |expression|
126 // remain the same state.
127 //
128 // To allow resetting the state of all scopes, an exception is made for the
129 // first scope name in the sequence, which may not be prefixed by any sign.
130 // That is considered as an implicit plus sign for that scope and also
131 // indicates that all scopes are first disabled before enabled by
132 // |expression|.
133 //
134 // If |expression| is an empty string, all scopes are disabled. Any unknown
135 // scope name found in |expression| is ignored.
136 void EnableScopesByName(const std::string &expression);
137
138 // Sets the verbose level for all scopes to |verbose_level|.
139 void set_verbose_level(int verbose_level) { verbose_level_ = verbose_level; }
140
141 private:
142 // Required for constructing LazyInstance<ScopeLogger>.
143 friend struct base::DefaultLazyInstanceTraits<ScopeLogger>;
144 friend class ScopeLoggerTest;
145 FRIEND_TEST(ScopeLoggerTest, GetEnabledScopeNames);
146 FRIEND_TEST(ScopeLoggerTest, SetScopeEnabled);
147 FRIEND_TEST(ScopeLoggerTest, SetVerboseLevel);
148
149 // Disables logging for all scopes.
150 void DisableAllScopes();
151
152 // Enables or disables logging for |scope|.
153 void SetScopeEnabled(Scope scope, bool enabled);
154
155 // Boolean values to indicate whether logging is enabled for each scope.
156 std::bitset<kNumScopes> scope_enabled_;
157
158 // Verbose level that is applied to all scopes.
159 int verbose_level_;
160
161 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeLogger);
162};
163
164} // namespace shill
165
166#endif // SHILL_SCOPE_LOGGER_H_