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