• Home
  • 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   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   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   void SetStdoutOnly() {
83     log_fd_ = -1;
84   }
85 
86   // Logs a line, with a vprintf(3)-like interface.  This will block on writing
87   // the line to stdout/disk iff the dedicated logging thread is not running.
88   // This will block on adding the line to the queue if doing so would exceed
89   // kMaxQueueSize.
90   //
91   // Args:
92   //   priority: If this is numerically greater than the verbosity, the line
93   //             will not be logged.
94   //   format: see vprintf(3)
95   //   args: see vprintf(3)
96   void VLogF(int priority, const char *format, va_list args);
97 
98   // Starts the dedicated logging thread.  May not be called while multiple
99   // threads are already running.
100   void StartThread();
101 
102   // Stops the dedicated logging thread.  May only be called when the logging
103   // thread is the only other thread running.  Any queued lines will be logged
104   // before this returns.  Waits for the thread to finish before returning.
105   void StopThread();
106 
107  private:
108   Logger();
109 
110   ~Logger();
111 
112   // Args:
113   //   line: Must be non-NULL.  This function takes ownership of it.
114   void QueueLogLine(string *line);
115 
116   // Args:
117   //   line: Must be non-NULL.  This function takes ownership of it.
118   void WriteAndDeleteLogLine(string *line);
119 
120   // Callback for pthread_create(3).
121   static void *StartRoutine(void *ptr);
122 
123   // Processes the log queue.
124   void ThreadMain();
125 
126   pthread_t thread_;
127   int verbosity_;
128   int log_fd_;
129   bool thread_running_;
130   vector<string*> queued_lines_;
131   // This doubles as a mutex for log_fd_ when the logging thread is not running.
132   pthread_mutex_t queued_lines_mutex_;
133   // Lets the logging thread know that the queue is no longer empty.
134   pthread_cond_t queued_lines_cond_;
135   // Lets the threads blocked on the queue having reached kMaxQueueSize know
136   // that the queue has been emptied.
137   pthread_cond_t full_queue_cond_;
138 
139   DISALLOW_COPY_AND_ASSIGN(Logger);
140 };
141 
142 #endif  // STRESSAPPTEST_LOGGER_H_
143