• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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