1 // Copyright 2009 Google Inc. All Rights Reserved. 2 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 7 // http://www.apache.org/licenses/LICENSE-2.0 8 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef STRESSAPPTEST_LOGGER_H_ 16 #define STRESSAPPTEST_LOGGER_H_ 17 18 #include <pthread.h> 19 #include <stdarg.h> 20 21 #include <string> 22 #include <vector> 23 24 // This file must work with autoconf on its public version, 25 // so these includes are correct. 26 #include "sattypes.h" 27 28 // Attempts to log additional lines will block when the queue reaches this size. 29 // Due to how the logging thread works, up to twice this many log lines may be 30 // outstanding at any point. 31 static const size_t kMaxQueueSize = 250; 32 33 34 // This is only for use by the Logger class, do not use it elsewhere! 35 // 36 // All Logger assertions should use this macro instead of sat_assert(). 37 // 38 // This is like sat_assert() from sattypes.h, but whereas sat_assert() tries to 39 // log the assertion after printing it to stderr, this only prints it to stderr. 40 // Logging from within the wrong part of the logger would trigger a deadlock, 41 // and even in places where it wouldn't there's a very good chance that the 42 // logger is in no condition to handle new log lines. 43 #define LOGGER_ASSERT(x) \ 44 {\ 45 if (!(x)) {\ 46 fprintf(stderr, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\ 47 exit(1);\ 48 }\ 49 } 50 51 52 // This class handles logging in SAT. It is a singleton accessed via 53 // GlobalLogger(). 54 // 55 // By default log lines are written in the calling thread. Call StartThread() 56 // to launch a dedicated thread for the writes. 57 class Logger { 58 public: 59 // Returns a pointer to the single global Logger instance. Will not return 60 // NULL. 61 static Logger *GlobalLogger(); 62 63 // Lines with a priority numerically greater than this will not be logged. 64 // May not be called while multiple threads are running. SetVerbosity(int verbosity)65 virtual void SetVerbosity(int verbosity) { 66 verbosity_ = verbosity; 67 } 68 69 // Sets a file to log to, in addition to stdout. May not be called while 70 // multiple threads are running. 71 // 72 // Args: 73 // log_fd: The file descriptor to write to. Will not be closed by this 74 // object. SetLogFd(int log_fd)75 virtual void SetLogFd(int log_fd) { 76 LOGGER_ASSERT(log_fd >= 0); 77 log_fd_ = log_fd; 78 } 79 80 // Set output to be written to stdout only. This is the default mode. May 81 // not be called while multiple threads are running. SetStdoutOnly()82 virtual void SetStdoutOnly() { 83 log_fd_ = -1; 84 } 85 86 // Enable or disable logging of timestamps. SetTimestampLogging(bool log_ts_enabled)87 void SetTimestampLogging(bool log_ts_enabled) { 88 log_timestamps_ = log_ts_enabled; 89 } 90 91 // Logs a line, with a vprintf(3)-like interface. This will block on writing 92 // the line to stdout/disk iff the dedicated logging thread is not running. 93 // This will block on adding the line to the queue if doing so would exceed 94 // kMaxQueueSize. 95 // 96 // Args: 97 // priority: If this is numerically greater than the verbosity, the line 98 // will not be logged. 99 // format: see vprintf(3) 100 // args: see vprintf(3) 101 void VLogF(int priority, const char *format, va_list args); 102 103 // Starts the dedicated logging thread. May not be called while multiple 104 // threads are already running. 105 void StartThread(); 106 107 // Stops the dedicated logging thread. May only be called when the logging 108 // thread is the only other thread running. Any queued lines will be logged 109 // before this returns. Waits for the thread to finish before returning. 110 void StopThread(); 111 112 protected: 113 Logger(); 114 115 virtual ~Logger(); 116 117 private: 118 // Args: 119 // line: Must be non-NULL. This function takes ownership of it. 120 void QueueLogLine(string *line); 121 122 // Args: 123 // line: Must be non-NULL. This function takes ownership of it. 124 void WriteAndDeleteLogLine(string *line); 125 126 // Callback for pthread_create(3). 127 static void *StartRoutine(void *ptr); 128 129 // Processes the log queue. 130 void ThreadMain(); 131 132 pthread_t thread_; 133 int verbosity_; 134 int log_fd_; 135 bool thread_running_; 136 bool log_timestamps_; 137 vector<string*> queued_lines_; 138 // This doubles as a mutex for log_fd_ when the logging thread is not running. 139 pthread_mutex_t queued_lines_mutex_; 140 // Lets the logging thread know that the queue is no longer empty. 141 pthread_cond_t queued_lines_cond_; 142 // Lets the threads blocked on the queue having reached kMaxQueueSize know 143 // that the queue has been emptied. 144 pthread_cond_t full_queue_cond_; 145 146 DISALLOW_COPY_AND_ASSIGN(Logger); 147 }; 148 149 #endif // STRESSAPPTEST_LOGGER_H_ 150