使用C++编写简单的log日志文件

使用C++编写自定义的日志文件,无需第三方库,包含输出日志信息的时间、类别、代码文件名、行数、线程号以及日志内容。

#pragma once
#include <string>
#include <iostream>
#include <fstream>
#ifdef WIN32
#include <io.h>
#include <direct.h>
#include <windows.h>
#else
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/syscall.h>
#endif
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <mutex>
#include <sstream>
#include <stdarg.h>

#define gettid() syscall(__NR_gettid)
#define MAX_LEN 1024
static std::mutex logMutex;


enum LogLevelEnum
{
	INFO = 0,
	DEBUG = 1,
	WARN = 2,
	ERROR = 3,
	CRITICAL = 4,
};



class logInf
{
public:
    
    logInf(){}

    logInf(std::string logDir, std::string prjname)
    {
        InitialStrLog(logDir, prjname);
    }

    ~logInf(){}

    std::time_t getTimeStamp()
    {
        std::chrono::time_point<std::chrono::system_clock,std::chrono::milliseconds> tp = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
        auto tmp=std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
        std::time_t timestamp = tmp.count();
        return timestamp;
    }
    std::tm* gettm(uint64_t timestamp)
    {
        uint64_t milli = timestamp;
        milli += (uint64_t)8*60*60*1000;//转换时区,北京时间+8小时
        auto mTime = std::chrono::milliseconds(milli);
        auto tp=std::chrono::time_point<std::chrono::system_clock,std::chrono::milliseconds>(mTime);
        auto tt = std::chrono::system_clock::to_time_t(tp);
        std::tm* now = std::gmtime(&tt);
        return now;
    }
     
    std::string getTimeStr()
    {
        time_t timep;
        timep = getTimeStamp(); 
        struct tm *info;
        info = gettm(timep); 
     
        char tmp[1000] = {0};
        sprintf(tmp, "%04d-%02d-%02d %02d:%02d:%02d.%03ld", info->tm_year+1900, info->tm_mon+1, info->tm_mday, info->tm_hour, info->tm_min, info->tm_sec, timep%1000000);
        return tmp;
    }
  

    void InitialStrLog(std::string logDir, std::string prjname)
    {
    	strlogPath = logDir + "/" + prjname;
    #ifdef WIN32
    	int iRet = _access(strlogPath.c_str(), 0);
    #else
    	int iRet = access(strlogPath.c_str(), 0);
    #endif
    	if (iRet != 0)
    	{
    		std::ofstream ofs(strlogPath, std::ios::app);
    		if (ofs.is_open())
    		{
    			std::cout << "file is open !" << std::endl;
    			ofs.close();
    		}
    	}
    }
    
    
    
    inline void LogString(std::string strInf, LogLevelEnum nLevel, std::string filename, int nrow)
    {
    	time_t timep;
    	time(&timep);
    	char tmp[64];
    	strftime(tmp, 23, "%Y-%m-%d %H:%m:%s", localtime(&timep));
    	std::string strTime = getTimeStr(); //tmp;
    	std::string strTimeOut = "{" + strTime + "}";
    
    	std::string strloglevel;
    	if (nLevel == LogLevelEnum::INFO)
    	{
    		strloglevel = "{INFO}";
    	}
    	else if (nLevel == LogLevelEnum::DEBUG)
    	{
    		strloglevel = "{DEBUG}";
    	}
    	else if (nLevel == LogLevelEnum::WARN)
    	{
    		strloglevel = "{WARN}";
    	}
    	else if (nLevel == LogLevelEnum::ERROR)
    	{
    		strloglevel = "{ERROR}";
    	}
    	else if (nLevel == LogLevelEnum::CRITICAL)
    	{
    		strloglevel = "{CRITICAL}";
    	}
        int findex = filename.find_last_of("/");
        if(findex < 0) findex = 0;
        std::string strfilename = filename.substr(findex+1);
    	std::string strFuncName = "{" + strfilename + "}";
    	
    	int lineRow = __LINE__;
    	std::stringstream ss;
    	ss << lineRow;
    	std::string strRowNum = "{" + ss.str() + "}";
    
    	std::stringstream sthread;
    	int nTreadID;
    #ifdef WIN32
    	nTreadID = GetCurrentThreadId();
    #else
    	nTreadID = gettid();
    #endif
    	sthread << nTreadID;
    	std::string strTreadID = "{" + sthread.str() + "}";
    
    	logMutex.lock();
    	std::string strlineInf = strTimeOut + strloglevel + strFuncName + strRowNum + strTreadID + ": " + strInf;
    	std::ofstream ofs(strlogPath, std::ios::app);
    	if (ofs.is_open())
    	{
    		ofs << strlineInf << std::endl;
    		std::cout<<strlineInf<<std::endl;
    	}
    	logMutex.unlock();
    }
    
    
    
    inline void LogString(LogLevelEnum nLevel, std::string filename, int nrow,const char* format, ...)
    {
        char message[MAX_LEN];
        va_list args;
        va_start(args, format);
        vsnprintf (message, MAX_LEN, format, args);
        va_end(args);
    
        time_t timep= time(NULL);
    	char tmp[64];
    	strftime(tmp, 23, "%Y-%m-%d %H:%M:%S", localtime(&timep));
    	std::string strTime = getTimeStr(); //tmp;
    	std::string strTimeOut = "{" + strTime + "}";
    
    	std::string strloglevel;
    	if (nLevel == LogLevelEnum::INFO)
    	{
    		strloglevel = "{INFO}";
    	}
    	else if (nLevel == LogLevelEnum::DEBUG)
    	{
    		strloglevel = "{DEBUG}";
    	}
    	else if (nLevel == LogLevelEnum::WARN)
    	{
    		strloglevel = "{WARN}";
    	}
    	else if (nLevel == LogLevelEnum::ERROR)
    	{
    		strloglevel = "{ERROR}";
    	}
    	else if (nLevel == LogLevelEnum::CRITICAL)
    	{
    		strloglevel = "{CRITICAL}";
    	}
        int findex = filename.find_last_of("/");
        if(findex < 0) findex = 0;
        std::string strfilename = filename.substr(findex+1);
    	std::string strFuncName = "{" + strfilename + "}";
    	
    	int lineRow = nrow;
    	std::stringstream ss;
    	ss << lineRow;
    	std::string strRowNum = "{" + ss.str() + "}";
    
    	std::stringstream sthread;
    	int nTreadID;
    #ifdef WIN32
    	nTreadID = GetCurrentThreadId();
    #else
    	nTreadID = gettid();
    #endif
    	sthread << nTreadID;
    	std::string strTreadID = "{" + sthread.str() + "}";
    
    	logMutex.lock();
    	std::string strInf = message;
    	std::string strlineInf = strTimeOut + strloglevel + strFuncName + strRowNum + strTreadID + ": " + strInf;
    	std::ofstream ofs(strlogPath, std::ios::app);
    	if (ofs.is_open())
    	{
    		ofs << strlineInf << std::endl;
    		std::cout<<strlineInf<<std::endl;
    	}
    	logMutex.unlock();
    
    }

    private:

    std::string strlogPath;
    
};
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值