1.1Linux高性能服务器日志系统框架

作者寄语:用心写好每一篇文章,一起进步


前言

🔙返回目录(建议收藏)Linux C++高性能服务器


项目目录

建议收藏:Linux C++高性能服务器Sylar跟写


0.为什么服务器需要日志系统

出现问题:

不一致性:对文件系统进行修改时,这些操作可能中途被打断,也就是说,这些操作不是“不可中断”的。如果操作被打断,就可能造成文件系统出现不一致的状态。

解决问题:

解决不一致定:为了避免这样的错误,日志文件系统分配了一个称为日志的区域来提前记录要对文件系统做的更改。在崩溃后,只要读取日志重新执行未完成的操作,文件系统就可以恢复一致。

1.日志系统怎样设计?

  1. 表达日志LogEvent类至少应该包含两个属性,一个是时间戳,另一个是消息本身;
  2. 日志级别LogLevel类定义了日志的级别;
  3. 日志输出: LogAppender类可以输出到不同的地方,控制台、文件等,通过继承实现;
  4. 日志信息格式化LogFormatter可以引用 LogFormatter 这样就可以将 LogEvent 事件中的日志消息经过 LogFormatter 进行格式化,然后再由 LogAppender 输出;
  5. 获取日志Logger日志器。
    类图:(项目整体类图)

在这里插入图片描述


2.命名空间angel

为什么用命名空间就是为了方式命名冲突了

namespace angel
{
	//上述类都定义在这个命名空间内
}

3.LogEvent类

//日志事件类,表达日志信息的概念
class LogEvent
{
public:
	typedef std::shared_ptr<LogEvent> ptr;
	LogEvent();                        //构造函数
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;       	   //携程id
	uint64_t m_time = 0;		       //时间戳
	std::string m_content;  
};

LogEvent类难点

  1. std::shared_ptr:一种智能指针(smart pointer),作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。这便是所谓的引用计数(reference counting),一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除。
  2. 包含两个属性,一个是时间戳,另一个是消息本身

4.LogLevel类

//日志级别类
class LogLevel
{
public:
	enum Level
	{
		UNKNOW = 0,				//未知级别
		DEBUG = 1;				//DEBUG级别
		INFO =2;				//INFO级别
		WARN =3;				//WARN级别
		ERROR = 4;				//ERROR级别
		FATAL = 5;				//FATAL级别
	};
};

5.LogFormatter类

//日志格式器
class LogFormatter
{
public:
	typedef std::shared_ptr<LogFormatter> ptr;		//智能指针
	std::string format(LogEvent::ptr event);		//格式化写入日志内容
	
private:
};

6.LogAppender类及子类

基类:

//日志输出地类
class LogAppender
{
public:
	typedef std::shared_ptr<LogAppender> ptr;			//智能指针
	virtual ~LogAppender(){}							//析构
	/**
     * @brief 写入日志
     * @param[in] logger 日志器
     * @param[in] level 日志级别
     * @param[in] event 日志事件
     */
	virtual void log(LogEvent::Level level,LogEvent::ptr event) = 0;
	
protected:
	LogLevel::Level level;
};

子类

//日志输出到控制台
class StdoutLogAppender: public LogAppender
{
public:
	
}

//日志输出到文件
classs FileLogAppender: public LogAppender
{

} 

7.Logger类

//日志器
class Logger
{
public:
	std::shared_ptr<Logger> ptr;							//智能指针
	Logger(const std::string name = 'root');
	void log(LogLevel::Level level,LogEvent::ptr event);	//@brief 写日志
	
	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);			//@brief 添加日志目标
	void delAppender(LogAppender::ptr appender);			//@brief 删除日志目标
    void clearAppenders();									//@brief 清空日志目标
	LogLevel::Level getLevel() const {return m_level;}		//@brief 获取日志等级
	void setLevel(LogLevel::level val){m_level = val;}		//@brief 设置日志等级
private:
	std::string name;			//日志名称
	LogLevel::Level m_level;	//日志级别
	std::list<LogAppender::ptr> m_appenders;		//Appender集合
};

*第一天跟写记录

心得体会

第一次接触服务器,100%是有一点难度的,比如说Sylar中一些C++语言没看懂,比如说智能指针,stringsream库,还有被VScode惯坏的我用Vim的时候有点困难。希望自己能坚持写下去,当然也希望从中获得很多,“千里之行始于足下”,加油吧!

源码

#ifndef __ANGEL_LOG_H__
#define __ANGEL_LOG_H__

#include <string>
#include <stdint.h>
#include <memory>
#include <list>
#include <stringstream>
#include <fstream>

namespace angel
{

//日志事件类
class LogEvent
{
public:
	typedef std::shared_ptr<LogEvent> ptr;
	LogEvent();
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;       	    //携程id
	uint64_t m_time = 0;		    //时间戳
	std::string m_content;  
};

//日志级别类
class LogLevel
{
public:
	enum Level
	{
		DEBUG = 1;
		INFO =2;
		WARN =3;
		ERROR = 4;
		FATAL = 5;
	};
};

//日志格式器
class LogFormatter
{
public:
	typedef std::shared_ptr<LogFormatter> ptr;
	std::string format(LogEvent::ptr event);
	
private:
};

//日志输出地类
class LogAppender
{
public:
	typedef std::shared_ptr<LogAppender> ptr;
	virtual ~LogAppender(){}
	
	virtual void log(LogEvent::Level level,LogEvent::ptr event) = 0;
	
protected:
	LogLevel::Level level;
	
};
//日志器
class Logger
{
public:
	std::shared_ptr<Logger> 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;}
private:
	std::string name;		//日志名称
	LogLevel::Level m_level;	//日志级别
	std::list<LogAppender::ptr> m_appenders;		//Appender集合
};

//日志输出到控制台
class StdoutLogAppender: public LogAppender
{
public:
	
}

//日志输出到文件
classs FileLogAppender: public LogAppender
{

} 
	
}
#endif

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫荆鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值