【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, <);
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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!