首先实现一个异步队列,用来保证线程间安全通信的方法
#pragma once
/*异步队列*/
#include <thread>
#include <queue>
#include <condition_variable>
#include <mutex>
template <typename T>
class SafeQueue
{
public:
void Push(T & value)
{
std::lock_guard<std::mutex> lock(m_mutex);
m_queue.push(value);
m_condition.notify_one();
}
void Pop(T &value)
{
while (m_queue.empty())
{
std::unique_lock<std::mutex> lock(m_mutex);
m_condition.wait(lock);
}
value = m_queue.front();
m_queue.pop();
//return value;
}
private:
std::mutex m_mutex;
std::condition_variable m_condition;
std::queue<T> m_queue;
};
接下来实现日志类
#pragma once
#include <iostream>
#include <time.h>
#include "SafeQueue.h"
#include <Windows.h>
#include <fstream>
#include <iostream>
#include <filesystem>
using namespace std::filesystem;
enum class LogLevel{
LOG_INFO,
LOG_ERROR
};
class Logger
{
public:
static Logger &GetInstance();
void setLogLevel(LogLevel level);
void WriteLog(std::string msg);
private:
Logger();
Logger(const Logger&) = delete;
Logger(Logger&&) = delete;
private:
SafeQueue<std::string> m_SafeQueue;
LogLevel m_Level;
};
#define LOG_INFO(msgformat,...)\ do\ {
\ Logger::GetInstance().setLogLevel(LogLevel::LOG_INFO);\ char c[1024] = {
0};\ sprintf_s(c,msgformat,##__VA_ARGS__);\ Logger::GetInstance().WriteLog(c);\ }\ while(0);
#define LOG_ERROR(msgformat,...)\ do\ {
\ Logger::GetInstance().setLogLevel(LogLevel::LOG_ERROR);\ char c[1024] = {
0};\ sprintf_s(c,msgformat,##__VA_ARGS__);\ Logger::GetInstance().WriteLog(c);\ }\ while(0);
#include "logger.h"
Logger &Logger::GetInstance()
{
static Logger logger;
return logger;
}
Logger::Logger()
{
std::thread LogThread([this]() {
while (1)
{
time_t now = time(nullptr);
tm nowtm;
localtime_s(&nowtm,&now);
char file_name[128];
sprintf_s(file_name, sizeof(file_name),"/%d-%d-%d-log.txt", nowtm.tm_year + 1900, nowtm.tm_mon + 1, nowtm.tm_mday);
std::string m_path = "E:/csdemo/C++/asynclog/log/log/log";
std::filesystem::path dir(m_path);
if (!exists(dir))
{
create_directories(dir);
}
m_path += file_name;
std::ofstream fi;
fi.open(m_path, std::ios::app);
char time_buf[128];
sprintf_s(time_buf, sizeof(time_buf), "%d:%d:%d ====>[%s]", nowtm.tm_hour, nowtm.tm_min, nowtm.tm_sec, (m_Level == LogLevel::LOG_INFO ? "info" : "error"));
std::string msg;
m_SafeQueue.Pop(msg);
msg.insert(0, time_buf);
//msg.append("\n");
fi << msg << std::endl;
fi.flush();
fi.close();
}
});
LogThread.detach();
}
void Logger::setLogLevel(LogLevel level)
{
m_Level = level;
}
void Logger::WriteLog(std::string msg)
{
m_SafeQueue.Push(msg);
}
写完后加载测试,检测功能是否正常
#include <iostream>
#include "logger.h"
int main(int argc, char **argv)
{
LOG_INFO("===============!=================");
LOG_INFO("================================");
LOG_INFO("================!================");
while (1)
{
Sleep(1);
}
return 0;
}
文章评论