Skip to content

Instantly share code, notes, and snippets.

@shanewfx
Created April 26, 2013 02:56
Show Gist options
  • Save shanewfx/5464798 to your computer and use it in GitHub Desktop.
Save shanewfx/5464798 to your computer and use it in GitHub Desktop.
a log tool
#include "log.h"
#include <stdarg.h>
#include <windows.h>
FILE* Logger::m_hLogFile = NULL;
LogLevel Logger::m_LogLevel = LOG_TRACE;
std::string Logger::m_strFileDir = LOG_FILE_DIR;
std::string Logger::m_strFileName = LOG_FILE_NAME;
std::string Logger::m_strFilePath = LOG_FILE_PATH;
bool Logger::m_bCreateDir = true;
char* LogLevelStr[] = {
"TRACE",
"INFO",
"WARNING",
"ERROR",
"CRITICAL",
"FATAL",
};
Logger& Logger::Instance()
{
static Logger LoggerInstance;
return LoggerInstance;
}
void Logger::SetLogFileName(const std::string& strFileName)
{
m_strFileName = strFileName;
MakeLogFilePath();
}
bool Logger::SetLogFileDirectory(const std::string& strFileDir, bool bDeleteOldDir)
{
std::string strDirTemp = strFileDir;
if (strDirTemp.substr(strDirTemp.length() - 1, 1) == "\\") {
strDirTemp = strDirTemp.substr(0, strDirTemp.length() - 1);
}
if (!CreateLogDirectory(strDirTemp)) {
return false;
}
if (bDeleteOldDir) {
Dispose();
DeleteLogDirectory(m_strFileDir);
}
m_strFileDir = strDirTemp;
MakeLogFilePath();
return true;
}
void Logger::SetLogLevel(const LogLevel Level)
{
m_LogLevel = Level;
}
Logger::Logger()
{
Initialise();
}
Logger::~Logger()
{
Dispose();
}
bool Logger::Initialise()
{
if (m_hLogFile != NULL) {
return true;
}
if (m_bCreateDir) {
if (!SetLogFileDirectory(m_strFileDir)) {
return false;
}
m_bCreateDir = false;
}
m_hLogFile = fopen(m_strFilePath.c_str(), "w+");
if (m_hLogFile == NULL) {
return false;
}
return true;
}
void Logger::Dispose()
{
if (NULL != m_hLogFile) {
fflush(m_hLogFile);
fclose(m_hLogFile);
m_hLogFile = NULL;
}
}
void Logger::Log(const LogLevel Level, const char* Format, ...)
{
if (m_LogLevel > Level) {
return;
}
if (NULL == m_hLogFile && !Initialise()) {
return;
}
char szBuffer[1024];
va_list args;
va_start(args, Format);
vsprintf_s(szBuffer, Format, args);
va_end(args);
SYSTEMTIME st;
GetLocalTime(&st);
if (0 > fprintf(m_hLogFile, "[%02u:%02u:%02u:%03u] [%s] %s",
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
LogLevelStr[Level], szBuffer)) {
Dispose();
}
else {
fflush(m_hLogFile);
}
}
void Logger::MakeLogFilePath()
{
Dispose();
m_strFilePath = m_strFileDir + "\\";
m_strFilePath += m_strFileName;
}
bool Logger::CreateLogDirectory(const std::string& strFileDir)
{
char* pChar = NULL;
char strPathTemp[MAX_PATH] = { 0 };
memcpy(strPathTemp, strFileDir.c_str(), strFileDir.size());
pChar = strchr(strPathTemp, ':');
if (pChar == NULL) {
return false;
}
pChar = strchr(strPathTemp, '\\');
if (pChar == NULL) {
return false;
}
//C:\Dir1\Dir2\Dir3
do {
pChar = strchr(++pChar, '\\');
if (pChar == NULL) {
CreateDirectoryA(strPathTemp, NULL);
}
else {
*pChar = '\0';
CreateDirectoryA(strPathTemp, NULL);
memcpy(strPathTemp, strFileDir.c_str(), strFileDir.size());
}
} while (pChar != NULL);
return true;
}
bool Logger::DeleteLogDirectory(const std::string& strFileDir)
{
char* pChar = NULL;
char strPathTemp[MAX_PATH] = { 0 };
memcpy(strPathTemp, strFileDir.c_str(), strFileDir.size());
pChar = strchr(strPathTemp, ':');
if (pChar == NULL) {
return false;
}
pChar = strchr(strPathTemp, '\\');
if (pChar == NULL) {
return false;
}
pChar = strchr(++pChar, '\\');
if (pChar != NULL) {
*pChar = '\0';
}
return DeleteDirectoryFile(strPathTemp);;
}
bool Logger::DeleteDirectoryFile(char* lpszPath)
{
SHFILEOPSTRUCTA FileOp = { 0 };
FileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
FileOp.pFrom = lpszPath;
FileOp.pTo = NULL;
FileOp.wFunc = FO_DELETE;
return SHFileOperationA(&FileOp) == 0;
}
#ifndef _LOG_H
#define _LOG_H
#include <string>
#define DEBUG_LOG
#define LOG_FILE_DIR "C:\\DebugLog"
#define LOG_FILE_NAME "log.txt"
#define LOG_FILE_PATH "C:\\DebugLog\\log.txt"
#ifdef DEBUG_LOG
#define LogData Logger::Instance().Log
#define SetFileDirectory Logger::SetLogFileDirectory
#define SetFileName Logger::SetLogFileName
#define SetLevel Logger::SetLogLevel
#else
#define LogData
#define SetFileDirectory
#define SetFileName
#define SetLevel
#endif
typedef enum tagLogLevel {
LOG_TRACE,
LOG_INFO,
LOG_WARNING,
LOG_ERROR,
LOG_FATAL,
LOG_NONE,
} LogLevel;
class Logger
{
public:
static Logger& Instance();
static bool SetLogFileDirectory(const std::string& strFileDir, bool bDeleteOldDir = false);
static void SetLogFileName(const std::string& strFileName);
static void SetLogLevel(const LogLevel Level);
void Log(const LogLevel Level, const char* Format, ...);
private:
Logger();
Logger(Logger const&);
Logger& operator=(Logger const&);
~Logger();
static bool Initialise();
static void Dispose();
static void MakeLogFilePath();
static bool CreateLogDirectory(const std::string& strFileDir);
static bool DeleteLogDirectory(const std::string& strFileDir);
static bool DeleteDirectoryFile(char* lpszPath);
static FILE* m_hLogFile;
static LogLevel m_LogLevel;
static bool m_bCreateDir;
static std::string m_strFileDir;
static std::string m_strFileName;
static std::string m_strFilePath;
};
#endif//_LOG_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment