Skip to content

Commit efd9d19

Browse files
automatic console output logging facility
1 parent 0586130 commit efd9d19

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

include/core/Version.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <string>
55

66
namespace core {
7-
const std::string PRMERS_VERSION = "4.15.58-alpha";
7+
const std::string PRMERS_VERSION = "4.15.59-alpha";
88
} // namespace core
99

1010
#endif // VERSION_HPP

src/main.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,60 @@
2020
* This code is released as free software.
2121
*/
2222
#include "core/App.hpp"
23+
#include <fstream>
24+
#include <streambuf>
25+
#include <iostream>
26+
#include <string>
27+
28+
class TeeBuf : public std::streambuf {
29+
std::streambuf* a_;
30+
std::streambuf* b_;
31+
public:
32+
TeeBuf(std::streambuf* a, std::streambuf* b) : a_(a), b_(b) {}
33+
protected:
34+
int overflow(int ch) override {
35+
if (ch == EOF) return !EOF;
36+
const int r1 = a_ ? a_->sputc(ch) : ch;
37+
const int r2 = b_ ? b_->sputc(ch) : ch;
38+
return (r1 == EOF || r2 == EOF) ? EOF : ch;
39+
}
40+
int sync() override {
41+
const int s1 = a_ ? a_->pubsync() : 0;
42+
const int s2 = b_ ? b_->pubsync() : 0;
43+
return (s1 == 0 && s2 == 0) ? 0 : -1;
44+
}
45+
};
46+
47+
struct LogTee {
48+
std::ofstream file;
49+
std::streambuf *oldCout = nullptr, *oldCerr = nullptr, *oldClog = nullptr;
50+
TeeBuf *teeCout = nullptr, *teeCerr = nullptr, *teeClog = nullptr;
51+
52+
explicit LogTee(const std::string& path) : file(path, std::ios::app) {
53+
if (!file) return;
54+
oldCout = std::cout.rdbuf();
55+
oldCerr = std::cerr.rdbuf();
56+
oldClog = std::clog.rdbuf();
57+
teeCout = new TeeBuf(oldCout, file.rdbuf());
58+
teeCerr = new TeeBuf(oldCerr, file.rdbuf());
59+
teeClog = new TeeBuf(oldClog, file.rdbuf());
60+
std::cout.rdbuf(teeCout);
61+
std::cerr.rdbuf(teeCerr);
62+
std::clog.rdbuf(teeClog);
63+
std::cout.setf(std::ios::unitbuf);
64+
std::cerr.setf(std::ios::unitbuf);
65+
std::clog.setf(std::ios::unitbuf);
66+
}
67+
68+
~LogTee() {
69+
if (teeCout) { std::cout.rdbuf(oldCout); delete teeCout; }
70+
if (teeCerr) { std::cerr.rdbuf(oldCerr); delete teeCerr; }
71+
if (teeClog) { std::clog.rdbuf(oldClog); delete teeClog; }
72+
if (file) file.flush();
73+
}
74+
};
2375

2476
int main(int argc, char** argv) {
77+
LogTee _tee("prmers.log");
2578
return core::App(argc, argv).run();
2679
}

0 commit comments

Comments
 (0)