#头文件内容如下
打印log日志到文件中的结果
自己纯属学习而自己编写的简单的log功能,如有错误之处请各位码友指出,我定虚心学习请教,当然日志模块开源的很多,还有很多需要我加强学习和改正
#pragma once
#include <iostream>
#include <mutex>
#include <stdarg.h>
#include <time.h>
#include <memory>
#include <thread>
#include <io.h>
#include <stdio.h>
#include <direct.h>
#define LogOBJ (MyLog::GetInstance())
#define Debug(model, fmt, ...) LogOBJ->printLog("Debug", model, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
#define Info(model, fmt, ...) LogOBJ->printLog("Info", model, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
class MyLog
{
public:
static MyLog* GetInstance();
void printLog(const char* level, const char* module, const char* fileName, const char* funcName, int line, const char* format, ...);
protected:
explicit MyLog();
~MyLog();
private:
void getCurrentTime(char* time);
void getCurrentDate(char* date);
void writeLogToFile();
std::string getCurrentDir();
private:
std::mutex m_mutex;
std::vector<char*> m_messageVec;
std::ofstream m_of;
static MyLog* m_pLog;
};
#cpp内容
MyLog* MyLog::m_pLog = nullptr;
MyLog::MyLog()
{
char* pDate = new char[50];
this->getCurrentDate(pDate);
auto str = getCurrentDir();
str += "\\log";
if (_access(str.c_str(), 0) == -1)
{
auto re = _mkdir(str.c_str());
if (re == 0)
{
str += ("\\" + (std::string)pDate + ".log");
this->m_of.open(str.c_str(), std::ios::app | std::ios::out);
}
}
else
{
str += ("\\" + (std::string)pDate + ".log");
this->m_of.open(str.c_str(), std::ios::app | std::ios::out);
}
if (pDate)
{
delete [] pDate;
pDate = nullptr;
}
this->m_messageVec.clear();
std::thread thread(&MyLog::writeLogToFile, this);
thread.detach();
}
MyLog::~MyLog()
{
if(this->m_of.is_open())
m_of.close();
}
void MyLog::getCurrentTime(char* time)
{
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
WORD year = sysTime.wYear;
WORD month = sysTime.wMonth;
WORD day = sysTime.wDay;
WORD hour = sysTime.wHour;
WORD min = sysTime.wMinute;
WORD se = sysTime.wSecond;
WORD mill = sysTime.wMilliseconds;
sprintf(time, "[%u-%u-%u %u:%u:%u, %u]", year, month, day, hour, min, se, mill);
}
void MyLog::getCurrentDate(char* date)
{
SYSTEMTIME time;
GetLocalTime(&time);
sprintf(date, "%u-%u-%u", time.wYear, time.wMonth, time.wDay);
}
void MyLog::printLog(const char* level, const char* module, const char* fileName, const char* funcName, int line, const char* format, ...)
{
Sleep(10);
char data[1024];
char* pTime = new char[100];
this->getCurrentTime(pTime);
sprintf(data, "%s-[%s]-[%s][%s][%s][%d]:", pTime, level, module, fileName, funcName, line);
int index = strlen(data);
va_list messageData;
va_start(messageData, format);
for (int i = 0, n = strlen(format); i < n; i++)
{
if (format[i] == '%')
{
switch (format[i + 1])
{
case 'd':
{
char str[50] = { 0 };
int value = va_arg(messageData, int);
char* re = _itoa(value, str, 10);
memcpy(data + index, re, sizeof(re));
index = strlen(data);
i++;
}
break;
case 'u':
case 'f':
{
char buff[50] = { 0 };
double value = va_arg(messageData, double);
_gcvt(value, 10, buff);
memcpy(data + index, buff, sizeof(buff));
index = strlen(data);
i++;
}
break;
case 's':
{
char* value = va_arg(messageData, char*);
int len = sizeof(value);
sprintf(data + index, "%s", value);
index = strlen(data);
i++;
}
break;
case 'c':
{
char v = va_arg(messageData, char);
sprintf(data + index, "%c", v);
index = strlen(data);
i++;
}
break;
default:
break;
}
}
else
{
sprintf(data + index, "%c", format[i]);
index = strlen(data);
}
}
if (pTime)
{
delete[] pTime;
pTime = nullptr;
};
va_end(messageData);
std::lock_guard<std::mutex> lock(this->m_mutex);
this->m_messageVec.emplace_back(data);
}
void MyLog::writeLogToFile()
{
try
{
while (true)
{
//Sleep(500);
if (this->m_messageVec.empty())
continue;
std::lock_guard<std::mutex> lock(this->m_mutex);
if (!this->m_messageVec.empty()) {
if (this->m_of.is_open())
{
this->m_of << this->m_messageVec.front()<<std::endl;
this->m_messageVec.erase(this->m_messageVec.begin());
}
}
}
}
catch (std::ofstream::failure e)
{
auto re = e.what();
std::cout << e.what() << std::endl;
}
}
std::string MyLog::getCurrentDir()
{
wchar_t dirpath[216] = { 0 };
GetModuleFileName(NULL, dirpath, 216);
char path[216];
std::size_t size = 0;
wcstombs_s(&size, path, 216, dirpath, _TRUNCATE);
std::string strPath = (std::string)path;
std::size_t pos = strPath.find_last_of("\\", strPath.length());
return strPath.substr(0, pos);
}
使用直接调用宏定义即可
如:Debug("OILO", "12目前处于测试状态%dp%c%s%f", 1234, 'Q', "你是谁呢", -2.369);
Info("KLHJ", "目前处于测试状态%d", 987);