c++ 日志类

// .h
/**
 * @brief 日志类
*/
class Logger
{
public:

	enum LogLevel
	{
		LL_DEBUG, // 优先级 低
		LL_INFO,
		LL_WARNING,
		LL_ERROR, // 优先级 高
		LL_NONE,
	};

	enum LogTarget
	{
		LT_FILE, // 文件
		LT_TERMINAL, // 终端
		LT_FILEANDTERMINAL // both
	};

public:
	Logger();
	Logger(LogTarget tar, const std::string& path, LogLevel level);
	~Logger();

public:
	static Logger* getInstance();

public:
	void Debug(std::string& text);
	void Info(std::string& text);
	void Wraning(std::string& text);
	void Error(std::string& text);

private:
	class Impl;
	std::unique_ptr<Impl> impl_;
};
// .cpp
/**
 * @brief 日志类
*/
class Logger::Impl
{
public:
	Impl(Logger::LogTarget, const std::string&, Logger::LogLevel);
	~Impl();

public:
	void Export(LogLevel level, const std::string& info);

private:
	std::string currentTime();

public:
	LogTarget target_;
	std::string path_;
	LogLevel level_;

private:
	std::ofstream m_file_;
	std::string m_content_;
};

Logger::Impl::Impl(Logger::LogTarget target, const std::string & path, Logger::LogLevel level)
    : target_(target)
    , path_(path)
    , level_(level)
{
	m_content_ = "************************Start***********************\n";

	if (target_ != LogTarget::LT_FILE)
	{
		std::cout << m_content_;
	}
	if (target_ != LogTarget::LT_TERMINAL)
	{
		m_file_.open(path, std::ios::out | std::ios::app);
		m_file_ << m_content_;
	}
}

Logger::Impl::~Impl()
{
	m_content_ = "************************End***********************\n";

	if (target_ != LogTarget::LT_FILE)
	{
		std::cout << m_content_;
	}
	if (target_ != LogTarget::LT_TERMINAL)
	{
		m_file_ << m_content_;
		m_file_.close();
	}
}

void Logger::Impl::Export(LogLevel level, const std::string &info)
{
	m_content_ = "";

	if (level_ > level)
		return;

	switch (level)
	{
	case Logger::LL_DEBUG:
		m_content_.append("[DEBUG] ");
		break;
	case Logger::LL_INFO:
		m_content_.append("[INFO] ");
		break;
	case Logger::LL_WARNING:
		m_content_.append("[WARNING] ");
		break;
	case Logger::LL_ERROR:
		m_content_.append("[ERROR] ");
		break;
	default:
		break;
	}

	m_content_.append(currentTime());

	m_content_.append(info);

	m_content_.append("\n");

	if (target_ != LogTarget::LT_FILE)
	{
		std::cout << m_content_;
	}
	if (target_ != LogTarget::LT_TERMINAL)
	{
		m_file_ << m_content_;
	}
}

std::string Logger::Impl::currentTime()
{
	auto tNow = std::chrono::system_clock::now();
	auto tRawTime_ = std::chrono::system_clock::to_time_t(tNow);

	char buffer[_MAX_PATH];
	// %Y-%m-%d %H:%M:%S
	strftime(buffer, _MAX_PATH, "%H:%M:%S", localtime(&tRawTime_));

	auto tSec = std::chrono::duration_cast<std::chrono::seconds>(tNow.time_since_epoch());
	auto tMilli = std::chrono::duration_cast<std::chrono::milliseconds>(tNow.time_since_epoch());
	auto ms = std::to_string((tMilli - tSec).count());

	ms.insert(0,".000", 4 - ms.length());

	return buffer + ms + " ";
}

Logger::Logger()
{
	impl_ = std::make_unique<Impl>(Logger::LogTarget::LT_FILE, "calcSpeedJPEG.log", Logger::LogLevel::LL_DEBUG);
}

Logger::Logger(LogTarget tar, const std::string &path, LogLevel level)
{
	impl_ = std::make_unique<Impl>(tar, path, level);
}

Logger::~Logger()
{
}

Logger *Logger::getInstance()
{
	static Logger ins;
	return &ins;
}

void Logger::Debug(std::string &text)
{
	impl_->Export(LogLevel::LL_DEBUG, text);
}

void Logger::Info(std::string &text)
{
	impl_->Export(LogLevel::LL_INFO, text);
}

void Logger::Wraning(std::string &text)
{
	impl_->Export(LogLevel::LL_WARNING, text);
}

void Logger::Error(std::string &text)
{
	impl_->Export(LogLevel::LL_ERROR, text);
}

你可能感兴趣的:(C++/C,c++,笔记)