Home | History | Annotate | Download | only in src
      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.
     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.
     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.
     82   virtual void SetStdoutOnly() {
     83     log_fd_ = -1;
     84   }
     85 
     86   // Enable or disable logging of timestamps.
     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