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