24 static constexpr char logfilename[] =
"std.log";
28 producer_ = &buffer_[0];
29 consumer_ = &buffer_[1];
30 file_.open(logfilename, std::ios_base::out | std::ios_base::app);
31 if (!file_.is_open()) {
33 std::cerr <<
"open log file fail, use stderr\n";
36 tid_ = std::thread(&logger::run,
this);
41 if (tid_.joinable()) tid_.join();
42 if (file_.is_open()) file_.close();
45 void log(std::ostringstream& ss) {
46 std::lock_guard<std::mutex> lock(lock_);
47 producer_->emplace_back(std::move(ss).str());
56 std::this_thread::sleep_for(std::chrono::milliseconds(100));
62 std::ostream& os = (logtostderr_ || !file_.is_open()) ? std::cerr : file_;
64 std::lock_guard<std::mutex> lock(lock_);
65 std::swap(producer_, consumer_);
67 if (!consumer_->empty()) {
68 for (
const std::string& str : *consumer_) {
77 std::atomic<bool> started_;
79 std::vector<std::string> *producer_, *consumer_;
80 std::vector<std::string> buffer_[2];
81 mutable std::mutex lock_;
82 std::atomic<bool> logtostderr_{
false};
89 ss_ << format(
"[{} {} {}:{}] ", time_format(), std::this_thread::get_id(), filename, line);
92 std::ostringstream&
stream() {
return ss_; }
100 inline thread_local static std::ostringstream ss_;
106#define __FILENAME__ ((strrchr(__FILE__, '/') ?: __FILE__ - 1) + 1)
108#define LOG liph::log_message(__FILENAME__, __LINE__).stream()
std::ostringstream & stream()
Definition: logging.h:92
~log_message()
Definition: logging.h:94
log_message(const char *filename, int line)
Definition: logging.h:87
void set_logtostderr(bool b)
Definition: logging.h:50
logger()
Definition: logging.h:27
~logger()
Definition: logging.h:39
void log(std::ostringstream &ss)
Definition: logging.h:45
Definition: noncopyable.h:30
Definition: algorithm.h:10
static T & instance()
Definition: singleton.h:17