日志系统代码
发布日期:2022-07-08 02:55:55 浏览次数:27 分类:技术文章

本文共 15283 字,大约阅读时间需要 50 分钟。

日志器代码

log.h

#ifndef __SYLAR_LOG_H__#define __SYLAR_LOG_H__#include "singletojn.h"#include "util.h"#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SYLAR_LOG_LEVEL(logger, level) \ if (logger->getLevel() <= level) \ sylar::LogEventWrap( \ sylar::LogEvent::ptr(new sylar::LogEvent( \ logger, level, __FILE__, __LINE__, 0, sylar::GetThreadId(), \ sylar::GetFiberId(), time(0)))).getSS()#define SYLAR_LOG_DEBUG(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::DEBUG)#define SYLAR_LOG_INFO(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::INFO)#define SYLAR_LOG_WARN(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::WARN)#define SYLAR_LOG_ERROR(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::ERROR)#define SYLAR_LOG_FATAL(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::FATAL)#define SYLAR_LOG_FMT_LEVEL(logger, level, fmt, ...) \ if (logger->getLevel() <= level) \ sylar::LogEventWrap( \ sylar::LogEvent::ptr(new sylar::LogEvent( \ logger, level, __FILE__, __LINE__, 0, sylar::GetThreadId(), \ sylar::GetFiberId(), time(0)))) \ .getEvent() \ ->format(fmt, __VA_ARGS__)#define SYLAR_LOG_FMT_DEBUG(logger, fmt, ...) \ SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::DEBUG, fmt, __VA_ARGS__)#define SYLAR_LOG_FMT_INFO(logger, fmt, ...) \ SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::INFO, fmt, __VA_ARGS__)#define SYLAR_LOG_FMT_WARN(logger, fmt, ...) \ SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::WARN, fmt, __VA_ARGS__)#define SYLAR_LOG_FMT_ERROR(logger, fmt, ...) \ SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::ERROR, fmt, __VA_ARGS__)#define SYLAR_LOG_FMT_FATAL(logger, fmt, ...) \ SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::FATAL, fmt, __VA_ARGS__)namespace sylar{ class Logger;//日志级别class LogLevel{ public: enum Level { UNKNOW=0, DEBUG = 1, INFO = 2, WARN = 3, ERROR = 4, FATAL = 5, }; static const char *ToString(LogLevel::Level level);};//日志事件class LogEvent { public: typedef std::shared_ptr
ptr; LogEvent(std::shared_ptr
logger,LogLevel::Level level,const char *file, int32_t line, uint32_t elapse, uint32_t thread_id, uint32_t fiber_id, uint64_t time); const char *getFile() const { return m_file; } int32_t getLine() const { return m_line; } uint32_t getElapse() const { return m_elapse; } uint32_t getThreadId() const { return m_threadId; } uint32_t getFiberId() const { return m_fiberId; } uint64_t getTime() const { return m_time; } std::string getContent() const { return m_ss.str(); } std::stringstream &getSS() { return m_ss; } std::shared_ptr
getLogger()const{ return m_logger;} LogLevel::Level getLevel() const { return m_level; } void format(const char *fmt, ...); void format(const char *fmt,va_list al);private: const char *m_file = nullptr; //文件名 int32_t m_line = 0; // 行号 uint32_t m_elapse = 0; //程序启动开始到现在的毫秒数 uint32_t m_threadId = 0; //线程id uint32_t m_fiberId = 0; //协程 uint32_t m_time = 0; //时间戳 std::stringstream m_ss; std::shared_ptr
m_logger; LogLevel::Level m_level;};class LogEventWrap { //wrap作为临时对象,使用完后直接析构出发日志写入,由于日志本身的智能指针,如果声明再主函数里面,程序不结束就永远无法释放public: LogEventWrap(LogEvent::ptr e); ~LogEventWrap(); LogEvent::ptr getEvent()const{ return m_event;} std::stringstream &getSS();private: LogEvent::ptr m_event;};class LogFormatter{ public: typedef std::shared_ptr
ptr; LogFormatter(const std::string &pattern); std::string format(std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event); void init(); class FormatItem{ public: typedef std::shared_ptr
ptr; FormatItem(const std::string &fmt = ""){ } virtual ~FormatItem() { } virtual void format(std::ostream& os,std::shared_ptr
logger,LogLevel::Level level,LogEvent::ptr event)=0; };private: std::string m_pattern; std::vector
m_items;};//日志输出地class LogAppender{ public: typedef std::shared_ptr
ptr; virtual ~LogAppender(); virtual void log(std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event)=0; void setFormatter(LogFormatter::ptr val) { m_formatter = val; } LogFormatter::ptr getFormatter() const { return m_formatter; } LogLevel::Level getLevel() const { return m_level; } void setLevel(LogLevel::Level val){ m_level=val;}protected: LogLevel::Level m_level=LogLevel::DEBUG; LogFormatter::ptr m_formatter;};class StdoutLogAppender:public LogAppender{ public: typedef std::shared_ptr
ptr; void log(std::shared_ptr
logger,LogLevel::Level level, LogEvent::ptr event)override;};class FileLogAppender:public LogAppender{ public: typedef std::shared_ptr
ptr; FileLogAppender(const std::string &filename); ~FileLogAppender(){ } void log(std::shared_ptr
logger,LogLevel::Level level, LogEvent::ptr event)override; bool reopen();private: std::string m_filename; std::ofstream m_filestraeam;};//日志器class Logger:public std::enable_shared_from_this
{ //自己调用指针public: typedef std::shared_ptr
ptr; Logger(const std::string &name = "root"); void log(LogLevel::Level level, LogEvent::ptr event); void debug(LogEvent::ptr event); void info(LogEvent::ptr event); void warn(LogEvent::ptr event); void error(LogEvent::ptr event); void fatal(LogEvent::ptr event); void addAppender(LogAppender::ptr appender); void delAppender(LogAppender::ptr appender); LogLevel::Level getLevel() const { return m_level; }; void setLevel(LogLevel::Level val) { m_level = val; }; const std::string &getName() const{ return m_name;} private : std::string m_name; //日志名称 LogLevel::Level m_level; //日志级别 std::list
m_appenders; //Appender集合 LogFormatter::ptr m_formatter;};class LoggerManager { public: LoggerManager(); Logger::ptr getLogger(const std::string &name); void init();private: std::map
m_loggers; Logger::ptr m_root;};//集合分类信息输出typedef sylar::Singleton
LoggerMgr;}#endif

log.cc

#include "log.h"#include 
#include
#include
#include
#include
#include
#include
namespace sylar{ const char *LogLevel::ToString(LogLevel::Level level) { switch (level) { #define XX(name) \ case LogLevel::name: \ return #name; \ break; XX(DEBUG); XX(INFO); XX(WARN); XX(ERROR); XX(FATAL);#undef XX default: return "UNKNOW"; } return "UNKNOW";}LogEventWrap::LogEventWrap(LogEvent::ptr e):m_event(e) { }LogEventWrap::~LogEventWrap() { m_event->getLogger()->log(m_event->getLevel(), m_event);}std::stringstream &LogEventWrap::getSS() { return m_event->getSS(); }void LogEvent::format(const char *fmt, ...) { va_list al; va_start(al, fmt); format(fmt, al); va_end(al);}void LogEvent::format(const char *fmt, va_list al) { char *buf = nullptr; int len = vasprintf(&buf, fmt, al); if (len != -1) { m_ss << std::string(buf, len); free(buf); }}LogEvent::LogEvent(std::shared_ptr
logger, LogLevel::Level level, const char *file, int32_t line, uint32_t elapse, uint32_t thread_id, uint32_t fiber_id, uint64_t time) : m_file(file), m_line(line), m_elapse(elapse), m_threadId(thread_id), m_fiberId(fiber_id), m_time(time),m_logger(logger),m_level(level) { }class MessageFormatItem:public LogFormatter::FormatItem{ public: MessageFormatItem(const std::string &str = ""){ }; void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { os << event->getContent(); }};class LevelFormatItem : public LogFormatter::FormatItem{ public: LevelFormatItem(const std::string &str = ""){ }; void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { os << LogLevel::ToString(level); }};class ElapseFormatItem : public LogFormatter::FormatItem{ public: ElapseFormatItem(const std::string &str = ""){ }; void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { os << event->getElapse(); }};class NameFormatItem : public LogFormatter::FormatItem{ public: NameFormatItem(const std::string &str = ""){ }; void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { os << logger->getName(); }};class ThreadIdFormatItem : public LogFormatter::FormatItem{ public: ThreadIdFormatItem(const std::string &str = ""){ }; void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { os << event->getThreadId(); }};class FiberIdFormatItem : public LogFormatter::FormatItem{ public: FiberIdFormatItem(const std::string &str = ""){ }; void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { os << event->getFiberId(); }};class DateTimeFormatItem : public LogFormatter::FormatItem{ public: DateTimeFormatItem(const std::string &format = "%Y:%m:%d %H:%M:%S"):m_format(format){ if(m_format.empty()){ m_format = "%Y-%m-%d %H:%M:%S"; } } void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { struct tm tm; time_t time = event->getTime(); localtime_r(&time, &tm); char buf[64]; strftime(buf, sizeof(buf), m_format.c_str(), &tm); os << buf; }private: std::string m_format;};class FilenameFormatItem : public LogFormatter::FormatItem{ public: FilenameFormatItem(const std::string &str = ""){ }; void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { os << event->getFile(); }};class LineFormatItem : public LogFormatter::FormatItem{ public: LineFormatItem(const std::string &str = ""){ }; void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { os << event->getLine(); }};class NewLineFormatItem : public LogFormatter::FormatItem{ public: NewLineFormatItem(const std::string &str = ""){ }; void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { os << std::endl; }};class StringFormatItem : public LogFormatter::FormatItem{ public: StringFormatItem(const std::string& str):FormatItem(str),m_string(str){ } void format(std::ostream& os,std::shared_ptr
logger,LogLevel::Level level,LogEvent::ptr event)override{ os << m_string; }private: std::string m_string;};class TabFormatItem : public LogFormatter::FormatItem{ public: TabFormatItem(const std::string &str = ""){ } void format(std::ostream &os, std::shared_ptr
logger, LogLevel::Level level, LogEvent::ptr event) override { os << "\t"; }};Logger::Logger(const std::string &name):m_name(name),m_level(LogLevel::DEBUG){ m_formatter.reset(new LogFormatter("%d{%Y-%m-%d %H:%M:%S}%T%t%T%F%T[%p]%T[%c]%T%f:%l%T%m%n"));}void Logger::addAppender(LogAppender::ptr appender){ if(!appender->getFormatter()){ appender->setFormatter(m_formatter); } m_appenders.push_back(appender);}void Logger::delAppender(LogAppender::ptr appender){ for (auto it = m_appenders.begin(); it != m_appenders.end();++it) { if(*it ==appender) m_appenders.erase(it); break; }}void Logger::log(LogLevel::Level level, LogEvent::ptr event){ if(level>=m_level){ auto self = shared_from_this(); for (auto &i : m_appenders) { i->log(self,level,event); } }}void Logger::debug(LogEvent::ptr event){ log(LogLevel::DEBUG,event);}void Logger::info(LogEvent::ptr event){ log(LogLevel::INFO,event);}void Logger::warn(LogEvent::ptr event){ log(LogLevel::WARN,event);}void Logger::error(LogEvent::ptr event){ log(LogLevel::ERROR,event);}void Logger::fatal(LogEvent::ptr event){ log(LogLevel::FATAL,event);}LogAppender::~LogAppender(){ }FileLogAppender::FileLogAppender(const std::string &filename) : m_filename(filename) { reopen();}void FileLogAppender::log(std::shared_ptr
logger,LogLevel::Level level, LogEvent::ptr event){ if(level>=m_level) { m_filestraeam << m_formatter->format(logger,level,event);}}bool FileLogAppender::reopen(){ if(m_filestraeam){ m_filestraeam.close(); } m_filestraeam.open(m_filename,std::ios::app); return !!m_filestraeam;}void StdoutLogAppender::log(std::shared_ptr
logger,LogLevel::Level level, LogEvent::ptr event){ if(level>=m_level){ std::string str = m_formatter->format(logger, level, event); std::cout << str << "****" << std::endl; }}LogFormatter::LogFormatter(const std::string &pattern):m_pattern(pattern){ init();}std::string LogFormatter::format(std::shared_ptr
logger,LogLevel::Level level,LogEvent::ptr event){ std::stringstream ss; for(auto& i:m_items){ i->format(ss,logger,level,event); } return ss.str(); }void LogFormatter::init(){ //字符串解析部分,分成三块 1内容 2参数 3是否是命令 std::vector
>vec;// 存放处理结果的串,第一个是命令,第二个是参数,根据第三个判断是否字符串 std::string nstr; for (size_t i = 0; i < m_pattern.size(); i++) { if(m_pattern[i]!='%'){ //不是%直接添加到结果字符串 nstr.append(1,m_pattern[i]); continue; } if((i+1)
>", fmt, 0)); } } if(!nstr.empty()){ vec.push_back(std::make_tuple(nstr, "", 0)); } static std::map
> s_format_items = { #define XX(str, C) \ { #str, [](const std::string &fmt) { return FormatItem::ptr(new C(fmt));}} XX(m, MessageFormatItem), XX(p, LevelFormatItem), XX(r, ElapseFormatItem), XX(c, NameFormatItem), XX(t, ThreadIdFormatItem), XX(n, NewLineFormatItem), XX(d, DateTimeFormatItem), XX(f, FilenameFormatItem), XX(l, LineFormatItem), XX(T, TabFormatItem), XX(F, FiberIdFormatItem)#undef XX }; for(auto& i:vec){ if(std::get<2>(i)==0){ m_items.push_back(FormatItem::ptr(new StringFormatItem(std::get<0>(i)))); }else{ auto it = s_format_items.find(std::get<0>(i)); if(it==s_format_items.end()){ m_items.push_back(FormatItem::ptr(new StringFormatItem("<
(i) + ">>"))); }else{ m_items.push_back(it->second(std::get<1>(i))); } } std::cout << "(" << std::get<0>(i) << ") - (" << std::get<1>(i) << ") - (" << std::get<2>(i) << ")" << std::endl; }}LoggerManager::LoggerManager(){ m_root.reset(new Logger); m_root->addAppender(LogAppender::ptr(new StdoutLogAppender));}Logger::ptr LoggerManager::getLogger(const std::string &name) { auto it = m_loggers.find(name); return it == m_loggers.end() ? m_root: it->second;}}

util.h

#ifndef __SYLAR_UTIL_H__#define __SYLAR_UTIL_H__#include 
#include
#include
#include
#include
#include
namespace sylar { pid_t GetThreadId();uint32_t GetFiberId();}#endif

util.cc

#include "util.h"#include 
namespace sylar {
pid_t GetThreadId() {
return syscall(SYS_gettid); }uint32_t GetFiberId(){
return 0;}}

singleton.h

#ifndef __SYLAR_SINGLETON_H__#define __SYLAR_SINGLETON_H__#include 
namespace sylar {
template
class Singleton {
public: static T *GetInstance() {
static T v; return &v; }};template
class SingletonPtr {
public: static std::shared_ptr
GetInstance() {
static std::shared_ptr
v(new T); return v; }};}#endif

test.cc

#include "util.h"#include 
namespace sylar {
pid_t GetThreadId() {
return syscall(SYS_gettid); }uint32_t GetFiberId(){
return 0;}}
cmake_minimum_required(VERSION 2.8)project(sylar)set(CMAKE_VERBOSE_MAKEFILE ON)set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -rdynamic -O0 -g -std=c++11 -Wall -Wno-deprecated -Werror -Wno-unused-function")set(LIB_SRC    sylar/log.cc    sylar/util.cc    )add_library(sylar SHARED ${LIB_SRC})#add_library(sylar_static STATIC ${LIB_SRC})#SET_TARGET_PROPERTIES(sylar_static PROPERTIES OUTPUT_NAME "sylar")add_executable(test tests/test.cc)add_dependencies(test sylar)target_link_libraries(test sylar)SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

转载地址:https://blog.csdn.net/m0_55292629/article/details/125262528 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:日志统计【省赛】
下一篇:日志种类、日志命令、日志关键字

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月25日 12时45分24秒