我是靠谱客的博主 鳗鱼钢笔,这篇文章主要介绍【sylar服务器框架】完善日志系统,现在分享给大家,希望可以做个参考。

添加TabFormatItem类 用来输出tab,并在 s_format_items 中添加对应的映射关系%T
再添加FiberIdFormatItem类用来输出纤程ID,并添加上对应的映射关系%F

新建util.h 与util.cpp
添加函数 pid_t getThreadId(),利用systemcall(SYS_gettid)返回线程号
添加工具方法 uint32_t getFiberId() 暂且只让它返回0

编辑CMakeList,将新增的文件添加进去

修改LogEvent

添加shared_ptr<Logger> m_loggerLogEvent m_level字段,以及相应的get方法。并在构造函数中加入这两个字段。

添加LogEventWrap类(为了不直接使用智能指针LogEvent::ptr)
复制代码
1
2
3
4
5
6
7
8
9
class LogEventWrap { public : LogEventWrap(LogEvent::ptr e); //传入一个LogEvent给m_event赋值 ~LogEventWrap(); std::stringstream& getSS(); //返回logevnet的getSS() private: LogEvent::ptr m_event; }
编写~LogEventWrap()

获取m_event本身的m_logger,用m_event的级别m_level和自身作为参数,调用该事件所属的Logger的log()方法

添加void format( const char* fmt , .... )

装载变长参数va_start( va_list, 变长形参的首个固定参数 )、释放变长参数va_end()

添加 void format( const char* fmt , va_list al )

主要服务于上一个format() ,va_list al 接收了变长参数,交给vasprintf(char指针地址char** buf,格式字符串,va_list) 将格式化后的字符串写入buf字符串中,最后将其写入到 getSS() <<

定义宏使得日志模块更加易用

1、
先定义一个基础宏 LOG_LEVEL(logger,level)
只要当前等级>=logger中的日志等级,就创建一个新的LogEvent并用它来初始化一个LogEventWrap,并调用getSS()来返回其内容流。

用这个基础宏来定义等级分别为 LOG_debug LOG_warn … 的其它宏,使得:
输入:logger对象
输出:所创建事件的内容流(&stringstream)

使用方式:LOG_XXX(logger) << "日志内容"

2、
logEvent中新增的两个format方法主要是为了让我们能用格式字符串的方式来输入日志信息:即允许在日志内容中出现%x来进行格式化输出
同样,先定义一个基础宏:
LOG_FMT_LEVEL(logger , level , fmt , ... )
只要当前输入等级>=logger中的内置级别,就创建一个新的LogEvent,并用它来初始化一个LogEventWrap,并用新增的format()设置其中的LogEvent的内容getSS()
这个宏的主要难点是如何表示变长参数列表,这需要借助一个宏__VA_AR GS__来表示...

再用这个基础宏去定义当前格式化输出的日志级别分别是 debug 、info … 的宏LOG_FMT_XXXX(logger, “日志内容 %A %B ”,“aaa”,“bbb”)

修改LogAppender

增加 setLevel()getLevel() 方法

创建日志管理器(为了简化logger的使用)

新增类 LogMannger
数据:
map<string名称,Logger::ptr> m_logger,用来存放所有logger
m_root 默认使用的logger
方法:
init() 之后会和配置文件联合使用,加载配置产生logger

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
class LoggerManager(){ public: LoggerManager(); //设置缺省logger:m_root中包含仅一个输出地:stdLogAppender Logger::ptr getLogger(const std::string& name); 调用find按名字找对应的logger,没找到则返回默认的日志器m_root void init();//之后会从配置文件中直接加载我们要使用的logger private: Logger::ptr m_root; map<std::string,Logger::ptr> m_loggers; }
新建Singleton.h

在其中加入两个模板类

单例类:

复制代码
1
2
3
4
5
6
7
8
9
template<class T , class X = void ,int N = 0> //N用来区分同类型的多个不同实例 class Singleton{ public : static T* getInstance(){ static T v; return &v; } }

单例指针:

复制代码
1
2
3
4
5
6
7
8
9
template<class T , class X = void ,int N = 0> class SingletonPtr{ public : static std::shared_ptr<T> getInstance(){ static std::shared_ptr<T> v(new T); return v; } }
应用单例类来创建唯一一个 LogManager

定义新类型 LoggerMgr
typedef sylar::Singleton<LoggerManager> LoggerMgr

使用方式:

复制代码
1
2
3
auto my_logger = sylar::LoggerMgr::getInstance()->getLogger("logger名称")LOG_INFO(my_logger) << "日志内容"

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
注: class{}后面要记得加分号!! 命名空间::要加上!! std::shared_ptr<XX>.reset() 这里要用`.`!! shared_ptr<XX>.reset(new XX ) 调用原来所指向对象的析构函数(即释放掉旧对象),并将指针指向新对象new XX map.find() 后返回的是KV对,因此类型一般用auto 取出KV对中的“V”用 `->second()` static 表示该变量仅此一份,不会随作用域的退出而销毁。 vim :vs XX 垂直分屏 打开文件

最后

以上就是鳗鱼钢笔最近收集整理的关于【sylar服务器框架】完善日志系统的全部内容,更多相关【sylar服务器框架】完善日志系统内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部