LIPH's C++ Codes
logging.h
Go to the documentation of this file.
1#ifndef LIPH_LOGGING_H_
2#define LIPH_LOGGING_H_
3
4#include <atomic>
5#include <cstring>
6#include <fstream>
7#include <iostream>
8#include <memory>
9#include <mutex>
10#include <sstream>
11#include <string>
12#include <thread>
13#include <vector>
14
15#include "liph/format.h"
17#include "liph/lang/singleton.h"
18#include "liph/time.h"
19
20namespace liph {
21
23private:
24 static constexpr char logfilename[] = "std.log";
25
26public:
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()) {
32 logtostderr_ = true;
33 std::cerr << "open log file fail, use stderr\n";
34 }
35 started_ = true;
36 tid_ = std::thread(&logger::run, this);
37 }
38
40 started_ = false;
41 if (tid_.joinable()) tid_.join();
42 if (file_.is_open()) file_.close();
43 }
44
45 void log(std::ostringstream& ss) {
46 std::lock_guard<std::mutex> lock(lock_);
47 producer_->emplace_back(std::move(ss).str());
48 }
49
50 void set_logtostderr(bool b) { logtostderr_ = b; }
51
52private:
53 void run() {
54 while (started_) {
55 consume();
56 std::this_thread::sleep_for(std::chrono::milliseconds(100));
57 }
58 consume();
59 }
60
61 void consume() {
62 std::ostream& os = (logtostderr_ || !file_.is_open()) ? std::cerr : file_;
63 {
64 std::lock_guard<std::mutex> lock(lock_);
65 std::swap(producer_, consumer_);
66 }
67 if (!consumer_->empty()) {
68 for (const std::string& str : *consumer_) {
69 os << str;
70 }
71 os.flush();
72 consumer_->clear();
73 }
74 }
75
76 std::ofstream file_;
77 std::atomic<bool> started_;
78 std::thread tid_;
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};
83};
84
86public:
87 log_message(const char *filename, int line) {
88 ss_.str("");
89 ss_ << format("[{} {} {}:{}] ", time_format(), std::this_thread::get_id(), filename, line);
90 }
91
92 std::ostringstream& stream() { return ss_; }
93
95 ss_ << '\n';
97 }
98
99private:
100 inline thread_local static std::ostringstream ss_;
101};
102
103} // namespace liph
104
105#ifndef __FILENAME__
106#define __FILENAME__ ((strrchr(__FILE__, '/') ?: __FILE__ - 1) + 1)
107#endif
108#define LOG liph::log_message(__FILENAME__, __LINE__).stream()
109
110#endif // LIPH_LOGGING_H_
Definition: logging.h:85
std::ostringstream & stream()
Definition: logging.h:92
~log_message()
Definition: logging.h:94
log_message(const char *filename, int line)
Definition: logging.h:87
Definition: logging.h:22
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