Implemented VLOG() et al.

Implemented VLOG(), VLOG_IF(), VLOG_IS_ON().  Added --v and --vmodule
switches.

Changed some spammy sync-related logs to use VLOG.

BUG=56965
TEST=New unittests

Review URL: http://codereview.chromium.org/3448028

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60976 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/base/logging.h b/base/logging.h
index 2084739f..72f7274e 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -74,6 +74,39 @@
 //
 // which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion;
 //
+// There are "verbose level" logging macros.  They look like
+//
+//   VLOG(1) << "I'm printed when you run the program with --v=1 or more";
+//   VLOG(2) << "I'm printed when you run the program with --v=2 or more";
+//
+// These always log at the INFO log level (when they log at all).
+// The verbose logging can also be turned on module-by-module.  For instance,
+//    --vmodule=profile=2,icon_loader=1,browser_*=3 --v=0
+// will cause:
+//   a. VLOG(2) and lower messages to be printed from profile.{h,cc}
+//   b. VLOG(1) and lower messages to be printed from icon_loader.{h,cc}
+//   c. VLOG(3) and lower messages to be printed from files prefixed with
+//      "browser"
+//   d. VLOG(0) and lower messages to be printed from elsewhere
+//
+// The wildcarding functionality shown by (c) supports both '*' (match
+// 0 or more characters) and '?' (match any single character) wildcards.
+//
+// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as
+//
+//   if (VLOG_IS_ON(2)) {
+//     // do some logging preparation and logging
+//     // that can't be accomplished with just VLOG(2) << ...;
+//   }
+//
+// There is also a VLOG_IF "verbose level" condition macro for sample
+// cases, when some extra computation and preparation for logs is not
+// needed.
+//
+//   VLOG_IF(1, (size > 1024))
+//      << "I'm printed when size is more than 1024 and when you run the "
+//         "program with --v=1 or more";
+//
 // We also override the standard 'assert' to use 'DLOG_ASSERT'.
 //
 // Lastly, there is:
@@ -177,6 +210,15 @@
 // Gets the current log level.
 int GetMinLogLevel();
 
+// Gets the current vlog level for the given file (usually taken from
+// __FILE__).
+template <size_t N>
+int GetVlogLevel(const char (&file)[N]) {
+  return GetVlogLevelHelper(file, N);
+}
+// Note that |N| is the size *with* the null terminator.
+int GetVlogLevelHelper(const char* file_start, size_t N);
+
 // Sets the log filter prefix.  Any log message below LOG_ERROR severity that
 // doesn't start with this prefix with be silently ignored.  The filter defaults
 // to NULL (everything is logged) if this function is not called.  Messages
@@ -279,13 +321,25 @@
 // impossible to stream something like a string directly to an unnamed
 // ostream. We employ a neat hack by calling the stream() member
 // function of LogMessage which seems to avoid the problem.
+//
+// We can't do any caching tricks with VLOG_IS_ON() like the
+// google-glog version since it requires GCC extensions.  This means
+// that using the v-logging functions in conjunction with --vmodule
+// may be slow.
+#define VLOG_IS_ON(verboselevel) \
+  (logging::GetVlogLevel(__FILE__) >= (verboselevel))
 
 #define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
 #define SYSLOG(severity) LOG(severity)
+#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel))
+
+// TODO(akalin): Add more VLOG variants, e.g. VPLOG.
 
 #define LOG_IF(severity, condition) \
   !(condition) ? (void) 0 : logging::LogMessageVoidify() & LOG(severity)
 #define SYSLOG_IF(severity, condition) LOG_IF(severity, condition)
+#define VLOG_IF(verboselevel, condition) \
+  LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel))
 
 #define LOG_ASSERT(condition)  \
   LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". "