日志模块设计思路

日志模块设计思路

日志系统是一个项目不可或缺的东西,其存在的意义就是可以为我们输出一些关键信息,因为我们作为一个开发工程师,在项目还没有上线的时候我们可以使用本地调试工具来调试程序,也可以在调试工具或者控制台上输出一些关键信息来定位BUG,但是一旦我们开发的程序投入使用,那么我定位BUG和快速分析和修复线上系统出现的问题,唯一能靠的就是日志了。

设计思路

一个日志类必备的东西:

1. 存放日志输出的路径(或指向这个打开文件的文件指针)
2. 一个判断路径所包含的文件是否打开成功
3. 日志文件的文件名
4. 静态的输出函数(用来把字符串输出到文件中)

一个文件打开失败可以有多种原因,比如文件被占用、文件的权限不够等等。在C++语言中,我们不可以在构造函数中抛出异常(见Effective C++),因此当文件打开失败的时候我们有必要使用这个标志来判断文件是否打开成功,在后续的写日志或其他操作前进行判断并处理

日志类锦上添花的东西:

  1. 设置不同的日志级别,如Ratel后端网络框架中我对日志简单的分了四个级别:调试、信息、警告、错误 级别是在不断的上升
  2. 利用宏定义简化输出(不理解的话,会在之后的代码中体现出来)
  3. 利用单例模式保证全局只有一个日志存在,方便输出
  4. 设计日志锁,写日志的时候加锁

日志的设计大概可以分成两种设计思想:多线程+锁机制 和 单线程+线程池异步排队。

日志在输出的时候应该尽量设计的详细一些,例如包含线程号、文件名、行号和打印时间等相关信息,这样更能有利于定位和解决问题。

现在大概的思路已经有了,其他的细节一看源码便知,接下来细说一下输出函数

我认为日志系统的输出函数最好设计成可变参数并且可以格式化字串因为对于日志来说这很有必要,否则在使用的时候不得不先进行字符串的格式化,然后再传入日志系统的输出函数中,这样设计非常的不友好,因此这些最好都交给日志系统自己来处理。

void CLog::output(Log_level level, char* fmt, ...){
	if(!isok_open) assert("日志文件打开失败");

	//获取可变参数开始
	va_list va;
	va_start(va,fmt);
	int strlength = vsnprintf((char* )nullptr, 0, fmt, va);  //用来计算需要的长度
	va_end(va);

	std::string stroutput;
	stroutput.resize(strlength + 1);	//加上末尾\0

	va_list vb;
	va_start(vb,fmt);
	vsnprintf((char*)stroutput.data(), stroutput.capacity(), fmt, vb); //把格式化后的放到变量中
	va_end(vb);
	//获取可变参数结束

	std::string strhead = makeHead(level); //根据传入日志的等级构造必要的日志头
	strhead += stroutput + '\n'; //日志头和日志内容相加

	fp.write(strhead.c_str(),strhead.size());
	fp.flush();
	
	return ;
}

文提到的日志的分类和宏定义设计

enum class Log_level{
	LOG_DEBUG,		 //调试输出
	LOG_INFO,		//信息输出
	LOG_WARNING,	//警告信息
	LOG_ERROR		//错误信息
};
//宏定义用来简化调用,使用起来更方便
#define LOG(Level,...) CLog::output(Level, __VA_ARGS__) //通用LOG输出,便于下面的宏定义使用

#define LOGD(...) LOG(Log_level::LOG_DEBUG, __VA_ARGS__)  //对应于调试输出打印
#define LOGI(...) LOG(Log_level::LOG_INFO, __VA_ARGS__)   //对应于信息输出打印
#define LOGW(...) LOG(Log_level::LOG_WARNING, __VA_ARGS__)//对应于警告信息打印
#define LOGE(...) LOG(Log_level::LOG_ERROR, __VA_ARGS__)  //对应于错误信息打印

日志系统算是比较核心的一个模块,应该尽量考虑的全面一些,这样才能为以后定位、调试线上出现的问题提供便利,不能说是一劳永逸,但能说为了以后节省了大量的时间和精力

公众号: 畅游码海 这里有更多高质量原创文章~
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
秒杀模块是一个高并发、高可用性的场景,需要考虑多方面的因素,以下是一个设计秒杀模块思路: 1. 预热:在秒杀活动开始之前,需要对系统进行预热,将商品信息、活动规则等数据加载到缓存中,以提高系统的响应速度。 2. 并发控制:为了避免系统崩溃或者性能下降,需要对请求进行并发控制。可以采用限流、队列、分布式锁等方式进行控制。 3. 库存控制:秒杀活动中库存是一个重要的考虑因素。需要对库存进行实时的更新和控制,避免超卖或者少卖的情况。 4. 订单处理:在秒杀成功后,需要生成订单,并对订单进行处理。可以采用异步处理的方式,将订单放入队列中进行处理,避免请求过多导致系统阻塞。 5. 缓存优化:为了提高系统的响应速度,可以采用缓存优化的方式,将热点数据缓存到内存或者分布式缓存中,避免每次请求都需要查询数据库的开销。 6. 数据库优化:为了避免数据库成为瓶颈,需要对数据库进行优化,包括索引优化、读写分离、分库分表等方式。 7. 安全防护:由于秒杀活动的高价值,需要考虑安全因素。可以采用验证码、IP黑名单、风控系统等方式进行安全防护。 8. 监控和调优:在秒杀活动中,需要对系统进行实时监控和调优,包括性能监控、日志监控、异常监控等方式,避免出现问题导致系统崩溃。 以上是设计一个秒杀模块的基本思路,具体实现需要根据具体的业务场景进行调整和完善。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

星光 不服赶路人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值