1 // Copyright (c) 2017 Nuxi, https://nuxi.nl/ 2 // 3 // This file is distributed under a 2-clause BSD license. 4 // See the LICENSE file for details. 5 6 #ifndef FLOWER_UTIL_LOGGER_H 7 #define FLOWER_UTIL_LOGGER_H 8 9 #include <iomanip> 10 #include <mutex> 11 #include <ostream> 12 #include <streambuf> 13 #include <thread> 14 15 namespace flower { 16 namespace util { 17 namespace { 18 19 // Log entry that is in the process of being written. This class 20 // serializes output to the stream and also ensures all entries have a 21 // trailing newline. 22 class LogTransaction : public std::ostream { 23 public: LogTransaction(std::streambuf * streambuf,std::mutex * streambuf_lock)24 LogTransaction(std::streambuf* streambuf, std::mutex* streambuf_lock) 25 : std::ostream(streambuf), ostream_guard_(*streambuf_lock) { 26 } 27 ~LogTransaction()28 ~LogTransaction() { 29 *this << std::endl; 30 } 31 32 private: 33 std::lock_guard<std::mutex> ostream_guard_; 34 }; 35 36 // Wrapper around std::ostream for writing log entries. 37 // 38 // C++ streams are not required to be thread-safe. This class protects 39 // an output stream with a mutex. 40 class Logger { 41 public: Logger(std::streambuf * streambuf)42 explicit Logger(std::streambuf* streambuf) : streambuf_(streambuf) { 43 } 44 45 // TODO(ed): Should we add support for logging severities? Log()46 LogTransaction Log() { 47 return LogTransaction(streambuf_, &streambuf_lock_); 48 } 49 50 private: 51 std::mutex streambuf_lock_; 52 std::streambuf* streambuf_; 53 }; 54 55 } // namespace 56 } // namespace util 57 } // namespace flower 58 59 #endif 60