122 lines
3.3 KiB
C++
122 lines
3.3 KiB
C++
#include <iostream>
|
|
#include <sstream>
|
|
#include <vector>
|
|
#include <functional>
|
|
#include <fstream>
|
|
#include <chrono>
|
|
#include <iomanip>
|
|
#include <ctime>
|
|
//SAMPLE
|
|
class customCallbackFunc {
|
|
public:
|
|
virtual void processOutput(const std::string& output) {
|
|
std::cout << "customCallbackFunc received: " << output;
|
|
}
|
|
};
|
|
|
|
//输出到文件
|
|
class FileLogger : public customCallbackFunc {
|
|
public:
|
|
FileLogger(std::string basePath):logBasePath(basePath){
|
|
updateLogFile();
|
|
}
|
|
|
|
~FileLogger() {
|
|
if (logFile.is_open()) {
|
|
logFile.close();
|
|
}
|
|
}
|
|
|
|
virtual void processOutput(const std::string& output) override {
|
|
updateLogFileIfNeeded();
|
|
if (logFile.is_open()) {
|
|
logFile << (getCurrentTime()+">>>"+output);
|
|
logFile.flush();
|
|
}
|
|
else {
|
|
std::cerr << "Failed to write to log file: file is not open" << std::endl;
|
|
}
|
|
}
|
|
|
|
private:
|
|
std::string logBasePath;
|
|
std::ofstream logFile;
|
|
std::string currentDate;
|
|
std::string getCurrentDate() {
|
|
auto now = std::chrono::system_clock::now();
|
|
auto in_time_t = std::chrono::system_clock::to_time_t(now);
|
|
std::ostringstream oss;
|
|
oss << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d");
|
|
return oss.str();
|
|
}
|
|
std::string getCurrentTime() {
|
|
auto now = std::chrono::system_clock::now();
|
|
auto in_time_t = std::chrono::system_clock::to_time_t(now);
|
|
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()) % 1000000;
|
|
|
|
std::ostringstream oss;
|
|
oss << std::put_time(std::localtime(&in_time_t), "(%Y-%m-%d %H-%M-%S");
|
|
oss << " " << std::setfill('0') << std::setw(6) << microseconds.count()<<"):";
|
|
return oss.str();
|
|
}
|
|
void updateLogFile() {
|
|
currentDate = getCurrentDate();
|
|
std::string filename = logBasePath+"/"+currentDate + "std.log";
|
|
if (logFile.is_open()) {
|
|
logFile.close();
|
|
}
|
|
logFile.open(filename, std::ios::app);
|
|
if (!logFile.is_open()) {
|
|
throw std::runtime_error("Unable to open log file: " + filename);
|
|
}
|
|
}
|
|
|
|
void updateLogFileIfNeeded() {
|
|
std::string newDate = getCurrentDate();
|
|
if (newDate != currentDate) {
|
|
updateLogFile();
|
|
}
|
|
}
|
|
};
|
|
|
|
//截取std::cout的内容
|
|
class stdConsoleRedirector : public std::streambuf {
|
|
public:
|
|
using CallbackType = std::function<void(const std::string&)>;
|
|
|
|
stdConsoleRedirector(std::ostream& stream)
|
|
: originalStream(stream), originalBuffer(stream.rdbuf(this)) {}
|
|
|
|
~stdConsoleRedirector() {
|
|
originalStream.rdbuf(originalBuffer);
|
|
}
|
|
|
|
// 注册回调函数
|
|
void registerCallback(CallbackType callback) {
|
|
callbacks.push_back(callback);
|
|
}
|
|
|
|
protected:
|
|
virtual int overflow(int c) override {
|
|
if (c == EOF) {
|
|
return EOF;
|
|
}
|
|
else {
|
|
char ch = static_cast<char>(c);
|
|
buffer += ch;
|
|
if (ch == '\n') {
|
|
for (const auto& callback : callbacks) {
|
|
callback(buffer);
|
|
}
|
|
buffer.clear();
|
|
}
|
|
return c;
|
|
}
|
|
}
|
|
|
|
private:
|
|
std::ostream& originalStream;
|
|
std::streambuf* originalBuffer;
|
|
std::string buffer;
|
|
std::vector<CallbackType> callbacks;
|
|
}; |