windows日志实现

#pragma once
#include <sstream>

class Logger
{
public:
	enum LogLevel
	{
		TRACE,
		DEBUG,
		INFO,
		WARN,
		ERROR,
		FATAL,
		LOGLEVEL_COUNT
	};

	Logger(const char *file, int line);
	Logger(const char *file, int line, LogLevel level);
	Logger(const char *file, int line, bool isAbort);
	~Logger();

	static void setHandle(FILE* fd);
	static void setLevel(LogLevel level);
	static LogLevel level();

	std::ostream& stream();

private:
	void initMsgHead(const char *file, int line, LogLevel level = TRACE);

private:
	LogLevel level_;
	FILE* fd_;
	std::ostringstream stream_;

	static LogLevel s_level_;
	static FILE* s_fd_;
};

#define LOG_TRACE if (Logger::level() <= Logger::TRACE) \
	Logger(__FILE__, __LINE__, Logger::TRACE).stream()
#define LOG_DEBUG if (Logger::level() <= Logger::DEBUG) \
	Logger(__FILE__, __LINE__, Logger::DEBUG).stream()
#define LOG_INFO if (Logger::level() <= Logger::INFO) \
	Logger(__FILE__, __LINE__, Logger::INFO).stream()
#define LOG_WARN if (Logger::level() <= Logger::WARN) \
	Logger(__FILE__, __LINE__, Logger::WARN).stream()
#define LOG_ERROR Logger(__FILE__, __LINE__, Logger::ERROR).stream()
#define LOG_FATAL Logger(__FILE__, __LINE__, Logger::FATAL).stream()
#include "stdafx.h"
#include "Logger.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sstream>
#include <assert.h>

Logger::LogLevel Logger::s_level_ = Logger::TRACE;
FILE* Logger::s_fd_ = NULL;

Logger::Logger(const char *file, int line)
{
    initMsgHead(file, line);
}

Logger::Logger(const char *file, int line, LogLevel level)
{
    initMsgHead(file, line, level);
}

Logger::Logger(const char *file, int line, bool isAbort)
{
    LogLevel level = (isAbort?FATAL:ERROR);
	initMsgHead(file, line, level);
}

Logger::~Logger()
{
	if (s_fd_) {
		stream_ << std::endl;
		std::string buf(stream_.str());
		fwrite(buf.data(), sizeof(char), buf.size(), s_fd_);
		if (level_ == FATAL) {
			abort();
		}
	}
}

void Logger::setHandle(FILE* fd)
{
	s_fd_ = fd;
}

void Logger::setLevel(LogLevel level)
{
    s_level_ = level;
}

Logger::LogLevel Logger::level()
{
	return s_level_;
}

std::ostream& Logger::stream()
{
	return stream_;
}

void Logger::initMsgHead(const char *file, int line, LogLevel level)
{
    const char *logLevel[LOGLEVEL_COUNT] = {"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
    char msgHead[256] = {0};
    time_t curtime = time(NULL);
	struct tm curtm;
	localtime_s(&curtm, &curtime);
    const char *pstr = strrchr(file, '\\');
    const char *name = ((pstr!=NULL) ? pstr+1 : file);

    level_ = level;
   
	sprintf_s(msgHead, sizeof(msgHead), "%04d-%02d-%02d %02d:%02d:%02d[%s:%04d][%s] - ",
		curtm.tm_year+1900, curtm.tm_mon+1, curtm.tm_mday, curtm.tm_hour, curtm.tm_min, curtm.tm_sec,
		name, line, logLevel[level_]);
	
    stream_ << msgHead;
}

#include "Logger.h"


int _tmain(int argc, _TCHAR* argv[])
{
	FILE *fd = NULL;
	if (0 != fopen_s(&fd, "log.txt", "a+")) {
		printf("open error\n");
	}

	Logger::setHandle(fd);
	Logger::setLevel(Logger::WARN);

	for (int i=0; i<2000; i++) {
		LOG_TRACE << "this is trace";
		LOG_WARN << "this is warning";
		LOG_ERROR << "this is error" << ", number:" << i+1;
		LOG_WARN << "this is last";
	}

	LOG_ERROR << "endline" << std::endl;
	fclose(fd);

	system("pause");
	return 0;
}


你可能感兴趣的:(windows日志实现)