scope_logger.h revision d34a47c06c38f2594c85b14b0f9cee2bf37c0e84
1// 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. 71 // These scope identifiers are sorted by their scope names alphabetically. 72 enum Scope { 73 kCellular = 0, 74 kConnection, 75 kCrypto, 76 kDaemon, 77 kDBus, 78 kDevice, 79 kDHCP, 80 kDNS, 81 kEthernet, 82 kHTTP, 83 kHTTPProxy, 84 kInet, 85 kManager, 86 kMetrics, 87 kModem, 88 kPortal, 89 kPower, 90 kProfile, 91 kProperty, 92 kResolver, 93 kRoute, 94 kRTNL, 95 kService, 96 kStorage, 97 kTask, 98 kVPN, 99 kWiFi, 100 kWiMax, 101 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_ 167