2024-06-27 服务器开发-日志代码-记录

摘要:

2024-06-27 服务器开发-日志代码-记录

日志代码

logger.h

#pragma once

#include <Windows.h>
#include <stdio.h>
#include <time.h>
#include <functional>

#pragma warning(disable:4996)
#pragma warning(disable:4482)

namespace VH_DRIVER
{

	//日志级别的提示信息
	static const char* KEYINFOPREFIX = " [Key]:";
	static const char* ERRORPREFIX = " [Error]:";
	static const char* WARNINGPREFIX = " [Warning]:";
	static const char* INFOPREFIX = " [Info]:";

	static const int MAX_STR_LEN = 20480;
	//日志级别枚举
	enum EnumLogLevel
	{
		LogLevelAll = 0,    //所有信息都写日志
		LogLevelMid,        //写错误、警告信息
		LogLevelNormal,     //只写错误信息
		LogLevelStop        //不写日志
	};

	class Logger
	{
	public:
		//默认构造函数
		Logger();
		//构造函数
		Logger(const char* strLogPath, EnumLogLevel nLogLevel = EnumLogLevel::LogLevelNormal);
		//析构函数
		virtual ~Logger();
	public:
		//写关键信息
		void TraceKeyInfo(const char* strInfo, ...);
		//写错误信息
		void TraceError(const char* strInfo, ...);
		//写警告信息
		void TraceWarning(const char* strInfo, ...);
		//写一般信息
		void TraceInfo(const char* strInfo, ...);
		//设置写日志级别
		void SetLogLevel(EnumLogLevel nLevel);
		//是否设置控制台输出
		void SetConsoleOutput(bool flag) { m_isStandOut = flag; }
	private:
		//写文件操作
		void Trace(const char* strInfo);
		//获取当前系统时间
		char* GetCurrentTime();
		//创建日志文件名称
		void GenerateLogName();
		//创建日志路径
		void CreateLogPath();
	private:
		//是否同步控制台输出
		bool m_isStandOut;
		//日志切割的时间
		tm  m_pTimeInfo;
		//写日志文件流
		FILE* m_pFileStream;
		//写日志级别
		EnumLogLevel m_nLogLevel;
		//日志的路径
		char m_strLogPath[MAX_STR_LEN];
		//日志的名称
		char m_strCurLogName[MAX_STR_LEN];
		//线程同步的临界区变量
		CRITICAL_SECTION m_cs;
	};

}

logger.cpp

#include "Logger.h"
#include <time.h>
#include <string.h>
#include <stdarg.h>
#include <imagehlp.h>
#include <stdio.h>
#include <direct.h>
#include <iostream>

#pragma comment(lib, "DbgHelp.lib")

namespace VH_DRIVER
{

	Logger AILog;

	//默认构造函数
	Logger::Logger()
	{
		//初始化
		memset(m_strLogPath, 0, MAX_STR_LEN);
		memset(m_strCurLogName, 0, MAX_STR_LEN);
		m_pFileStream = NULL;
		//设置默认的写日志级别
		m_nLogLevel = EnumLogLevel::LogLevelNormal;
		//初始化临界区变量
		InitializeCriticalSection(&m_cs);
		//创建日志文件名
		CreateLogPath();
		GenerateLogName();
		SetLogLevel(LogLevelAll);
		m_isStandOut = false;
	}

	//构造函数
	Logger::Logger(const char* strLogPath, EnumLogLevel nLogLevel) :m_nLogLevel(nLogLevel)
	{
		//初始化
		m_pFileStream = NULL;
		strcpy(m_strLogPath, strLogPath);
		InitializeCriticalSection(&m_cs);
		CreateLogPath();
		GenerateLogName();
		SetLogLevel(LogLevelAll);
		m_isStandOut = false;
	}

	//析构函数
	Logger::~Logger()
	{
		//释放临界区
		DeleteCriticalSection(&m_cs);
		//关闭文件流
		if (m_pFileStream)
			fclose(m_pFileStream);
	}

	//写关键信息接口
	void Logger::TraceKeyInfo(const char* strInfo, ...)
	{
		if (!strInfo)
			return;
		char pTemp[MAX_STR_LEN] = { 0 };
		char* pTime = GetCurrentTime();
		strcpy(pTemp, pTime);
		strcat(pTemp, KEYINFOPREFIX);
		//获取可变形参
		va_list arg_ptr = NULL;
		va_start(arg_ptr, strInfo);
		vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr);
		va_end(arg_ptr);
		//写日志文件
		Trace(pTemp);
		arg_ptr = NULL;
		delete pTime;
	}

	//写错误信息
	void Logger::TraceError(const char* strInfo, ...)
	{
		//判断当前的写日志级别,若设置为不写日志则函数返回
		if (m_nLogLevel >= EnumLogLevel::LogLevelStop)
			return;
		if (!strInfo)
			return;
		char pTemp[MAX_STR_LEN] = { 0 };
		char* pTime = GetCurrentTime();
		strcpy(pTemp, pTime);
		strcat(pTemp, ERRORPREFIX);
		va_list arg_ptr = NULL;
		va_start(arg_ptr, strInfo);
		vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr);
		va_end(arg_ptr);
		Trace(pTemp);
		arg_ptr = NULL;
		delete pTime;
	}

	//写警告信息
	void Logger::TraceWarning(const char* strInfo, ...)
	{
		//判断当前的写日志级别,若设置为只写错误信息则函数返回
		if (m_nLogLevel >= EnumLogLevel::LogLevelNormal)
			return;
		if (!strInfo)
			return;
		char pTemp[MAX_STR_LEN] = { 0 };
		char* pTime = GetCurrentTime();
		strcpy(pTemp, pTime);
		strcat(pTemp, WARNINGPREFIX);
		va_list arg_ptr = NULL;
		va_start(arg_ptr, strInfo);
		vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr);
		va_end(arg_ptr);
		Trace(pTemp);
		arg_ptr = NULL;
		delete pTime;
	}


	//写一般信息
	void Logger::TraceInfo(const char* strInfo, ...)
	{
		//判断当前的写日志级别,若设置只写错误和警告信息则函数返回
		if (m_nLogLevel >= EnumLogLevel::LogLevelMid)
			return;
		if (!strInfo)
			return;
		char pTemp[MAX_STR_LEN] = { 0 };
		char* pTime = GetCurrentTime();
		strcpy(pTemp, pTime);
		strcat(pTemp, INFOPREFIX);
		va_list arg_ptr = NULL;
		va_start(arg_ptr, strInfo);
		vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr);
		va_end(arg_ptr);
		Trace(pTemp);
		arg_ptr = NULL;
		delete pTime;
	}

	//获取系统当前时间
	char* Logger::GetCurrentTime()
	{
		time_t curTime;
		struct tm* pTimeInfo = NULL;
		time(&curTime);
		pTimeInfo = localtime(&curTime);
		char* temp = new char[MAX_STR_LEN];
		sprintf(temp, "%04d-%02d-%02d %02d:%02d:%02d", pTimeInfo->tm_year + 1990, pTimeInfo->tm_mon + 1, pTimeInfo->tm_mday, pTimeInfo->tm_hour, pTimeInfo->tm_min, pTimeInfo->tm_sec);
		char* pTemp = temp;
		return pTemp;
	}

	//设置写日志级别
	void Logger::SetLogLevel(EnumLogLevel nLevel)
	{
		m_nLogLevel = nLevel;
	}

	//写文件操作
	void Logger::Trace(const char* strInfo)
	{
		if (!strInfo)
			return;
		try
		{
			//进入临界区
			EnterCriticalSection(&m_cs);
			time_t curTime;
			struct tm* pTimeInfo = NULL;
			time(&curTime);
			pTimeInfo = localtime(&curTime);
			if (
				pTimeInfo->tm_year != m_pTimeInfo.tm_year
				|| pTimeInfo->tm_mon != m_pTimeInfo.tm_mon
				|| pTimeInfo->tm_mday != m_pTimeInfo.tm_mday
				)
			{
				GenerateLogName();
			}

			//若文件流没有打开,则重新打开
			if (!m_pFileStream)
			{
				char temp[1024] = { 0 };
				strcat(temp, m_strLogPath);
				strcat(temp, m_strCurLogName);
				m_pFileStream = fopen(temp, "a+");
				if (!m_pFileStream)
				{
					return;
				}
			}
			//写日志信息到文件流
			fprintf(m_pFileStream, "%s\n", strInfo);
			fflush(m_pFileStream);
			//写日志到控制台
			if (m_isStandOut)
			{
				printf("%s\n", strInfo);
			}

			//离开临界区
			LeaveCriticalSection(&m_cs);
		}
		catch (...) //若发生异常,则先离开临界区,防止死锁
		{
			LeaveCriticalSection(&m_cs);
		}
	}

	//创建日志文件的名称
	void Logger::GenerateLogName()
	{
		time_t curTime;
		struct tm* pTimeInfo = NULL;
		time(&curTime);
		pTimeInfo = localtime(&curTime);
		char temp[1024] = { 0 };
		//日志的名称如:2013-01-01.log
		sprintf(temp, "%04d-%02d-%02d-%02d_AI.log", (pTimeInfo->tm_year + 1900), (pTimeInfo->tm_mon + 1), pTimeInfo->tm_mday, pTimeInfo->tm_hour);
		if (0 != strcmp(m_strCurLogName, temp))
		{
			strcpy(m_strCurLogName, temp);
			if (m_pFileStream)
			{
				fflush(m_pFileStream);
				fclose(m_pFileStream);
			}

			char newTemp[1024] = { 0 };
			strcat(newTemp, m_strLogPath);
			strcat(newTemp, m_strCurLogName);
			//以追加的方式打开文件流
			m_pFileStream = fopen(newTemp, "a+");
		}
		m_pTimeInfo = *(pTimeInfo);
	}

	//创建日志文件的路径
	void Logger::CreateLogPath()
	{
		memset(m_strLogPath, 0, sizeof(m_strLogPath));
		char* buffer;
		//也可以将buffer作为输出参数
		if ((buffer = getcwd(NULL, 0)) == NULL)
		{
			strcat(m_strLogPath, "\\");
		}
		else
		{
			strcat(m_strLogPath, buffer);
			strcat(m_strLogPath, "\\LOGAI\\");
			free(buffer);
		}
		MakeSureDirectoryPathExists(m_strLogPath);
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟世者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值