C++ 【异步日志模块和std::cout << 一样使用习惯替代性好】 使用示例,后续加上远程日志

devtools/2024/11/29 4:39:14/

简单 易用

使用示例

    CLogSystem::Instance().SetLogLevel( E_LOG_LEVEL::LOG_LEVEL_INFO | E_LOG_LEVEL::LOG_LEVEL_DEBUG | E_LOG_LEVEL::LOG_LEVEL_DUMP );CLogSystem::Instance().SetFileInfo(true, "./log.txt");LogDebug() << 12;LogInfo() << "hello, world!";std::string str = { 1, 2, 3, 4, 12 };QByteArray data;QDataStream out(&data, QIODevice::WriteOnly);out.setByteOrder(QDataStream::BigEndian);uint16_t u16MsgId = 0x55AA;uint8_t u8Length = 0x01;uint8_t u8Result = 0x01;out << u16MsgId << u8Length << u8Result;LogDump() << data.data();

在这里插入图片描述

公共头定义

/*
**  File name:   LogCommon.h
**  Author:      
**  Date:        2024-11-4
**  Brief:       日志系统公共头文件
**  Copyright (C) 1392019713@qq.com All rights reserved.
*/#pragma once#include <string>
#include <sstream>enum E_LOG_LEVEL
{LOG_LEVEL_DEBUG = 1,  // 调试信息LOG_LEVEL_INFO = 2,   // 一般信息LOG_LEVEL_WARN = 4,   // 警告信息LOG_LEVEL_ERROR = 16,  // 错误信息LOG_LEVEL_DUMP = 32,   // 16进制数据
};static const char* GetLogLevelString(int nLevel)
{switch (nLevel){case LOG_LEVEL_DEBUG:return "DEBUG";case LOG_LEVEL_INFO:return "INFO";case LOG_LEVEL_WARN:return "WARN";case LOG_LEVEL_ERROR:return "ERROR";case LOG_LEVEL_DUMP:return "DUMP";default:return "NONE";}
}**日志流类**
/*
**  File name:   LogStream.h
**  Author:      
**  Date:        2024-11-4
**  Brief:       日志流类
**  Copyright (C) 1392019713@qq.com All rights reserved.
*/#pragma once#include <stdint.h>
#include "LogCommon.h"
#include "LogSystem.h"
#include "LogWriter.h"
#include <string>
#include <chrono>class CByteArray;class CLogLocator
{
public:CLogLocator(const char* szFile, uint32_t nLine);~CLogLocator();public:const char* m_szFile;uint32_t m_nLine;
};class CLogStream
{
public:/** @brief 构造函数* @param eLevel 日志级别* @param szMsg 日志内容* @param szFile 日志文件名* @param szFunc 日志函数名* @param nLine 日志行号* @Note 日志格式为 [2024-01-01 12:34:56.789] [DEBUG] [file:func:line] [pid] msg*/CLogStream(E_LOG_LEVEL eLevel, const CLogLocator& rLogLocator);CLogStream& operator <<(bool bArg);CLogStream& operator <<(char cArg);CLogStream& operator <<(int16_t n16Arg);CLogStream& operator <<(uint16_t u16Arg);CLogStream& operator <<(int32_t n32Arg);CLogStream& operator <<(uint32_t u32Arg);CLogStream& operator <<(int64_t n64Arg);CLogStream& operator <<(uint64_t u64Arg);CLogStream& operator <<(double dArg);CLogStream& operator <<(const char* szArg);CLogStream& operator <<(const std::string& strArg);~CLogStream();private:std::string String2Hex(const std::string& str);private:std::string m_strMsg;std::string m_strLogHead;E_LOG_LEVEL m_eLevel;
};

实现

#include "../Include/LogStream.h"CLogLocator::CLogLocator(const char* szFile, uint32_t nLine)
{m_szFile = szFile;m_nLine = nLine;
}CLogLocator::~CLogLocator()
{
}//
CLogStream::CLogStream(E_LOG_LEVEL eLevel, const CLogLocator& rLogLocator)
{auto now = std::chrono::system_clock::now();std::time_t   now_time_t = std::chrono::system_clock::to_time_t(now);std::tm now_tm{};localtime_s(&now_tm, &now_time_t);auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;char szTime[27] = { 0 };strftime(szTime, sizeof(szTime), "[%Y-%m-%d %H:%M:%S", &now_tm);snprintf(szTime + strlen(szTime), sizeof(szTime) - strlen(szTime), ".%03ld]", static_cast<long>(milliseconds.count()));m_strLogHead = szTime + std::string(" [") + std::string(GetLogLevelString(eLevel)) + "]";if (CLogSystem::Instance().IsHasFileInfo()){m_strLogHead += " [" + std::string(rLogLocator.m_szFile) +  ":" + std::to_string(rLogLocator.m_nLine) + "]";}if (CLogSystem::Instance().IsHasPid()){auto tid = std::this_thread::get_id();std::stringstream s;s << tid;m_strLogHead += " [" + s.str() + "]";}m_eLevel = eLevel;
}CLogStream::~CLogStream()
{CByteArray byteArray;if (m_eLevel == E_LOG_LEVEL::LOG_LEVEL_DUMP){std::string strLog = String2Hex(m_strMsg);byteArray.m_strMsg = m_strLogHead + " " + strLog + "\n";std::cout << strLog << '\n';}else {byteArray.m_strMsg = m_strLogHead  + " " + m_strMsg + "\n";std::cout << m_strMsg << '\n';}CLogWriter::Instance().WriteLog(byteArray);
}std::string CLogStream::String2Hex(const std::string& str)
{std::string strResult;for (size_t i = 0; i < str.size(); i++){char szValue[4];memset(szValue, 0, sizeof(szValue));snprintf(szValue, sizeof(szValue), "%02X ", (uint8_t)str[i]);strResult += szValue;}return strResult;
}CLogStream& CLogStream::operator<<(bool bArg)
{if (bArg){m_strMsg += " true";}else{m_strMsg += " false";}return *this;
}CLogStream& CLogStream::operator<<(char cArg)
{m_strMsg += cArg;return *this;
}CLogStream& CLogStream::operator<<(int16_t n16Arg)
{m_strMsg += std::to_string(n16Arg);return *this;
}CLogStream& CLogStream::operator<<(uint16_t u16Arg)
{m_strMsg += std::to_string(u16Arg);return *this;
}CLogStream& CLogStream::operator<<(int32_t n32Arg)
{m_strMsg += std::to_string(n32Arg);return *this;
}CLogStream& CLogStream::operator<<(uint32_t u32Arg)
{m_strMsg += std::to_string(u32Arg);return *this;
}CLogStream& CLogStream::operator<<(int64_t n64Arg)
{m_strMsg += std::to_string(n64Arg);return *this;
}CLogStream& CLogStream::operator<<(uint64_t u64Arg)
{m_strMsg += std::to_string(u64Arg);return *this;
}CLogStream& CLogStream::operator<<(double dArg)
{m_strMsg += std::to_string(dArg);return *this;
}CLogStream& CLogStream::operator<<(const char* szArg)
{m_strMsg += szArg;return *this;
}CLogStream& CLogStream::operator<<(const std::string& strArg)
{m_strMsg += strArg;return *this;
}

具体实现链接 git https://gitee.com/wyj4869/LogSystem.git


http://www.ppmy.cn/devtools/137831.html

相关文章

一分钟食用前端测试框架Jest

安装 其实食用Jest是很简单的,我们只需要安装Jest即可 npm install --save-dev jestyarn add --dev jestpnpm add --save-dev jest ESmodule 本身来说,Jest是不支持Esmodule的,他支持CommonJS,我们需要Babel改一下 npm i --save-dev babel-jest babel/core babel/preset-env …

【八股文】小米

文章目录 一、vector 和 list 的区别&#xff1f;二、include 双引号和尖括号的区别&#xff1f;三、set 的底层数据结构&#xff1f;四、set 和 multiset 的区别&#xff1f;五、map 和 unordered_map 的区别&#xff1f;六、虚函数和纯虚函数的区别&#xff1f;七、extern C …

SpringBoot源码-spring boot启动入口ruan方法主线分析(一)

一、SpringBoot启动的入口 1.当我们启动一个SpringBoot项目的时候&#xff0c;入口程序就是main方法&#xff0c;而在main方法中就执行了一个run方法。 SpringBootApplication public class StartApp {public static void main(String[] args) {// testSpringApplication.ru…

python excel接口自动化测试框架!

今天采用Excel继续写一个接口自动化测试框架。 设计流程图 这张图是我的excel接口测试框架的一些设计思路。 首先读取excel文件&#xff0c;得到测试信息&#xff0c;然后通过封装的requests方法&#xff0c;用unittest进行测试。 其中&#xff0c;接口关联的参数通过正则进…

c++ 主函数里的return 0写不写的区别是什么?

在 C 中&#xff0c;main 函数是程序的入口点。main 函数的标准定义如下&#xff1a; int main() {// ... 代码 ... } 或者可以带参数&#xff1a; int main(int argc, char* argv[]) {// ... 代码 ... } main 函数的返回类型是 int&#xff0c;这意味着它应该返回一个整数…

缓存方案分享

不知道大家平常更新缓存是怎么做的&#xff0c;但是大部分时候都是更新数据的同时更新缓存&#xff0c;今天和同事一起聊到一个缓存方案的问题&#xff0c;感觉很有趣、非常精妙&#xff0c;记录一下。 基于此本文将介绍几种常见的缓存更新策略&#xff0c;包括简单的缓存覆盖…

C/C++基础知识复习(31)

1) 什么是 C 中的多继承&#xff1f;它有哪些优缺点&#xff1f; 多继承&#xff08;Multiple Inheritance&#xff09;是指在 C 中&#xff0c;一个类可以继承自多个基类&#xff0c;从而拥有多个基类的特性和行为。具体来说&#xff0c;子类可以通过继承多个父类&#xff0c…

海康VsionMaster学习笔记(学习工具+思路)

一、前言 VisionMaster算法平台集成机器视觉多种算法组件&#xff0c;适用多种应用场景&#xff0c;可快速组合算法&#xff0c;实现对工件或被测物的查找测量与缺陷检测等。VM算法平台依托海康威视在图像领域多年的技术积淀&#xff0c;自带强大的视觉分析工具库&#xff0c;可…