• c++ 日志操作


    程序需要一个简单的日志类,为此简单学习了Boost.Log和google的glog,前者功能非常强大,后者非常小巧但是不够灵活,最终打算自己写一个。

     环境:

    win7 32位旗舰版、VS2010旗舰版

    TinyLog.h文件

    #ifndef _TINY_LOG_H_
    #define _TINY_LOG_H_
    
    #include <fstream>
    #include <list>
    #include <string>
    
    #define _WINDOWS
    
    namespace TinyLogHelper
    {
    	template<typename T>
    	T GetCurrentDir()
    	{
    	}
    
    #ifdef _WINDOWS
    
    	#include <windows.h>
    
    	//////////////////////////////////////////////////////////////////////////
    	//	线程互斥锁
    	//////////////////////////////////////////////////////////////////////////
    	class CLock
    	{
    	public:
    		CLock()
    		{
    			InitializeCriticalSection(&m_cs);//初始化临界区
    		}
    
    		~CLock()
    		{
    			DeleteCriticalSection(&m_cs);//删除临界区
    		}
    
    		void Lock()
    		{
    			EnterCriticalSection(&m_cs);//加锁
    		}
    
    		void UnLock()
    		{
    			LeaveCriticalSection(&m_cs);//解锁
    		}
    
    	private:
    		CRITICAL_SECTION m_cs;
    	};
    
    	//////////////////////////////////////////////////////////////////////////
    	//	函数功能:
    	//		获取当前目录
    	//////////////////////////////////////////////////////////////////////////
    	template<>
    	std::string GetCurrentDir<std::string>();
    
    	template<>
    	std::wstring GetCurrentDir<std::wstring>();
    
    #endif
    }
    
    namespace TinyLog
    {
    	//////////////////////////////////////////////////////////////////////////
    	//						CTinyLog类修改记录								
    	//	2014-5-24
    	//		使用m_nLogBufferLength记录当前日志缓存的大小,而不使用GetLogBufferSize
    	//		函数将整个日志缓存遍历一次来获取,提高运行速度。
    	//////////////////////////////////////////////////////////////////////////
    
    	//////////////////////////////////////////////////////////////////////////
    	//	日志等级
    	//		LogLevelDebug等级,会输出所有日志信息
    	//		LogLevelInfo等级,会输出INFO日志信息
    	//		LogLevelError等级,会输出ERROR日志信息
    	//////////////////////////////////////////////////////////////////////////
    	enum LogLevel
    	{
    		LogLevelDebug,//调试
    		LogLevelInfo,//信息
    		LogLevelError,//错误
    	};
    
    	const static char* pszLogLevelString[3] = {
    		"Debug",
    		"Info",
    		"Error"
    	};
    
    	//////////////////////////////////////////////////////////////////////////
    	//	类说明:
    	//		单线程日志类,应该只在一个线程中操作日志
    	//////////////////////////////////////////////////////////////////////////
    	template<typename T>
    	class CTinyLog
    	{
    
    	};
    
    	template<>
    	class CTinyLog<char>
    	{
    	public:
    		CTinyLog();
    
    		~CTinyLog();
    
    	public:
    		//添加日志记录
    		CTinyLog& operator <<(const char* pszMessage);
    
    		//添加调试日志
    		void Debug(const char* pszMessage);
    
    		//添加信息日志
    		void Info(const char* pszMessage);
    
    		//添加错误日志
    		void Error(const char* pszMessage);
    
    		//将日志缓存写入到文件中
    		CTinyLog& WriteToFile();
    
    		//得到第一个写入文件路径
    		std::string GetFirstWriteFilePath() const;
    
    		//得到下一个写入文件路径
    		std::string GetNextWriteFilePath() const;
    
    		//得到文件路径格式
    		std::string GetCurrentFilePathFormat() const;
    
    	public://属性
    		//设置文件
    		bool SetFileDir(const std::string& strFileDir);
    
    		//设置文件扩展名
    		bool SetFillExtendName(const std::string& strFileExtendName);
    
    		//设置文件名称格式
    		bool SetFileNameFormat(const std::string& strFileNameFormat);
    
    		//设置最大文件大小(字节)
    		void SetMaxFileSize(std::size_t size);
    
    		//设置最大写入文件大小(字节)
    		void SetMaxWriteFileSize(std::size_t size);
    
    		//设置最大文件个数
    		void SetMaxFileCount(std::size_t count);
    
    		//设置日志等级
    		void SetLogLevel(LogLevel emLogLevel);
    
    	private:
    		//日志缓存
    		std::list<std::string> m_lstLogBuffer;
    
    		std::string m_strFileDir;//文件目录
    		std::string m_strFileExtendName;//文件扩展名
    		std::string m_strFileNameFormat;//文件名格式
    
    		std::size_t m_nMaxFileSize;//最大文件大小(字节)
    		std::size_t m_nMaxWriteFileSize;//最大写入文件大小(字节)
    		mutable std::size_t m_nFileIndex;//文件索引
    		std::size_t m_nFileCount;//文件最大个数
    
    		LogLevel m_emLogLevel;//日志等级
    
    		std::size_t m_nLogBufferLength;//日志缓存长度(字节)
    	};
    
    	template<>
    	class CTinyLog<wchar_t>
    	{
    
    	};
    
    	//////////////////////////////////////////////////////////////////////////
    	//	类说明:
    	//		多线程日志类,可以在多个线程中操作日志
    	//////////////////////////////////////////////////////////////////////////
    	template<typename T>
    	class CTinyLogM
    	{
    
    	};
    
    	template<>
    	class CTinyLogM<char>
    	{
    	public:
    		CTinyLogM();
    
    		~CTinyLogM();
    
    	public:
    		//添加日志记录
    		CTinyLogM& operator <<(const char* pszMessage);
    
    		//添加调试日志
    		void Debug(const char* pszMessage);
    
    		//添加信息日志
    		void Info(const char* pszMessage);
    
    		//添加错误日志
    		void Error(const char* pszMessage);
    
    		//将日志缓存写入到文件中
    		CTinyLogM& WriteToFile();
    
    		//得到第一个写入文件路径
    		std::string GetFirstWriteFilePath() const;
    
    		//得到下一个写入文件路径
    		std::string GetNextWriteFilePath() const;
    
    		//得到文件路径格式
    		std::string GetCurrentFilePathFormat() const;
    
    	public://属性
    		//设置文件目录
    		bool SetFileDir(const std::string& strFileDir);
    
    		//设置文件扩展名
    		bool SetFillExtendName(const std::string& strFileExtendName);
    
    		//设置文件名称格式
    		bool SetFileNameFormat(const std::string& strFileNameFormat);
    
    		//设置最大文件大小(字节)
    		void SetMaxFileSize(std::size_t size);
    
    		//设置最大写入文件大小(字节)
    		void SetMaxWriteFileSize(std::size_t size);
    
    		//设置最大文件个数
    		void SetMaxFileCount(std::size_t count);
    
    		//设置日志等级
    		void SetLogLevel(LogLevel emLogLevel);
    
    	private:
    		//日志缓存
    		std::list<std::string> m_lstLogBuffer;
    
    		std::string m_strFileDir;//文件目录
    		std::string m_strFileExtendName;//文件扩展名
    		std::string m_strFileNameFormat;//文件名格式
    
    		std::size_t m_nMaxFileSize;//最大文件大小(字节)
    		std::size_t m_nMaxWriteFileSize;//最大写入文件大小(字节)
    		mutable std::size_t m_nFileIndex;//文件索引
    		std::size_t m_nFileCount;//文件最大个数
    		//线程互斥锁
    		mutable TinyLogHelper::CLock m_lock;
    		
    		LogLevel m_emLogLevel;//日志等级
    
    		std::size_t m_nLogBufferLength;//日志缓存长度(字节)
    	};
    
    	template<>
    	class CTinyLogM<wchar_t>
    	{
    
    	};
    }
    
    #endif

    TinyLog.cpp文件

    #include <time.h>
    #include "TinyLog.h"
    
    namespace TinyLogHelper
    {
    #ifdef _WINDOWS
    
    	//////////////////////////////////////////////////////////////////////////
    	//	函数功能:
    	//		获取当前目录
    	//////////////////////////////////////////////////////////////////////////
    	template<>
    	std::string GetCurrentDir<std::string>()
    	{
    		std::string s(256, '');
    		DWORD dwLength = GetCurrentDirectoryA(s.size(), &s[0]);
    		return s.substr(0, dwLength);
    	}
    
    	template<>
    	std::wstring GetCurrentDir<std::wstring>()
    	{
    		std::wstring s(256, L'');
    		DWORD dwLength = GetCurrentDirectoryW(s.size(), &s[0]);
    		return s.substr(0, dwLength);
    	}
    #endif
    }
    
    namespace TinyLog
    {
    	CTinyLog<char>::CTinyLog()
    	{
    		m_strFileDir = TinyLogHelper::GetCurrentDir<std::string>();
    		m_strFileDir += "/";
    		SetFillExtendName(".log");
    		SetFileNameFormat("_%d");
    
    		SetMaxFileSize(1 * 1024 * 1024);//1 MB
    		SetMaxWriteFileSize(4 * 1024);//4 KB
    		SetMaxFileCount(10);
    		m_nFileIndex = 1;
    		m_emLogLevel = LogLevelInfo;
    		m_nLogBufferLength = 0;
    	}
    
    	CTinyLog<char>::~CTinyLog()
    	{
    		WriteToFile();
    	}
    
    	//添加日志记录
    	CTinyLog<char>& CTinyLog<char>::operator <<(const char* pszMessage)
    	{
    		time_t timet;
    		struct tm* pTime = NULL;
    		char szTime[256] = {0};
    		int nCharNum = 0;
    		//得到当前时间
    		time(&timet);
    		pTime = localtime(&timet);
    		nCharNum = sprintf(szTime, "%02d-%02d-%02d	", pTime->tm_hour, pTime->tm_min, pTime->tm_sec);
    		if (nCharNum > 0)
    		{
    			std::string s;
    			s = s + szTime + pszMessage;
    			m_lstLogBuffer.push_back(s);//添加记录
    			m_nLogBufferLength += (s.size() + 2);
    		}
    		//写入缓存日志到文件
    		if (m_nLogBufferLength > m_nMaxWriteFileSize)
    		{
    			WriteToFile();
    		}
    
    		return *this;
    	}
    
    	//添加调试日志
    	void CTinyLog<char>::Debug(const char* pszMessage)
    	{
    		if (m_emLogLevel == LogLevelDebug)
    		{
    			std::string s = pszLogLevelString[m_emLogLevel];
    			s = s + "	" + pszMessage;
    			*this << s.c_str();
    		}
    	}
    
    	//添加信息日志
    	void CTinyLog<char>::Info(const char* pszMessage)
    	{
    		if (m_emLogLevel == LogLevelInfo ||
    			m_emLogLevel == LogLevelDebug)
    		{
    			std::string s = pszLogLevelString[m_emLogLevel];
    			s = s + "	" + pszMessage;
    			*this << s.c_str();
    		}
    	}
    
    	//添加错误日志
    	void CTinyLog<char>::Error(const char* pszMessage)
    	{
    		if (m_emLogLevel == LogLevelError ||
    			m_emLogLevel == LogLevelDebug)
    		{
    			std::string s = pszLogLevelString[m_emLogLevel];
    			s = s + "	" + pszMessage;
    			*this << s.c_str();
    		}
    	}
    
    	//将日志缓存写入到文件中
    	CTinyLog<char>& CTinyLog<char>::WriteToFile()
    	{
    		bool bRet = false;
    		
    		try
    		{
    			std::string path;
    			std::ofstream ofs;
    			//打开第一个写入的文件
    			path = GetFirstWriteFilePath();
    			if (path.empty())
    			{
    				bRet = false;
    				throw bRet;
    			}
    			ofs.open(path, std::ios::app);
    			if (!ofs.is_open())
    			{
    				bRet = false;
    				throw bRet;
    			}
    			std::size_t nFileSize = 0;
    			std::list<std::string>::iterator beg, end;
    
    			beg = m_lstLogBuffer.begin();
    			end = m_lstLogBuffer.end();
    			while (beg != end)
    			{
    				ofs.seekp(0, std::ios::end);
    				nFileSize = ofs.tellp();
    				if (nFileSize + beg->size() + 2 < m_nMaxFileSize)
    				{
    					ofs << *beg << std::endl;//回车换行
    					m_nLogBufferLength -= (beg->size() + 2);
    					beg = m_lstLogBuffer.erase(beg);
    				}
    				else
    				{
    					//打开下一个写入的文件
    					path = GetNextWriteFilePath();
    					if (path.empty())
    					{
    						bRet = false;
    						throw bRet;
    					}
    					if (ofs.is_open())
    					{
    						ofs.close();
    					}
    					ofs.open(path, std::ios::app);
    					if (!ofs.is_open())
    					{
    						bRet = false;
    						throw bRet;
    					}
    				}
    			}
    			bRet = true;
    		}
    		catch (bool)
    		{
    		}
    
    		return *this;
    	}
    
    	//得到第一个写入文件路径
    	std::string CTinyLog<char>::GetFirstWriteFilePath() const
    	{
    		std::string path;
    
    		try
    		{
    			std::string strPathFromat = GetCurrentFilePathFormat();
    			std::size_t nPos = strPathFromat.rfind("%d");
    			if (nPos == strPathFromat.npos)
    			{
    				path = "";
    				throw path;
    			}
    
    			std::string strTempPath;
    			char szNumber[32] = {0};
    			std::ifstream file;
    
    			for (std::size_t i = m_nFileIndex; i < m_nFileCount + 1; ++i)
    			{
    				memset(szNumber, 0, 32);
    				itoa(i, szNumber, 10);
    				strTempPath = strPathFromat;
    				strTempPath.replace(nPos, 2, szNumber);
    
    				file.open(strTempPath, std::ios::app);
    				if (file.is_open())
    				{
    					file.seekg(0, std::ios::end);
    					if (file.tellg() < m_nMaxFileSize)
    					{
    						m_nFileIndex = i;
    						path = strTempPath;
    						break;
    					}
    				}
    				else
    				{
    					m_nFileIndex = i;
    					path = strTempPath;
    					break;
    				}
    			}
    		}
    		catch (const std::string&)
    		{
    		}
    
    		return path;
    	}
    
    	//得到下一个写入文件路径
    	std::string CTinyLog<char>::GetNextWriteFilePath() const
    	{
    		std::string path;
    		std::string strFilePathFormat;
    		std::size_t nPos = 0;
    		char szNum[32] = {0};
    
    		if (m_nFileIndex > m_nFileCount-1)
    		{
    			return path;
    		}
    		strFilePathFormat = GetCurrentFilePathFormat();
    		nPos = strFilePathFormat.rfind("%d");
    		if (nPos != strFilePathFormat.npos)
    		{
    			++m_nFileIndex;
    			itoa(m_nFileIndex, szNum, 10);
    			path = strFilePathFormat;
    			path.replace(nPos, 2, szNum);
    		}
    		return path;
    	}
    
    	//得到文件路径格式
    	std::string CTinyLog<char>::GetCurrentFilePathFormat() const
    	{
    		//文件路径格式
    		std::string strFilePathFormat;
    
    		try
    		{
    			if (m_strFileDir.empty() ||
    				m_strFileNameFormat.empty() ||
    				m_strFileExtendName.empty())
    			{
    				strFilePathFormat = "";
    				throw strFilePathFormat;
    			}
    			//获取本地时间
    			time_t timet;
    			struct tm* pTime = NULL;
    			char szTime[256] = {0};
    
    			time(&timet);
    			pTime = localtime(&timet);
    			sprintf(szTime, "%d-%02d-%02d", 1900 + pTime->tm_year, 1 + pTime->tm_mon, pTime->tm_mday);
    			strFilePathFormat = m_strFileDir + szTime + m_strFileNameFormat + m_strFileExtendName;
    		}
    		catch (const std::string&)
    		{
    		}
    
    		return strFilePathFormat;
    	}
    
    	//设置文件目录
    	bool CTinyLog<char>::SetFileDir(const std::string& strFileDir)
    	{
    		if (!strFileDir.empty() &&
    			(strFileDir.back() == '\' ||
    			strFileDir.back() == '/'))
    		{
    			m_strFileDir = strFileDir;
    			return true;
    		}
    		return false;
    	}
    
    	//设置文件扩展名
    	bool CTinyLog<char>::SetFillExtendName(const std::string& strFileExtendName)
    	{
    		if (strFileExtendName.size() > 1 &&
    			strFileExtendName.front() == '.')
    		{
    			m_strFileExtendName = strFileExtendName;
    			return true;
    		}
    		return false;
    	}
    
    	//设置文件名称格式
    	bool CTinyLog<char>::SetFileNameFormat(const std::string& strFileNameFormat)
    	{
    		if (strFileNameFormat.size() > 1 &&
    			strFileNameFormat.find("%d") != strFileNameFormat.npos)
    		{
    			m_strFileNameFormat = strFileNameFormat;
    			return true;
    		}
    		return false;
    	}
    
    	//设置最大文件大小(字节)
    	void CTinyLog<char>::SetMaxFileSize(std::size_t size)
    	{
    		m_nMaxFileSize = size;
    	}
    
    	//设置最大写入文件大小(字节)
    	void CTinyLog<char>::SetMaxWriteFileSize(std::size_t size)
    	{
    		m_nMaxWriteFileSize = size;
    	}
    
    	//设置最大文件个数
    	void CTinyLog<char>::SetMaxFileCount(std::size_t count)
    	{
    		m_nFileCount = count;
    	}
    
    	//设置日志等级
    	void CTinyLog<char>::SetLogLevel(LogLevel emLogLevel)
    	{
    		m_emLogLevel = emLogLevel;
    	}
    
    
    	//////////////////////////////////////////////////////////////////////////
    	//	类说明:
    	//		多线程日志类,可以在多个线程中操作日志
    	//////////////////////////////////////////////////////////////////////////
    	CTinyLogM<char>::CTinyLogM()
    	{
    		m_strFileDir = TinyLogHelper::GetCurrentDir<std::string>();
    		m_strFileDir += "/";
    		SetFillExtendName(".log");
    		SetFileNameFormat("_%d");
    
    		SetMaxFileSize(1 * 1024 * 1024);//1 MB
    		SetMaxWriteFileSize(4 * 1024);//4 KB
    		SetMaxFileCount(10);
    		m_nFileIndex = 1;
    		m_emLogLevel = LogLevelInfo;
    		m_nLogBufferLength = 0;
    	}
    
    	CTinyLogM<char>::~CTinyLogM()
    	{
    		WriteToFile();
    	}
    
    	//添加日志记录
    	CTinyLogM<char>& CTinyLogM<char>::operator <<(const char* pszMessage)
    	{
    		time_t timet;
    		struct tm* pTime = NULL;
    		char szTime[256] = {0};
    		int nCharNum = 0;
    
    		time(&timet);
    		pTime = localtime(&timet);
    		nCharNum = sprintf(szTime, "%02d-%02d-%02d	", pTime->tm_hour, pTime->tm_min, pTime->tm_sec);
    		if (nCharNum > 0)
    		{
    			std::string s;
    			s = s + szTime + pszMessage;
    			m_lock.Lock();
    			m_lstLogBuffer.push_back(s);
    			m_nLogBufferLength += (s.size() + 2);
    			m_lock.UnLock();
    		}
    
    		if (m_nLogBufferLength > m_nMaxWriteFileSize)
    		{
    			WriteToFile();
    		}
    
    		return *this;
    	}
    
    	//添加调试日志
    	void CTinyLogM<char>::Debug(const char* pszMessage)
    	{
    		if (m_emLogLevel == LogLevelDebug)
    		{
    			*this << pszLogLevelString[m_emLogLevel] << "	" << pszMessage;
    		}
    	}
    
    	//添加信息日志
    	void CTinyLogM<char>::Info(const char* pszMessage)
    	{
    		if (m_emLogLevel == LogLevelInfo ||
    			m_emLogLevel == LogLevelDebug)
    		{
    			*this << pszLogLevelString[m_emLogLevel] << "	" << pszMessage;
    		}
    	}
    
    	//添加错误日志
    	void CTinyLogM<char>::Error(const char* pszMessage)
    	{
    		if (m_emLogLevel == LogLevelError ||
    			m_emLogLevel == LogLevelDebug)
    		{
    			*this << pszLogLevelString[m_emLogLevel] << "	" << pszMessage;
    		}
    	}
    
    	//将日志缓存写入到文件中
    	CTinyLogM<char>& CTinyLogM<char>::WriteToFile()
    	{
    		bool bRet = false;
    
    		try
    		{
    			std::string path;
    			std::ofstream ofs;
    			
    			//打开第一个写入的文件
    			path = GetFirstWriteFilePath();
    			if (path.empty())
    			{
    				bRet = false;
    				throw bRet;
    			}
    			m_lock.Lock();
    			ofs.open(path, std::ios::app);
    			if (!ofs.is_open())
    			{
    				bRet = false;
    				throw bRet;
    			}
    			std::size_t nFileSize = 0;
    			std::list<std::string>::iterator beg, end;
    
    			beg = m_lstLogBuffer.begin();
    			end = m_lstLogBuffer.end();
    			while (beg != end)
    			{
    				ofs.seekp(0, std::ios::end);
    				nFileSize = ofs.tellp();
    				if (nFileSize + beg->size() + 2 < m_nMaxFileSize)
    				{
    					ofs << *beg << std::endl;//回车换行
    					m_nLogBufferLength -= (beg->size() + 2);
    					beg = m_lstLogBuffer.erase(beg);
    				}
    				else
    				{
    					//打开下一个写入的文件
    					path = GetNextWriteFilePath();
    					if (path.empty())
    					{
    						bRet = false;
    						throw bRet;
    					}
    					if (ofs.is_open())
    					{
    						ofs.close();
    					}
    					ofs.open(path, std::ios::app);
    					if (!ofs.is_open())
    					{
    						bRet = false;
    						throw bRet;
    					}
    				}
    			}
    			bRet = true;
    		}
    		catch (bool)
    		{
    		}
    
    		m_lock.UnLock();
    		return *this;
    	}
    
    	//得到第一个写入文件路径
    	std::string CTinyLogM<char>::GetFirstWriteFilePath() const
    	{
    		std::string path;
    
    		try
    		{
    			std::string strPathFromat = GetCurrentFilePathFormat();
    			std::size_t nPos = strPathFromat.rfind("%d");
    			if (nPos == strPathFromat.npos)
    			{
    				path = "";
    				throw path;
    			}
    
    			std::string strTempPath;
    			char szNumber[32] = {0};
    			std::ifstream file;
    
    			m_lock.Lock();
    			for (std::size_t i = m_nFileIndex; i < m_nFileCount + 1; ++i)
    			{
    				memset(szNumber, 0, 32);
    				itoa(i, szNumber, 10);
    				strTempPath = strPathFromat;
    				strTempPath.replace(nPos, 2, szNumber);
    
    				file.open(strTempPath, std::ios::app);
    				if (file.is_open())
    				{
    					file.seekg(0, std::ios::end);
    					if (file.tellg() < m_nMaxFileSize)
    					{
    						m_nFileIndex = i;
    						path = strTempPath;
    						break;
    					}
    				}
    				else
    				{
    					m_nFileIndex = i;
    					path = strTempPath;
    					break;
    				}
    			}
    			m_lock.UnLock();
    		}
    		catch (const std::string&)
    		{
    		}
    
    		return path;
    	}
    
    	//得到下一个写入文件路径
    	std::string CTinyLogM<char>::GetNextWriteFilePath() const
    	{
    		std::string path;
    		std::string strFilePathFormat;
    		std::size_t nPos = 0;
    		char szNum[32] = {0};
    
    		if (m_nFileIndex > m_nFileCount-1)
    		{
    			return path;
    		}
    		strFilePathFormat = GetCurrentFilePathFormat();
    		nPos = strFilePathFormat.rfind("%d");
    		if (nPos != strFilePathFormat.npos)
    		{
    			m_lock.Lock();
    			++m_nFileIndex;
    			m_lock.UnLock();
    			itoa(m_nFileIndex, szNum, 10);
    			path = strFilePathFormat;
    			path.replace(nPos, 2, szNum);
    		}
    		return path;
    	}
    
    	//得到文件路径格式
    	std::string CTinyLogM<char>::GetCurrentFilePathFormat() const
    	{
    		//文件路径格式
    		std::string strFilePathFormat;
    
    		try
    		{
    			if (m_strFileDir.empty() ||
    				m_strFileNameFormat.empty() ||
    				m_strFileExtendName.empty())
    			{
    				strFilePathFormat = "";
    				throw strFilePathFormat;
    			}
    			//获取本地时间
    			time_t timet;
    			struct tm* pTime = NULL;
    			char szTime[256] = {0};
    
    			time(&timet);
    			pTime = localtime(&timet);
    			sprintf(szTime, "%d-%02d-%02d", 1900 + pTime->tm_year, 1 + pTime->tm_mon, pTime->tm_mday);
    			strFilePathFormat = m_strFileDir + szTime + m_strFileNameFormat + m_strFileExtendName;
    		}
    		catch (const std::string&)
    		{
    		}
    
    		return strFilePathFormat;
    	}
    
    	//设置文件目录
    	bool CTinyLogM<char>::SetFileDir(const std::string& strFileDir)
    	{
    		if (!strFileDir.empty() &&
    			(strFileDir.back() == '\' ||
    			strFileDir.back() == '/'))
    		{
    			m_lock.Lock();
    			m_strFileDir = strFileDir;
    			m_lock.UnLock();
    			return true;
    		}
    		return false;
    	}
    
    	//设置文件扩展名
    	bool CTinyLogM<char>::SetFillExtendName(const std::string& strFileExtendName)
    	{
    		if (strFileExtendName.size() > 1 &&
    			strFileExtendName.front() == '.')
    		{
    			m_lock.Lock();
    			m_strFileExtendName = strFileExtendName;
    			m_lock.UnLock();
    			return true;
    		}
    		return false;
    	}
    
    	//设置文件名称格式
    	bool CTinyLogM<char>::SetFileNameFormat(const std::string& strFileNameFormat)
    	{
    		if (strFileNameFormat.size() > 1 &&
    			strFileNameFormat.find("%d") != strFileNameFormat.npos)
    		{
    			m_lock.Lock();
    			m_strFileNameFormat = strFileNameFormat;
    			m_lock.UnLock();
    			return true;
    		}
    		return false;
    	}
    
    	//设置最大文件大小(字节)
    	void CTinyLogM<char>::SetMaxFileSize(std::size_t size)
    	{
    		m_lock.Lock();
    		m_nMaxFileSize = size;
    		m_lock.UnLock();
    	}
    
    	//设置最大写入文件大小(字节)
    	void CTinyLogM<char>::SetMaxWriteFileSize(std::size_t size)
    	{
    		m_lock.Lock();
    		m_nMaxWriteFileSize = size;
    		m_lock.UnLock();
    	}
    
    	//设置最大文件个数
    	void CTinyLogM<char>::SetMaxFileCount(std::size_t count)
    	{
    		m_nFileCount = count;
    	}
    
    	//设置日志等级
    	void CTinyLogM<char>::SetLogLevel(LogLevel emLogLevel)
    	{
    		m_emLogLevel = emLogLevel;
    	}
    }

    测试:

    TinyLog::CTinyLog<char> log;
    
    	log.SetMaxFileSize(1 * 1024 * 1024);
    	log.SetMaxWriteFileSize(1 * 1024 * 1024);
    	log.SetLogLevel(TinyLog::LogLevelError);
    	for (int i = 0; i < 60000; ++i)
    	{
    		log.Error("Hello Word!");
    	}
    	log.WriteToFile();


     

  • 相关阅读:
    字典-dict
    队列-deque
    with-as 语句
    odoo 在"动作"("Action")菜单中添加子菜单, 点击子菜单弹窗自定义form
    odoo onchange readonly
    pyhton 连接 oracle
    PyCharm WSL 配置
    docker 安装 oracle
    docker 安装 mssql
    odoo =like
  • 原文地址:https://www.cnblogs.com/dongc/p/5225120.html
Copyright © 2020-2023  润新知