1// Copyright 2011 Google Inc. All Rights Reserved.
2// Author: settinger@google.com (Scott Ettinger)
3
4// Simplified Google3 style logging with Android support.
5// Supported macros are : LOG(INFO), LOG(WARNING), LOG(ERROR), LOG(FATAL),
6//                        and VLOG(n).
7//
8// Portions of this code are taken from the GLOG package.  This code
9// is only a small subset of the GLOG functionality. And like GLOG,
10// higher levels are more verbose.
11//
12// Notable differences from GLOG :
13//
14// 1. lack of support for displaying unprintable characters and lack
15// of stack trace information upon failure of the CHECK macros.
16// 2. All output is tagged with the string "native".
17// 3. While there is no runtime flag filtering logs (-v, -vmodule), the
18//    compile time define MAX_LOG_LEVEL can be used to silence any
19//    logging above the given level.
20//
21// -------------------------------- Usage ------------------------------------
22// Basic usage :
23// LOG(<severity level>) acts as a c++ stream to the Android logcat output.
24// e.g. LOG(INFO) << "Value of counter = " << counter;
25//
26// Valid severity levels include INFO, WARNING, ERROR, FATAL.
27// The various severity levels are routed to the corresponding Android logcat
28// output.
29// LOG(FATAL) outputs to the log and then terminates.
30//
31// VLOG(<severity level>) can also be used.
32// VLOG(n) output is directed to the Android logcat levels as follows :
33//  >=2 - Verbose
34//    1 - Debug
35//    0 - Info
36//   -1 - Warning
37//   -2 - Error
38// <=-3 - Fatal
39// Note that VLOG(FATAL) will terminate the program.
40//
41// CHECK macros are defined to test for conditions within code.  Any CHECK
42// that fails will log the failure and terminate the application.
43// e.g. CHECK_GE(3, 2) will pass while CHECK_GE(3, 4) will fail after logging
44//      "Check failed 3 >= 4".
45// The following CHECK macros are defined :
46//
47// CHECK(condition) - fails if condition is false and logs condition.
48// CHECK_NOTNULL(variable) - fails if the variable is NULL.
49//
50// The following binary check macros are also defined :
51//    Macro                 operator applied
52// ------------------------------------------
53// CHECK_EQ(val1, val2)      val1 == val2
54// CHECK_NE(val1, val2)      val1 != val2
55// CHECK_GT(val1, val2)      val1 > val2
56// CHECK_GE(val1, val2)      val1 >= val2
57// CHECK_LT(val1, val2)      val1 < val2
58// CHECK_LE(val1, val2)      val1 <= val2
59//
60// Debug only versions of all of the check macros are also defined.  These
61// macros generate no code in a release build, but avoid unused variable
62// warnings / errors.
63// To use the debug only versions, Prepend a D to the normal check macros.
64// e.g. DCHECK_EQ(a, b);
65
66#ifndef MOBILE_BASE_LOGGING_H_
67#define MOBILE_BASE_LOGGING_H_
68
69// Definitions for building on an Android system.
70#include <android/log.h>
71#include <time.h>
72
73#include <algorithm>
74#include <iostream>
75#include <string>
76#include <fstream>
77#include <set>
78#include <sstream>
79#include <vector>
80
81// Log severity level constants.
82const int FATAL   = -3;
83const int ERROR   = -2;
84const int WARNING = -1;
85const int INFO    =  0;
86
87// ------------------------- Glog compatibility ------------------------------
88
89namespace google {
90
91typedef int LogSeverity;
92const int INFO    = ::INFO;
93const int WARNING = ::WARNING;
94const int ERROR   = ::ERROR;
95const int FATAL   = ::FATAL;
96
97#ifdef ENABLE_LOG_SINKS
98
99// Sink class used for integration with mock and test functions.
100// If sinks are added, all log output is also sent to each sink through
101// the send function.  In this implementation, WaitTillSent() is called
102// immediately after the send.
103// This implementation is not thread safe.
104class LogSink {
105 public:
106  virtual ~LogSink() {}
107  virtual void send(LogSeverity severity, const char* full_filename,
108                    const char* base_filename, int line,
109                    const struct tm* tm_time,
110                    const char* message, size_t message_len) = 0;
111  virtual void WaitTillSent() = 0;
112};
113
114// Global set of log sinks.
115// TODO(settinger): Move this into a .cc file.
116static std::set<LogSink *> log_sinks_global;
117
118// Note: the Log sink functions are not thread safe.
119inline void AddLogSink(LogSink *sink) {
120  // TODO(settinger): Add locks for thread safety.
121  log_sinks_global.insert(sink);
122}
123inline void RemoveLogSink(LogSink *sink) {
124  log_sinks_global.erase(sink);
125}
126
127#endif  // #ifdef ENABLE_LOG_SINKS
128
129inline void InitGoogleLogging(char *argv) {}
130
131}  // namespace google
132
133// ---------------------------- Logger Class --------------------------------
134
135// Class created for each use of the logging macros.
136// The logger acts as a stream and routes the final stream contents to the
137// Android logcat output at the proper filter level.  This class should not
138// be directly instantiated in code, rather it should be invoked through the
139// use of the log macros LOG, or VLOG.
140class MessageLogger {
141 public:
142  MessageLogger(const char *file, int line, const char *tag, int severity)
143    : file_(file), line_(line), tag_(tag), severity_(severity) {
144    // Pre-pend the stream with the file and line number.
145    StripBasename(std::string(file), &filename_only_);
146    stream_ << filename_only_ << ":" << line << " ";
147  }
148
149  // Output the contents of the stream to the proper channel on destruction.
150  ~MessageLogger() {
151#ifdef MAX_LOG_LEVEL
152    if (severity_ > MAX_LOG_LEVEL && severity_ > FATAL) {
153      return;
154    }
155#endif
156    stream_ << "\n";
157    static const int android_log_levels[] = {
158        ANDROID_LOG_FATAL,    // LOG(FATAL)
159        ANDROID_LOG_ERROR,    // LOG(ERROR)
160        ANDROID_LOG_WARN,     // LOG(WARNING)
161        ANDROID_LOG_INFO,     // LOG(INFO), VLOG(0)
162        ANDROID_LOG_DEBUG,    // VLOG(1)
163        ANDROID_LOG_VERBOSE,  // VLOG(2) .. VLOG(N)
164    };
165
166    // Bound the logging level.
167    const int kMaxVerboseLevel = 2;
168    int android_level_index = std::min(std::max(FATAL, severity_),
169                                       kMaxVerboseLevel) - FATAL;
170    int android_log_level = android_log_levels[android_level_index];
171
172    // Output the log string the Android log at the appropriate level.
173    __android_log_write(android_log_level, tag_.c_str(), stream_.str().c_str());
174
175    // Indicate termination if needed.
176    if (severity_ == FATAL) {
177      __android_log_write(ANDROID_LOG_FATAL,
178                          tag_.c_str(),
179                          "terminating.\n");
180    }
181
182#ifdef ENABLE_LOG_SINKS
183
184    LogToSinks(severity_);
185    WaitForSinks();
186
187#endif  // #ifdef ENABLE_LOG_SINKS
188
189    // Android logging at level FATAL does not terminate execution, so abort()
190    // is still required to stop the program.
191    if (severity_ == FATAL) {
192      abort();
193    }
194  }
195
196  // Return the stream associated with the logger object.
197  std::stringstream &stream() { return stream_; }
198
199 private:
200#ifdef ENABLE_LOG_SINKS
201
202  void LogToSinks(int severity) {
203    time_t rawtime;
204    struct tm * timeinfo;
205
206    time ( &rawtime );
207    timeinfo = localtime ( &rawtime );
208    std::set<google::LogSink *>::iterator iter;
209    // Send the log message to all sinks.
210    for (iter = google::log_sinks_global.begin();
211         iter != google::log_sinks_global.end(); ++iter)
212      (*iter)->send(severity, file_.c_str(), filename_only_.c_str(), line_,
213                    timeinfo, stream_.str().c_str(), stream_.str().size());
214  }
215
216  void WaitForSinks() {
217    // TODO(settinger): add locks for thread safety.
218    std::set<google::LogSink *>::iterator iter;
219    // Call WaitTillSent() for all sinks.
220    for (iter = google::log_sinks_global.begin();
221         iter != google::log_sinks_global.end(); ++iter)
222      (*iter)->WaitTillSent();
223  }
224
225#endif // #ifdef ENABLE_LOG_SINKS
226
227  void StripBasename(const std::string &full_path, std::string *filename) {
228    // TODO(settinger): add support for OS with different path separators.
229    const char kSeparator = '/';
230    size_t pos = full_path.rfind(kSeparator);
231    if (pos != std::string::npos)
232      *filename = full_path.substr(pos + 1, std::string::npos);
233    else
234      *filename = full_path;
235  }
236
237  std::string file_;
238  std::string filename_only_;
239  int line_;
240  std::string tag_;
241  std::stringstream stream_;
242  int severity_;
243};
244
245// ---------------------- Logging Macro definitions --------------------------
246
247// This class is used to explicitly ignore values in the conditional
248// logging macros.  This avoids compiler warnings like "value computed
249// is not used" and "statement has no effect".
250class LoggerVoidify {
251 public:
252  LoggerVoidify() { }
253  // This has to be an operator with a precedence lower than << but
254  // higher than ?:
255  void operator&(const std::ostream &s) { }
256};
257
258// Log only if condition is met.  Otherwise evaluates to void.
259#define LOG_IF(severity, condition) \
260  !(condition) ? (void) 0 : LoggerVoidify() & \
261    MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream()
262
263// Log only if condition is NOT met.  Otherwise evaluates to void.
264#define LOG_IF_FALSE(severity, condition) LOG_IF(severity, !(condition))
265
266// LG is a convenient shortcut for LOG(INFO). Its use is in new
267// google3 code is discouraged and the following shortcut exists for
268// backward compatibility with existing code.
269#ifdef MAX_LOG_LEVEL
270#define LOG(n) LOG_IF(n, n <= MAX_LOG_LEVEL)
271#define VLOG(n) LOG_IF(n, n <= MAX_LOG_LEVEL)
272#define LG LOG_IF(INFO, INFO <= MAX_LOG_LEVEL)
273#else
274#define LOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", n).stream()
275#define VLOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", n).stream()
276#define LG MessageLogger((char *)__FILE__, __LINE__, "native", INFO).stream()
277#endif
278
279// Currently, VLOG is always on for levels below MAX_LOG_LEVEL.
280#ifndef MAX_LOG_LEVEL
281#define VLOG_IS_ON(x) (1)
282#else
283#define VLOG_IS_ON(x) (x <= MAX_LOG_LEVEL)
284#endif
285
286#ifndef NDEBUG
287#define DLOG LOG
288#else
289#define DLOG(severity) true ? (void) 0 : LoggerVoidify() & \
290    MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream()
291#endif
292
293// ---------------------------- CHECK helpers --------------------------------
294
295// Log a message and terminate.
296template<class T>
297void LogMessageFatal(const char *file, int line, const T &message) {
298  MessageLogger((char *)__FILE__, __LINE__, "native", FATAL).stream()
299      << message;
300}
301
302// ---------------------------- CHECK macros ---------------------------------
303
304// Check for a given boolean condition.
305#define CHECK(condition) LOG_IF_FALSE(FATAL, condition) \
306        << "Check failed: " #condition " "
307
308#ifndef NDEBUG
309// Debug only version of CHECK
310#define DCHECK(condition) LOG_IF_FALSE(FATAL, condition) \
311        << "Check failed: " #condition " "
312#else
313// Optimized version - generates no code.
314#define DCHECK(condition) if (false) LOG_IF_FALSE(FATAL, condition) \
315        << "Check failed: " #condition " "
316#endif  // NDEBUG
317
318// ------------------------- CHECK_OP macros ---------------------------------
319
320// Generic binary operator check macro. This should not be directly invoked,
321// instead use the binary comparison macros defined below.
322#define CHECK_OP(val1, val2, op) LOG_IF_FALSE(FATAL, (val1 op val2)) \
323  << "Check failed: " #val1 " " #op " " #val2 " "
324
325// Check_op macro definitions
326#define CHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==)
327#define CHECK_NE(val1, val2) CHECK_OP(val1, val2, !=)
328#define CHECK_LE(val1, val2) CHECK_OP(val1, val2, <=)
329#define CHECK_LT(val1, val2) CHECK_OP(val1, val2, <)
330#define CHECK_GE(val1, val2) CHECK_OP(val1, val2, >=)
331#define CHECK_GT(val1, val2) CHECK_OP(val1, val2, >)
332
333#ifndef NDEBUG
334// Debug only versions of CHECK_OP macros.
335#define DCHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==)
336#define DCHECK_NE(val1, val2) CHECK_OP(val1, val2, !=)
337#define DCHECK_LE(val1, val2) CHECK_OP(val1, val2, <=)
338#define DCHECK_LT(val1, val2) CHECK_OP(val1, val2, <)
339#define DCHECK_GE(val1, val2) CHECK_OP(val1, val2, >=)
340#define DCHECK_GT(val1, val2) CHECK_OP(val1, val2, >)
341#else
342// These versions generate no code in optimized mode.
343#define DCHECK_EQ(val1, val2) if (false) CHECK_OP(val1, val2, ==)
344#define DCHECK_NE(val1, val2) if (false) CHECK_OP(val1, val2, !=)
345#define DCHECK_LE(val1, val2) if (false) CHECK_OP(val1, val2, <=)
346#define DCHECK_LT(val1, val2) if (false) CHECK_OP(val1, val2, <)
347#define DCHECK_GE(val1, val2) if (false) CHECK_OP(val1, val2, >=)
348#define DCHECK_GT(val1, val2) if (false) CHECK_OP(val1, val2, >)
349#endif  // NDEBUG
350
351// ---------------------------CHECK_NOTNULL macros ---------------------------
352
353// Helpers for CHECK_NOTNULL(). Two are necessary to support both raw pointers
354// and smart pointers.
355template <typename T>
356T& CheckNotNullCommon(const char *file, int line, const char *names, T& t) {
357  if (t == NULL) {
358    LogMessageFatal(file, line, std::string(names));
359  }
360  return t;
361}
362
363template <typename T>
364T* CheckNotNull(const char *file, int line, const char *names, T* t) {
365  return CheckNotNullCommon(file, line, names, t);
366}
367
368template <typename T>
369T& CheckNotNull(const char *file, int line, const char *names, T& t) {
370  return CheckNotNullCommon(file, line, names, t);
371}
372
373// Check that a pointer is not null.
374#define CHECK_NOTNULL(val) \
375  CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
376
377#ifndef NDEBUG
378// Debug only version of CHECK_NOTNULL
379#define DCHECK_NOTNULL(val) \
380  CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
381#else
382// Optimized version - generates no code.
383#define DCHECK_NOTNULL(val) if (false)\
384  CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
385#endif  // NDEBUG
386
387inline void PrintAndroid(const char *msg) {
388  __android_log_write(ANDROID_LOG_VERBOSE, "native", msg);
389}
390
391#endif  // MOBILE_BASE_LOGGING_H_
392