C++异步日志的实现方法

首先实现一个异步队列,用来保证线程间安全通信的方法

#pragma once
/*异步队列*/
#include 
#include 
#include 
#include 


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 
#include 
#include "SafeQueue.h"
#include 
#include 
#include 
#include 
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 
#include "logger.h"


int main(int argc, char **argv)
{
	LOG_INFO("===============!=================");
	LOG_INFO("================================");
	LOG_INFO("================!================");

	while (1)
	{
		Sleep(1);
	}
	return 0;
}

你可能感兴趣的:(c++,开发语言)