2024-05-27 服务器开发-轻量级c++日志-实现

摘要:

2024-05-27 服务器开发-轻量级c++日志-实现

logger.h

#ifndef HDLOG_H
#define HDLOG_H#pragma once#ifdef _WIN32
#include <windows.h>
#include <io.h>
#else
//#include <chrono>#include <sys/time.h>#include <memory>
#include <stdarg.h>
#include <unistd.h>#define RESET "\033[0m"
#define BLACK "\033[30m" /* Black */
#define RED "\033[31m" /* Red */
#define GREEN "\033[32m" /* Green */
#define YELLOW "\033[33m" /* Yellow */
#define BLUE "\033[34m" /* Blue */
#define MAGENTA "\033[35m" /* Magenta */
#define CYAN "\033[36m" /* Cyan */
#define WHITE "\033[37m" /* White */
#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */
#define BOLDRED "\033[1m\033[31m" /* Bold Red */
#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */
#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
#define BOLDWHITE "\033[1m\033[37m" /* Bold White */
#endif#include <time.h>
#include <iostream>
#include <fstream>
#include <mutex>
#include <vector>
#include <string>
#include <sstream>
#include <map>
#include <exception>namespace hdlog
{enum class LogLevel{Trace,Debug,Info,Warn,Error};static std::mutex io_mutex;static std::map<std::string, std::mutex> file_mutex;static LogLevel level = LogLevel::Info;static std::string pattern = "{}";static const std::string enumstring[] = { "Trace", "Debug", "Info", "Warn", "Error" };inline std::string GetSystemTime(){
#ifdef _WIN32time_t tNowTime;time(&tNowTime);//struct tm t;tm tLocalTime;localtime_s(&tLocalTime, &tNowTime);char szTime[30] = { '\0' };strftime(szTime, 30, "[%Y-%m-%d %H:%M:%S", &tLocalTime);std::string strTime = szTime;SYSTEMTIME t;GetLocalTime(&t);int ms = t.wMilliseconds;if (ms < 10){strTime += ".00" + std::to_string(t.wMilliseconds);}else if (ms < 100){strTime += ".0" + std::to_string(t.wMilliseconds);}else{strTime += "." + std::to_string(t.wMilliseconds);}strTime += "]";return strTime;
#else//std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());//auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());//std::time_t timestamp = tmp.count();//uint64_t milli = timestamp;//milli += (uint64_t)8 * 60 * 60 * 1000;//auto mTime = std::chrono::milliseconds(milli);//tp = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>(mTime);//auto tt = std::chrono::system_clock::to_time_t(tp);//std::tm* now = std::gmtime(&tt);//char rst[27] = { 0 };//sprintf(rst, "[%04d-%02d-%02d %02d:%02d:%02d.%03d]", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, std::atoi(std::to_string(timestamp % 1000000).substr(3, 3).c_str()));struct tm* now;     struct timeval time;gettimeofday(&time, NULL);		      now = localtime(&time.tv_sec);				      char rst[27] = { 0 };		      if (NULL != now) { sprintf(rst, "[%04d-%02d-%02d %02d:%02d:%02d.%03d]", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, time.tv_usec / 1000); }return rst;
#endif}inline std::vector<std::string> split(std::string str, std::string pattern){std::string::size_type pos;std::vector<std::string> result;str += pattern;//扩展字符串以方便操作size_t size = str.size();for (size_t i = 0; i < size; i++){pos = str.find(pattern, i);if (pos < size){std::string s = str.substr(i, pos - i);result.push_back(s);i = pos + pattern.size() - 1;}}return result;}inline bool Exist(const char* name){
#ifdef _WIN32return _access(name, 0) != -1;
#elseint r = access(name, F_OK);return r == 0;
#endif // linuxreturn true;}inline bool WriteToFile(std::string filename, std::string content){std::ofstream file(filename, std::ios::binary | std::ios::app);if (file.good()){file << content << "\n";file.close();return true;}else{return false;}}inline void SetLevel(LogLevel Level){std::lock_guard<std::mutex> guard(io_mutex);level = Level;}inline void SetPattern(std::string pat){std::lock_guard<std::mutex> guard(io_mutex);pattern = pat;}inline void Clear(){std::lock_guard<std::mutex> guard(io_mutex);file_mutex.clear();}inline std::ostream& Red(std::ostream& s){
#ifdef _WIN32SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
#elses << BOLDRED;
#endifreturn s;}inline std::ostream& Yellow(std::ostream& s){
#ifdef _WIN32SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
#elses << BOLDYELLOW;
#endifreturn s;}inline std::ostream& Blue(std::ostream& s){
#ifdef _WIN32SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);
#elses << BOLDBLUE;
#endifreturn s;}inline std::ostream& Green(std::ostream& s){
#ifdef _WIN32SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
#elses << BOLDGREEN;
#endifreturn s;}inline std::ostream& White(std::ostream& s){
#ifdef _WIN32SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
#elses << BOLDWHITE;
#endifreturn s;}inline std::ostream& Reset(std::ostream& s){
#ifdef _WIN32SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
#elses << RESET;
#endifreturn s;}template<typename T>inline void readParas(std::vector<std::string>& content, T&& args){std::stringstream ss;ss << args;std::string s = ss.str();content.push_back(s);}inline void Log(std::vector<std::string>& content){}template<typename T, typename... Args>inline void Log(std::vector<std::string>& content, T&& first, Args&&... args){readParas(content, std::forward<T>(first));Log(content, std::forward<Args>(args)...);}template<typename... Args>inline void level_to_out(std::string content, LogLevel Level, Args... args){try{std::lock_guard<std::mutex> guard(io_mutex);if (level > Level) return;std::vector<std::string> cs = split(content, pattern);int paramcount = 0;paramcount = sizeof...(args);int amount = cs.size();if (Level == LogLevel::Trace){std::cout << GetSystemTime().c_str() << " [" << White << enumstring[(int)Level] << Reset << "] ";}else if (Level == LogLevel::Debug){std::cout << GetSystemTime().c_str() << " [" << Blue << enumstring[(int)Level] << Reset << "] ";}else if (Level == LogLevel::Warn){std::cout << GetSystemTime().c_str() << " [" << Yellow << enumstring[(int)Level] << Reset << "] ";}else if (Level == LogLevel::Error){std::cout << GetSystemTime().c_str() << " [" << Red << enumstring[(int)Level] << Reset << "] ";}else{std::cout << GetSystemTime().c_str() << " [" << Green << enumstring[(int)Level] << Reset << "] ";}if (paramcount == 0 || amount == 1){std::cout << content << std::endl;}else{std::vector<std::string> paramlist;Log(paramlist, args...);if (amount - 1 < paramcount){for (int i = 0; i < amount - 1; ++i){std::cout << cs[i] << paramlist[i];}}else{for (int i = 0; i < paramcount; ++i){std::cout << cs[i] << paramlist[i];}for (int i = paramcount; i < amount - 1; ++i){std::cout << cs[i] << pattern;}}std::cout << cs[amount - 1] << std::endl;}}catch (std::exception& ex){std::cout << GetSystemTime().c_str() << " [" << Red << "Error" << Reset << "] " << ex.what() << std::endl;}}template<typename... Args>inline void level_to_file(std::string filename, std::string content, LogLevel loglevel, Args... args){try{std::lock_guard<std::mutex> guard(file_mutex[filename]);if (level > loglevel) return;std::vector<std::string> cs = split(content, pattern);std::string filedata = GetSystemTime() + " [" + enumstring[(int)loglevel] + "] ";int paramcount = 0;paramcount = sizeof...(args);int amount = cs.size();if (paramcount == 0 || amount == 1){filedata += content;}else{std::vector<std::string> paramlist;Log(paramlist, args...);if (amount - 1 < paramcount){for (int i = 0; i < amount - 1; ++i){filedata += cs[i] + paramlist[i];}}else{for (int i = 0; i < paramcount; ++i){filedata += cs[i] + paramlist[i];}for (int i = paramcount; i < amount - 1; ++i){filedata += cs[i] + pattern;}}filedata += cs[amount - 1];}if (!WriteToFile(filename, filedata)){std::cout << GetSystemTime().c_str() << " [" << Red << "Error" << Reset << "] " << "Write log file failed!" << std::endl;}}catch (std::exception& ex){std::cout << GetSystemTime().c_str() << " [" << Red << "Error" << Reset << "] " << ex.what() << std::endl;}}template<typename... Args>inline void trace(std::string content, Args... args){level_to_out(content, LogLevel::Trace, args...);}template<typename... Args>inline void debug(std::string content, Args... args){level_to_out(content, LogLevel::Debug, args...);}template<typename... Args>inline void info(std::string content, Args... args){level_to_out(content, LogLevel::Info, args...);}template<typename... Args>inline void warn(std::string content, Args... args){level_to_out(content, LogLevel::Warn, args...);}template<typename... Args>inline void error(std::string content, Args... args){level_to_out(content, LogLevel::Error, args...);}template<typename... Args>inline void trace_to_file(std::string filename, std::string content, Args... args){level_to_file(filename, content, LogLevel::Trace, args...);}template<typename... Args>inline void debug_to_file(std::string filename, std::string content, Args... args){level_to_file(filename, content, LogLevel::Debug, args...);}template<typename... Args>inline void info_to_file(std::string filename, std::string content, Args... args){level_to_file(filename, content, LogLevel::Info, args...);}template<typename... Args>inline void warn_to_file(std::string filename, std::string content, Args... args){level_to_file(filename, content, LogLevel::Warn, args...);}template<typename... Args>inline void error_to_file(std::string filename, std::string content, Args... args){level_to_file(filename, content, LogLevel::Error, args...);}template<typename ... Args>static std::string str_format(const std::string& format, Args ... args){auto size_buf = std::snprintf(nullptr, 0, format.c_str(), args ...) + 1;std::unique_ptr<char[]> buf(new(std::nothrow) char[size_buf]);if (!buf)return std::string("");std::snprintf(buf.get(), size_buf, format.c_str(), args ...);return std::string(buf.get(), buf.get() + size_buf - 1);}
}#endif

使用:

一. 设置日志级别:

hdlog::SetLevel(hdlog::LogLevel::Debug);

二. 输出日志:

hdlog::info(hdlog::str_format("ut_driver Initialize ok, ret: %u", ret));hdlog::error(hdlog::str_format("Initialize fail, ret: %u", ret));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/17141.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python中import的搜索路径

文章目录 前言 一 python中import的搜索路径1. python中import的搜索路径先判断是否内置模块根据sys.path查找1.1 脚本当前目录和所属项目目录1.2 环境变量1.3 标准库1.4 .pth 文件1.5 第三方库 2. 解决ModuleNotFoundError 前言 码python时经常会遇到找不到包或者找不到模块的…

【杂记-利用TCP协议传输数据始末详解】

一、三次握手前&#xff1a; 1、使用TCP协议的原因 TCP协议的目的是为了保证数据能在两端准确、连续的传输。 2、实现多设备传输的基础 TCP协议可使一个设备能同时与多个设备交互信息&#xff0c;它必须要保证不同传输通道之间不会产生串联或相互影响&#xff0c;所以TCP使用S…

OpenWrt 23.05 安装之后默认空间小 磁盘扩容 教程 软路由实测 系列六

1 安装fdisk opkg update opkg install fdisk #查看磁盘 rootOpenWrt:~# fdisk -l GPT PMBR size mismatch (246303 ! 250069679) will be corrected by write. The backup GPT table is not on the end of the device. Disk /dev/sda: 119.24 GiB, 128035676160 bytes, 25006…

SpringCloud配置文件bootstrap不生效问题解决

解决方案&#xff1a; 情况一、SpringBoot 版本 小于 2.4.0 版本&#xff0c;添加以下依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-context</artifactId> </dependency> 情况二、SpringBoot…

开源远程协助:分享屏幕,隔空协助!

&#x1f5a5;️ 星控远程协助系统 &#x1f5b1;️ 一个使用Java GUI技术实现的远程控制软件&#xff0c;你现在就可以远程查看和控制你的伙伴的桌面&#xff0c;接受星星的指引吧&#xff01; 支持系统&#xff1a;Windows / Mac / Linux &#x1f31f; 功能导览 &#x1f…

java-求质数问题

在 Java 中求质数是一个经典的问题&#xff0c;它可以很好地展示编程技巧和数学知识。质数是只有两个正因数&#xff1a;1 和它本身的数。例如&#xff0c;2、3、5、7、11、13 等都是质数。在计算机科学中&#xff0c;质数有着广泛的应用&#xff0c;比如在密码学、公共密钥加密…

521源码-免费源码下载-免费学习教程-常见的原生js封装ajax

更多 网站源码 学习教程 游戏源码&#xff0c;请点击&#x1f449;-521源码-&#x1f448;获取最新资源 请看以下案例&#xff1a; function ajax(options) {var xhr null;var type GET;var params formsParams(options.data);if(typeof options.type ! undefined){type o…

【Flutter】KeyAnimatedList组件

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;Flutter学习 &#x1f320; 首发时间&#xff1a;2024年5月28日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43e; 目…

10个最佳人物素材网站推荐,免费获取第一个PNG文件!

人物素材是设计中应用最广泛的元素之一。无论是网页设计还是移动终端设计&#xff0c;人物素材的插画设计都比文字信息更容易吸引用户的注意力。作为内容呈现&#xff0c;还可以增加设计的艺术属性。为了节省大家寻找人物素材的时间成本&#xff0c;本文立即为大家整理了10个宝…

Java 实验12 线程同步与通信

&#xff08;一&#xff09;实验目的 1、掌握JAVA中多线程的实现方法&#xff1b; 2、重点掌握多线程的同步与通信机制&#xff1b; 3、熟悉JAVA中有关多线程同步与通信的方法 &#xff1b; 4、能使用多线程机制解决实际应用中的线程同步与通信问题。 &#xff08;二&…

202305青少年软件编程(Python)等级考试试卷(四级)

第 1 题 【单选题】 有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头 小母牛。问第n 年的时候, 共有多少头母牛? 由递推法可推测, 当年数小于等于 4 的时候, 第几年就是有几头牛, 即 a[1]=1; a[2]=2; a[3]=3; a[4]=4。 当 n 大于 …

行为设计模式之职责链模式

文章目录 概述原理代码实现小结 概述 职责链模式(chain of responsibility pattern) 定义: 避免将一个请求的发送者与接收者耦合在一起,让多个对象都有机会处理请求.将接收请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止. 在职责链模式中&…

宝塔:如何在宝塔面板做301重定向

如何在宝塔面板做301重定向?301重定向对于网站来说非常重要。如果你的网站以www开头&#xff0c;我们应该把没有www的域名重定向到有www的域名&#xff0c;反之亦然。 1、我们进入宝塔管理后台 2、登录面板并单击添加站点。既然要把xxx.com 301发到www.xxx.com&#xff0c;我…

GB/T 18915.2-2013 低辐射镀膜玻璃检测

低辐射镀膜玻璃是指对红外线有较高反射比的镀膜玻璃&#xff0c;根据工艺的不同分为离线镀膜玻璃和在线镀膜玻璃。 GB/T 18915.2-2013低辐射镀膜玻璃测试项目&#xff1a; 测试项目 测试方法 尺寸 GB/T 18915.2 弯曲度 GB/T 18915.2 外观质量 GB/T 18915.2 光学性能 …

如何从 JavaScript 对象中移除属性?

在 JavaScript 中,移除对象中的属性是一项常见的操作。本文将详细介绍如何使用 delete 操作符以及其他相关方法。 使用 delete 操作符 delete 操作符用于从对象中移除属性。例如: const obj = {foo: "bar" };delete obj.foo; console.log(obj.hasOwnProperty(&q…

大模型微调系列 --关于`transformer`中的`pipeline`是什么

大模型微调系列 --关于transformer中的pipeline是什么 pipeline就是一个帮你做数据预处理以及一些模型加载&#xff0c;模型预测的步骤的工具&#xff0c;提供各种接口 定义数据预处理函数 对输入的文本进行预处理 转换为小写去除标点符号去除特殊字符 def preprocess_tex…

JS 中怎么删除数组元素?有哪几种方法?

正文开始之前推荐一位宝藏博主免费分享的学习教程,学起来! 编号学习链接1Cesium: 保姆级教程+源码示例2openlayers: 保姆级教程+源码示例3Leaflet: 保姆级教程+源码示例4MapboxGL: 保姆级教程+源码示例splice() JavaScript中的splice()方法是一个内置的数组对象函数, 用于…

05.配置tomcat管理功能

认证失败&#xff0c;需要配置tomcat-users.xml文件 配置用户信息 [rootweb01 /application/tomcat/conf\]# tail tomcat-users.xml <role rolename"admin-gui"/> <role rolename"host-gui"/><role rolename"mana…

Java中集合中对象的某一个属性转为set集合

在Java中&#xff0c;如果你想要将一个集合&#xff08;比如List<YourObject>&#xff09;中对象的某个属性&#xff08;假设为String类型&#xff09;提取出来并放入一个Set<String>集合中&#xff0c;以确保去重&#xff0c;你可以通过Java 8的Stream API来轻松地…

Codeforces Round 946 (Div. 3)

Codeforces Round 946 &#xff08;div3&#xff09; A. Phone Desktop题意&#xff1a;题解&#xff1a;代码&#xff1a; Symmetric Encoding题意&#xff1a;题解&#xff1a;代码&#xff1a; C. Beautiful Triple Pairs题意&#xff1a;题解&#xff1a;代码&#xff1a;…