sylar日志模块

文件:log.h         log.cpp

讲师:sylar;b站视频:https://www.bilibili.com/video/BV184411s7qF?from=search&seid=11872876667245634701&spm_id_from=333.337.0.0

流程:

LogEventWrap可以得到LogEvent的内容流,直接输入内容。LogEventWrap在析构的时候,对日志时间进行了处理。

LogEventWrap内容输入->LogEventWrap::m_event->LogEvent::m_logger->Logger::log()->LogAppender::log()->LogAppender::m_formatter->LogFormatter::m_items->输出

类:

注:只列出其中主要函数

Logger:日志器

class Logger{
public:
    Logger(const std::string& name);
    //日志事件处理函数
    void log(LogLevel::Level level,LogEvent::ptr event);
private:
    std::string m_name;                         //日志名称
    LogLevel::Level m_level;                    //日志级别
    std::list<LogAppender::ptr> m_appenders;    //日志输出地
};

LogLevel:日志级别

class LogLevel{
public:
    enum Level{
        UNKNOW=0,
        DEBUG,
        INFO,
        WARN,
        ERROR,
        FATAL
    };
};

LogAppender:日志输出地(基类)

class LogAppender{
public:
    //基类
    virtual ~LogAppender();
    //日志时间处理函数
    virtual void log(std::shared_ptr<Logger> logger,
                        LogLevel::Level level,LogEvent::ptr event);
private:
    LogLevel::Level m_level;        //日志级别
    LogFormatter::ptr m_formatter;  //日志格式
};

StdLogAppender:标准输出地(继承m_level,m_formatter)

class StdLogAppender:public LogAppender{
public:
    //重载基类虚函数
    void log(std::shared_ptr<Logger> logger,
		LogLevel::Level level,LogEvent::ptr event)override;
};

FileLogAppender:文件输出地(继承m_level,m_formatter)

class FileLogAppender:public LogAppender{
public:
    FileLogAppender(const std::string& filename);
    //日志时间处理函数
	void log(std::shared_ptr<Logger> logger,
		LogLevel::Level level,LogEvent::ptr event)override;
	//文件重打开
    bool reopen();         
private:
	std::string m_filename;        //文件名
	std::ofstream m_filestream;    //文件流
	uint64_t m_time=0;             //重打开时间
};

LogFormatter:日志格式

class LogFormatter{
public:
    //默认日志格式    T(Tab键)
    //时间-T-线程id-T-线程名-T-协程id-T-日志级别-T-日志名称-T-文件名-:-行号-T-消息内容-换行
    LogFormatter(const std::string& pattern=
                "%d%T%t%T%N%T%F%T%p%T%c%T%f:%l%T%m%n);
    //嵌套类(基类)
    class FormatItem{
        virtual ~FormatItem();
        //对应消息处理(纯虚函数)
        virtual void format(std::ostream& os
                        ,std::shared_ptr<Logger> logger
                        ,LogLevel::Level
                        ,LogEvent::ptr event)=0;
    };
    void format(std::ostream& os
                    ,std::shared_ptr<Logger>
                    ,LogLevel::Level level
                    ,LogEvent::ptr event);
    //对格式的初始化
    void init();
private:
    std::string m_pattern;                 //格式
    std::list<FormatItem::ptr> m_items;    //每一个item对应格式中的一项
};

LogEvent:日志事件

class LogEvent{
public:
    LogEvent(std::shared_ptr<Logger> logger,LogLevel::Level level,const char* file,
			int32_t line,uint32_t elapse,uint32_t threadId,
			uint32_t fiberId,uint64_t cur_time,const std::string& threadName);
	//多参数输入内容
    void format(const char* fmt,...);
	void format(const char* fmt,va_list al);
private:
	std::shared_ptr<Logger> m_logger;    //日志器
	LogLevel::Level m_level;             //日志级别
	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;                //协程id
	uint64_t m_time=0;                   //时间
	std::stringstream m_ss;              //流
	std::string m_threadName;            //线程名
};

LogEventWrap:日志时间包装

class LogEventWrap{
public:
    LogEventWrap(LogEvent::ptr event);
    //重要:在析构中做了重要的事情
    ~LogEventWrap();    
    //返回日志时间的内容
	std::stringstream& getSS(){ return m_event->getSS();}
private:
	LogEvent::ptr m_event;    //日志时间
};

FormatItem子类:(只列出两个)

class LevelFormatItem: public LogFormatter::FormatItem{
public:
     //os文件流或标准输出流
	 void format(std::ostream& os,
		 	std::shared_ptr<Logger> logger,LogLevel::Level level,
				LogEvent::ptr event){
		 os<<LogLevel::ToString(level);
	 }
};
class MessageFormatItem: public LogFormatter::FormatItem{
public:
	 void format(std::ostream& os,
		 	std::shared_ptr<Logger> logger,LogLevel::Level level,
				LogEvent::ptr event){
		 os<<event->getContent();
	 }
};

LogManager:日志管理类

class LogManager{
public:
    //自动初始化一个root日志器
    LogManager();
    void init();
private:
    //日志器集合
    std::unordered_map<std::string,Logger::ptr> m_loggers;
    Logger::ptr m_root;
};

日志系统难点:

1.时间格式:

#include<time.h>

const char* getTimeFormat(){
    //时间格式(区分大小写) 年-月-日 时-分-秒
    const std::string timeFormat="%Y-%m-%d %H:%M:%s";
    time_t cur=time(0);    //当前时间
    struct tm t;           //存储cur分解出的年月日等
    localtime_r(&cur,&t);  //将cur分解
    char buf[64];
    //按照格式生成字符串
    strftime(buf,sizeof(buf),timeFormat.c_str(),&t); 
    return buf;
}

2.函数传可变参数(本人不太会,待更新)

va_start获取第一个可变参数的地址

va_arg得到下一个参数

va_end

3.输出地

标准输出:std::cout    

文件输出:

//标准输出也属于ostream类
std::ostream& fileStream;
char* fileName="system_log.txt";
fileStream.open(fileName);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值