IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 一个简简单单的废物C++11日志输出封装 -> 正文阅读

[C++知识库]一个简简单单的废物C++11日志输出封装

实现

#pragma once

#ifndef _LOG_CPP_HPP_
#define _LOG_CPP_HPP_

#include <iostream>
#include <string>
#include <deque>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <fstream>
#ifdef _MSC_VER
#include <ctime>
#include <memory>
#define LOG_FUNCTION __FUNCSIG__
#else
#define LOG_FUNCTION __PRETTY_FUNCTION__
#endif
// 日志输出等级
#ifndef LOG_CPP_LEVEL
#define LOG_CPP_LEVEL 100
#endif

// 默认日志输出等级,全部
#define LOG_CPP_DEBUG 1
#define LOG_CPP_INFO 10
#define LOG_CPP_ERROR 100

/**
* @brief Get the Current Time object
*
* @return std::string
*/
inline std::string getCurrentTime()
{
#ifndef _MSC_VER
	auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
	struct tm *ptm = localtime(&tt);
	char date[60] = { 0 };
	sprintf(date, "%d-%02d-%02d %02d:%02d:%02d",
		(int)ptm->tm_year + 1900, (int)ptm->tm_mon + 1, (int)ptm->tm_mday,
		(int)ptm->tm_hour, (int)ptm->tm_min, (int)ptm->tm_sec);
	return date;
#else
	struct tm newtime;
	char am_pm[] = "AM";
	__time64_t long_time;
	char date[60] = { 0 };
	errno_t err;

	// Get time as 64-bit integer.
	_time64(&long_time);
	// Convert to local time.
	err = _localtime64_s(&newtime, &long_time);
	sprintf_s(date, "%d-%02d-%02d %02d:%02d:%02d",
		(int)newtime.tm_year + 1900, (int)newtime.tm_mon + 1, (int)newtime.tm_mday,
		(int)newtime.tm_hour, (int)newtime.tm_min, (int)newtime.tm_sec);
	return date;
#endif
}

class SpaceFunction
{
public:
	SpaceFunction &operator<<(const std::string _t) { return *this; }
	SpaceFunction &operator<<(const int _t) { return *this; }
};

class LogCpp
{
private:
	/**
	* @brief 本对象的任务队列
	*
	*/
	std::deque<std::string> m_task;

	/**
	* @brief 写入线程条件变量
	*
	*/
	std::condition_variable m_cond;

	/**
	* @brief 写入线程执行锁
	*
	*/
	std::mutex m_mutex;

	/**
	* @brief 初始化
	*
	*/
	void ini()
	{
		m_thread = std::make_shared<std::thread>([this]()
		{
			while (true) {
				std::unique_lock<std::mutex> lock(m_mutex);
				if (this->m_task.empty() || this->m_logFile == nullptr) {
					m_cond.wait(lock);
				}
				this->m_logFile->write(m_task.front().c_str(), m_task.front().size());
				m_task.pop_front();
				std::this_thread::yield();
			} });
		m_thread->detach();
	}

public:
	/**
	* @brief 空白函数
	*
	* @param _t 需要忽略的参数
	* @return LogCpp& 自身引用
	*/
	SpaceFunction _spaceFunction;
	/**
	* @brief 日志文件指针
	*
	*/
	std::shared_ptr<std::ofstream> m_logFile = nullptr;
	/**
	* @brief 写文件线程指针
	*
	*/
	std::shared_ptr<std::thread> m_thread = nullptr;

public:
	/**
	* @brief Construct a new LogCpp object
	*
	*/
	LogCpp()
	{
		ini();
	}

	~LogCpp()
	{
		getGlobalLogCpp()->m_logFile->close();
	}

	/**
	* @brief Set the Global Path object
	*
	* @param filePath
	*/
	static void setGlobalPath(const std::string &filePath)
	{
		if (nullptr != getGlobalLogCpp()->m_logFile)
		{
			getGlobalLogCpp()->m_logFile->close();
			getGlobalLogCpp()->m_logFile = nullptr;
		}
		getGlobalLogCpp()->m_logFile = std::make_shared<std::ofstream>(filePath, std::ios::app);
	}

	/**
	* @brief 输出日志
	*
	* @param log 日志串
	* @return LogCpp 全局对象
	*/
	LogCpp &operator<<(const std::string &log)
	{
		std::unique_lock<std::mutex> lock(m_mutex);
		if (m_task.empty())
		{
			m_task.emplace_back(log);
		}
		else
		{
			m_task.back().append(log);
		}
		m_cond.notify_one();
		return *this;
	}
	/**
	* @brief 输出日志
	*
	* @param num 数字
	* @return LogCpp 全局对象
	*/
	LogCpp &operator<<(int num)
	{
		std::unique_lock<std::mutex> lock(m_mutex);
		if (m_task.empty())
		{
			m_task.emplace_back(std::to_string(num));
		}
		else
		{
			m_task.back().append(std::to_string(num));
		}
		m_cond.notify_one();
		return *this;
	}

	/**
	* @brief 新的一行
	*
	* @return LogCpp 对象本身
	*/
	LogCpp &addLine()
	{
		std::unique_lock<std::mutex> lock(m_mutex);
		if (m_task.empty())
		{
			m_task.emplace_back("\n" + getCurrentTime());
		}
		else
		{
			m_task.back().append("\n" + getCurrentTime());
		}
		m_cond.notify_one();
		return *this;
	}

	/**
	* @brief 错误输出
	*
	* @return LogCpp& 自身引用
	*/
	LogCpp &err()
	{

#if LOG_CPP_LEVEL >= LOG_CPP_ERROR
#define LogErr (LogCpp::getGlobalLogCpp()->addLine().err() << __FILE__ << ":" << LOG_FUNCTION << ":" << __LINE__ << " ")
		std::unique_lock<std::mutex> lock(m_mutex);
		if (m_task.empty())
		{
			m_task.emplace_back(" [ERROR] ");
		}
		else
		{
			m_task.back().append(" [ERROR] ");
		}
		m_cond.notify_one();
#else
		// 舍弃流
#define LogErr (LogCpp::getGlobalLogCpp()->_spaceFunction)
#endif // LOG_CPP_LEVEL
		return *this;
	}

	/**
	* @brief 信息输出
	*
	* @return LogCpp& 自身引用
	*/
	LogCpp &info()
	{

#if LOG_CPP_LEVEL >= LOG_CPP_INFO
#define LogInfo (LogCpp::getGlobalLogCpp()->addLine().info() << __FILE__ << ":" << LOG_FUNCTION << ":" << __LINE__ << " ")
		std::unique_lock<std::mutex> lock(m_mutex);
		if (m_task.empty())
		{
			m_task.emplace_back(" [INFO] ");
		}
		else
		{
			m_task.back().append(" [INFO] ");
		}
		m_cond.notify_one();
#else
		// 舍弃流
#define LogErr (LogCpp::getGlobalLogCpp()->_spaceFunction)
#endif // LOG_CPP_LEVEL
		return *this;
	}

	/**
	* @brief 调试输出
	*
	* @return LogCpp& 自身引用
	*/
	LogCpp &debug()
	{
#if LOG_CPP_LEVEL >= LOG_CPP_DEBUG
#define LogDebug (LogCpp::getGlobalLogCpp()->addLine().debug() << __FILE__ << ":" << LOG_FUNCTION << ":" << __LINE__ << " ")
		std::unique_lock<std::mutex> lock(m_mutex);
		if (m_task.empty())
		{
			m_task.emplace_back(" [DEBUG] ");
		}
		else
		{
			m_task.back().append(" [DEBUG] ");
		}
		m_cond.notify_one();
#else
		// 舍弃流
#define LogErr (LogCpp::getGlobalLogCpp()->_spaceFunction)
#endif // LOG_CPP_LEVEL
		return *this;
	}

	/**
	* @brief 全局日志对象指针
	*
	*/
	static LogCpp *getGlobalLogCpp()
	{
		static LogCpp *g_logCpp = new LogCpp();
		return g_logCpp;
	}
};

#endif // !_LOG_CPP_HPP_


示例

#define LOG_CPP_LEVEL 10

#include "./logcpp.hpp"
#include <iostream>
#include <chrono>
#include <string>
#include <sstream>

int main() {
    LogCpp::setGlobalPath(".\\log.txt");
    while (true) {
        LogErr << "卧槽卧槽";
        LogInfo << "卧槽卧槽";
        LogDebug << "卧槽卧槽";
    }
    return 0;
}

地址

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-26 21:57:27  更:2021-12-26 22:00:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:04:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码