- 1.兼容Windows和Linux平台(Linux平台未测试,如有问题,可以留言)
- 2.支持写数据到日志文件
- 3.支持向VS输出窗口打印信息,支持UNICODE和非UNICODE字符集的工程
- 4.用日期作为日志文件名,保证同一天内只会生成1个日志文件
- 5.可打印代码所在文件路径、函数名、行号
- 6.日志文件可实时刷新
#ifndef LogWriter_H #define LogWriter_H #includeMyLog.cpp#define LOG_BUFFER_SIZE 1024 #define VS_DEBUG_INFO_SIZE 500 #define MYLOG(str) MyLog::GetInstance().WriteLog((str),__FILE__, __FUNCTION__, __LINE__) #ifdef WIN32 #define LOG_DIR ("E:/Log/") void PrintVsDebugInfo(const char* strPrint); #define VSLOG(str) PrintVsDebugInfo(str) #else #define LOG_DIR ("E:/") #define VSLOG(str) #endif class MyLog { public: static MyLog& GetInstance(); MyLog(const MyLog&) = delete; MyLog(MyLog&&) = delete; MyLog& operator=(const MyLog&) = delete; MyLog& operator=(MyLog&&) = delete; bool WriteLog(const char* bufLog, const char* bufFile, const char* bufFunc, long line); private: MyLog(); ~MyLog(void); void GetDateTime(char *bufTime); void GetDate(char* bufDate); private: FILE* m_fp; char m_bufFilePath[LOG_BUFFER_SIZE]; }; #endif
#include "MyLog.h" #include3.使用说明#ifdef WIN32 #include #include #else #include #endif #pragma warning(disable:4996) #define LOG_CODE_DETAIL #ifdef WIN32 void PrintVsDebugInfo(const char* strPrint) { char bufLogData[VS_DEBUG_INFO_SIZE] = { 0 }; _snprintf(bufLogData, VS_DEBUG_INFO_SIZE - 1, "VS_DEBUG:t%sn", strPrint); #ifdef UNICODE USES_CONVERSION; OutputDebugString(A2W(bufLogData)); #else OutputDebugString(bufLogData); #endif } #endif MyLog::MyLog() { char bufFileName[100] = { 0 }; char bufDate[100] = { 0 }; GetDate(bufDate); _snprintf_s(bufFileName, 100, "%s.log", bufDate); memset(m_bufFilePath, 0, LOG_BUFFER_SIZE); strcat_s(m_bufFilePath, LOG_DIR); strcat_s(m_bufFilePath, bufFileName); m_fp = fopen(m_bufFilePath, "a+"); } MyLog::~MyLog(void) { if (m_fp) { fclose(m_fp); m_fp = NULL; } } MyLog& MyLog::GetInstance() { static MyLog objLog; return objLog; } bool MyLog::WriteLog(const char* bufLog, const char* bufFile, const char* bufFunc, long line) { if (m_fp == NULL) return false; char bufTime[100] = { 0 }; GetDateTime(bufTime); char bufLogData[LOG_BUFFER_SIZE] = { 0 }; #ifdef LOG_CODE_DETAIL _snprintf(bufLogData, LOG_BUFFER_SIZE, "%s %s\%s\Line_%d %sn", bufTime, bufFile, bufFunc, line, bufLog); fwrite(bufLogData, strlen(bufLogData), 1, m_fp); #else _snprintf(bufLogData, LOG_BUFFER_SIZE, "%s %sn", bufTime, bufLog); fwrite(bufLogData, strlen(bufLogData), 1, m_fp); #endif fflush(m_fp); return true; } void MyLog::GetDateTime(char* bufTime) { #ifdef WIN32 SYSTEMTIME sysTm; GetLocalTime(&sysTm); _snprintf(bufTime, LOG_BUFFER_SIZE, "%04d-%02d-%02d %02d:%02d:%02d:%03d", sysTm.wYear, sysTm.wMonth, sysTm.wDay , sysTm.wHour, sysTm.wMinute, sysTm.wSecond, sysTm.wMilliseconds); #else struct timeval tv; struct timezone tz; struct tm* curTime; gettimeofday(&tv, &tz); curTime = localtime(&tv.tv_sec); _snprintf(bufDate, LOG_BUFFER_SIZE, "%04d-%02d-%02d %02d:%02d:%02d:%03d", curTime->tm_year + 1900 , curTime->tm_mon + 1, curTime->tm_mday, curTime->tm_hour, curTime->tm_min, curTime->tm_sec, tv.tv_usec/1000); #endif } void MyLog::GetDate(char* bufDate) { #ifdef WIN32 SYSTEMTIME sysTm; GetLocalTime(&sysTm); _snprintf(bufDate, LOG_BUFFER_SIZE, "%04d-%02d-%02d", sysTm.wYear, sysTm.wMonth, sysTm.wDay); #else struct timeval tv; struct timezone tz; struct tm* curTime; gettimeofday(&tv, &tz); curTime = localtime(&tv.tv_sec); _snprintf(bufDate, LOG_BUFFER_SIZE, "%04d-%02d-%02d", curTime->tm_year + 1900, curTime->tm_mon + 1, curTime->tm_mday); #endif }
(1)使用MYLOG宏向日志文件写入信息,写法如下:
MYLOG("test log 1");
(2)使用VSLOG宏向VS输出窗口打印信息,写法如下:
VSLOG("vs debug");
(3)如果不需要打印函数名、行号等信息,请注释MyLog.cpp 中的
#define LOG_CODE_DETAIL
(4)“向VS输出窗口打印信息”这个功能,仅在WINDOWS平台的VS软件中可用
(5)将MyLog.h和MyLog.cpp添加到工程中,在需要打印日志的cpp中包含头文件后,即可使用日志打印功能
(6)在WINDOWS平台使用时,需注意VS是否自动添加了WIN32宏,如果没有,请手动写代码添加
(7)日志文件的创建路径在头文件中制定,默认路径我写的是E:/Log/,使用者需要根据自己的需求进行更改,但要保证更改后的路径已经存在,否则日志文件会创建失败,此日志类不会自动创建文件夹
4.使用方法示例#include "MyLog.h"
int main()
{
MYLOG("test log 1");
MYLOG("test log 2");
MYLOG("test log 3");
VSLOG("vs debug");
return 0;
}
在“return 0”这一行加断点,然后启动调试,可以看到VS输出窗口打印了"vs debug"
同时打开“E:/Log”,可以看到下面生成了一个日志文件
打开日志文件,内容如下:



