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

该代码实现了一个使用异步队列保证线程安全的Logger类,用于记录不同级别的日志信息。Logger类包含一个静态方法用于获取单例实例,支持设置日志级别,并使用SafeQueue确保在多线程环境中的日志写入安全。日志信息被写入到按日期命名的文本文件中。
摘要由CSDN通过智能技术生成

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

#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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Window C实现web服务器可以使用多种方式,下面是一种常见的实现方式。 首先,需要使用Window操作系统提供的Socket API来创建并管理服务器的Socket连接。通过调用Socket API创建一个Socket套接字,并绑定一个IP地址和端口号。 接下来,需要编写C代码来处理客户端的请求。可以使用多线程或者异步的方式处理多个客户端的请求。首先调用Socket API的接收函数accept()来接收客户端的连接请求。然后,使用Socket API的发送和接收函数来与客户端进行数据交互,实现HTTP协议的请求和响应。 在C代码中,需要解析客户端发送的HTTP请求报文,包括请求方法、URI、HTTP版本、请求头等信息。根据请求的URI,可以使用文件IO函数来读取服务器上的网页文件,将读取到的文件内容作为HTTP响应的主体返回给客户端。 另外,还需要处理一些特殊的请求,比如GET请求和POST请求。对于GET请求,可以从查询字符串中获取参数,根据参数的不同返回不同的响应;对于POST请求,需要解析请求主体中的表单数据,并根据表单数据的不同做出相应的处理。 最后,在C代码中还可以实现一些功能,比如日志记录、错误处理和异常处理等,以提高服务器的稳定性和安全性。 总结来说,Window C实现web服务器需要使用Window操作系统提供的Socket API来创建和管理服务器的Socket连接。通过编写C代码来处理客户端的请求,包括解析HTTP请求报文、读取网页文件、处理特殊请求等。除此之外,还需要实现一些额外的功能,比如日志记录和错误处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值