xref: /aosp_15_r20/external/stressapptest/src/logger.h (revision 424fb153c814cbcb3e8904974796228774b3229a)
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