一、简介
为了自己使用写的一个简单日志库,使用仅需包含一个头文件,支持Windows和Linux平台,支持多线程控制台输出以及写日志文件。
二、调用方式
#include "hdlog.h"//设置日志级别hdlog::SetLevel(hdlog::LogLevel::Info);//为Info时,以下函数将不会在控制台输出hdlog::trace("this is a {} test.", "trace");hdlog::debug("this is a {} test.", "debug");
//以下函数会在控制台输出hdlog::info("this is a {} test.", "info");hdlog::warn("this is a {} test.", "warn");hdlog::error("this is a {} test.", "error");
//设置分隔符, 默认为"{}"hdlog::SetPattern("[]");hdlog::info("this is a [] test.", "pattern");//写日志文件hdlog::trace_to_file("log.txt", "this is a {} test.", "file");hdlog::debug_to_file("log.txt", "this is a {} test.", "file");hdlog::info_to_file("log.txt", "this is a {} test.", "file");hdlog::warn_to_file("log.txt", "this is a {} test.", "file");hdlog::error_to_file("log.txt", "this is a {} test.", "file");
undefined
三、结果显示
四、hdlog.h
#ifndef HDLOG_H #define HDLOG_H #pragma once #ifdef _WIN32 #include#include #else //#include
#include
#include#include #include #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 #include #include #include #include #include <string> #include #include
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<:>string> split(std::string str, std::string pattern) { std::string::size_type pos; std::vector<:>string> result; str += pattern;//扩展字符串以方便操作 int size = str.size(); for (int 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 _WIN32 return _access(name, 0) != -1; #else int r = access(name, F_OK); return r == 0; #endif // linux return 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<:mutex> guard(io_mutex); level = Level; } inline void SetPattern(std::string pat) { std::lock_guard<:mutex> guard(io_mutex); pattern = pat; } inline void Clear() { std::lock_guard<:mutex> guard(io_mutex); file_mutex.clear(); } inline std::ostream& Red(std::ostream& s) { #ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED); #else s << BOLDRED; #endif return s; } inline std::ostream& Yellow(std::ostream& s) { #ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); #else s << BOLDYELLOW; #endif return s; } inline std::ostream& Blue(std::ostream& s) { #ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE); #else s << BOLDBLUE; #endif return s; } inline std::ostream& Green(std::ostream& s) { #ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN); #else s << BOLDGREEN; #endif return s; } inline std::ostream& White(std::ostream& s) { #ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); #else s << BOLDWHITE; #endif return s; } inline std::ostream& Reset(std::ostream& s) { #ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); #else s << RESET; #endif return s; } templateinline void readParas(std::vector<:>string>& content, T&& args) { std::stringstream ss; ss << args; std::string s = ss.str(); content.push_back(s); } inline void Log(std::vector<:>string>& content) { } template inline void Log(std::vector<:>string>& content, T&& first, Args&&... args) { readParas(content, std::forward (first)); Log(content, std::forward (args)...); } template inline void level_to_out(std::string content, LogLevel Level, Args... args) { try { std::lock_guard<:mutex> guard(io_mutex); if (level > Level) return; std::vector<:>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<:>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 inline void level_to_file(std::string filename, std::string content, LogLevel loglevel, Args... args) { try { std::lock_guard<:mutex> guard(file_mutex[filename]); if (level > loglevel) return; std::vector<:>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<:>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 inline void trace(std::string content, Args... args) { level_to_out(content, LogLevel::Trace, args...); } template inline void debug(std::string content, Args... args) { level_to_out(content, LogLevel::Debug, args...); } template inline void info(std::string content, Args... args) { level_to_out(content, LogLevel::Info, args...); } template inline void warn(std::string content, Args... args) { level_to_out(content, LogLevel::Warn, args...); } template inline void error(std::string content, Args... args) { level_to_out(content, LogLevel::Error, args...); } template inline void trace_to_file(std::string filename, std::string content, Args... args) { level_to_file(filename, content, LogLevel::Trace, args...); } template inline void debug_to_file(std::string filename, std::string content, Args... args) { level_to_file(filename, content, LogLevel::Debug, args...); } template inline void info_to_file(std::string filename, std::string content, Args... args) { level_to_file(filename, content, LogLevel::Info, args...); } template inline void warn_to_file(std::string filename, std::string content, Args... args) { level_to_file(filename, content, LogLevel::Warn, args...); } template inline void error_to_file(std::string filename, std::string content, Args... args) { level_to_file(filename, content, LogLevel::Error, args...); } } #endif
Original: https://www.cnblogs.com/Clark-Zhang/p/15699274.html
Author: 朔月の流光
Title: 一个轻量级的C++log日志库
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/710834/
转载文章受原作者版权保护。转载请注明原作者出处!