【7】基于多设计模式下的同步&异步日志系统-代码设计

2023-12-15 23:34:50

8.5 日志落地(LogSink)类设计(简单工厂模式)

1.?志落地类主要负责落地?志消息到?的地。
它主要包括以下内容:
? Formatter?志格式化器:主要是负责格式化?志消息,
? mutex互斥锁:保证多线程?志落地过程中的线程安全,避免出现交叉输出的情况。
这个类?持可扩展,其成员函数log设置为纯虚函数,当我们需要增加?个log输出?标, 可以增加?个类继承?该类并重写log?法实现具体的落地?志逻辑。
2.?前实现了三个不同?向上的?志落地:
? 标准输出:StdoutSink
? 固定?件:FileSink
? 滚动?件:RollSink
2.1滚动?志?件输出的必要性:

? 由于机器磁盘空间有限, 我们不可能?直?限地向?个?件中增加数据
? 如果?个?志?件体积太?,???是不好打开,另???是即时打开了由于包含数据巨?,也不利于查找我们需要的信息
? 所以实际开发中会对单个?志?件的??也会做?些控制,即当??超过某个??时(如1GB),我们就重新创建?个新的?志?件来滚动写?志。 对于那些过期的?志, ?部分企业内部都有专?的运维?员去定时清理过期的?志,或者设置系统定时任务,定时清理过期?志。

2.2?志?件的滚动思想:

?志?件滚动的条件有两个:?件?? 和 时间。我们可以选择:
? ?志?件在?于 1GB 的时候会更换新的?件
? 每天定点滚动?个?志?件

本项?基于?件??的判断滚动?成新的?件

#ifndef __M_SINK_H__
#define __M_SINK_H__
#include "util.hpp"
#include "message.hpp"
#include "formatter.hpp"
#include <memory>
#include <mutex>
namespace bitlog{
class LogSink {
 public:
 using ptr = std::shared_ptr<LogSink>;
 LogSink() {}
 virtual ~LogSink() {}
 virtual void log(const char *data, size_t len) = 0;
};
class StdoutSink : public LogSink {
 public:
 using ptr = std::shared_ptr<StdoutSink>;
 StdoutSink() = default;
 void log(const char *data, size_t len) {
 std::cout.write(data, len);
 }
};
class FileSink : public LogSink {
 public:
 using ptr = std::shared_ptr<FileSink>;
 FileSink(const std::string &filename):_filename(filename) {
 util::file::create_directory(util::file::path(filename));
 _ofs.open(_filename, std::ios::binary | std::ios::app);
 assert(_ofs.is_open());
 }
 const std::string &file() {return _filename; }
 void log(const char *data, size_t len) {
 _ofs.write((const char*)data, len);
 if (_ofs.good() == false) {
 std::cout << "?志输出?件失败!\n";
 }
 }
 private:
 std::string _filename;
 std::ofstream _ofs;
};
class RollSink : public LogSink {
 public:
 using ptr = std::shared_ptr<RollSink>;
 RollSink(const std::string &basename, size_t max_fsize):
 _basename(basename), _max_fsize(max_fsize), _cur_fsize(0){
 util::file::create_directory(util::file::path(basename));
 }
 void log(const char *data, size_t len) {
 initLogFile();
 _ofs.write(data, len);
 if (_ofs.good() == false) {
 std::cout << "?志输出?件失败!\n";
 }
 _cur_fsize += len;
 }
 private:
 void initLogFile() {
 if (_ofs.is_open() == false || _cur_fsize >= _max_fsize) {
 _ofs.close();
 std::string name = createFilename();
 _ofs.open(name, std::ios::binary | std::ios::app);
 assert(_ofs.is_open());
 _cur_fsize = 0;
 return;
 }
 return;
 } 
 std::string createFilename() {
 time_t t = time(NULL);
 struct tm lt;
 localtime_r(&t, &lt);
 std::stringstream ss;
 ss << _basename;
 ss << lt.tm_year + 1900;
 ss << lt.tm_mon + 1;
 ss << lt.tm_mday;
 ss << lt.tm_hour;
 ss << lt.tm_min;
 ss << lt.tm_sec;
 ss << ".log";
 return ss.str();
 }
 private:
 std::string _basename;
 std::ofstream _ofs;
 size_t _max_fsize;
 size_t _cur_fsize;
};
class SinkFactory {
 public:
 template<typename SinkType, typename ...Args>
 static LogSink::ptr create(Args &&...args) {
 return std::make_shared<SinkType>(std::forward<Args>(args)...);
 }
};
}
#endif

文章来源:https://blog.csdn.net/zzxz8/article/details/135026645
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。