网站建设的招聘要求,网站建设的分类,做软装有什么网站找图片,做网站用com还是cn好文章目录 专栏导读日志宏全局接口设计全局接口测试项目目录结构整理示例代码拓展示例代码 专栏导读 #x1f338;作者简介#xff1a;花想云 #xff0c;在读本科生一枚#xff0c;C/C领域新星创作者#xff0c;新星计划导师#xff0c;阿里云专家博主#xff0c;C… 文章目录 专栏导读日志宏全局接口设计全局接口测试项目目录结构整理示例代码拓展示例代码 专栏导读 作者简介花想云 在读本科生一枚C/C领域新星创作者新星计划导师阿里云专家博主CSDN内容合伙人…致力于 C/C、Linux 学习。 专栏简介本文收录于 C项目——基于多设计模式下的同步与异步日志系统 相关专栏推荐C语言初阶系列、C语言进阶系列 、C系列、数据结构与算法、Linux 日志宏全局接口设计
本章我们将完成提供全局接口宏函数对日志系统接口进行使用便捷性优化避免用户自己创建单例。
设计思想
提供获取指定日志器的全局接口避免用户自己操作单例对象使用宏函数对日志器的接口进行代理代理模式提供宏函数直接通过默认日志器进行日志的标准输出打印省去获取日志器的操作
#ifndef __MY_LOG__
#define __MY_LOG__
#include logger.hppnamespace LOG
{// 1.提供获取指定日志器的全局接口避免用户自己操作单例对象Logger::ptr getLogger(const std::string name){return LOG::LoggerManager::getInstance().getLogger(name);}Logger::ptr rootLogger(){return LOG::LoggerManager::getInstance().rootLogger();}// 2.实用宏函数对日志器的接口进行代理代理模式#define debug(fmt, ...) debug(__FILE__, __LINE__, fmt, ##__VA_ARGS__)#define info(fmt, ...) info(__FILE__, __LINE__, fmt, ##__VA_ARGS__)#define warn(fmt, ...) warn(__FILE__, __LINE__, fmt, ##__VA_ARGS__)#define error(fmt, ...) error(__FILE__, __LINE__, fmt, ##__VA_ARGS__)#define fatal(fmt, ...) fatal(__FILE__, __LINE__, fmt, ##__VA_ARGS__)// 3.提供宏函数直接通过默认日志器进行日志的标准输出打印#define DEBUG(fmt, ...) LOG::rootLogger()-debug(fmt, ##__VA_ARGS__)#define INFO(fmt, ...) LOG::rootLogger()-info(fmt, ##__VA_ARGS__)#define WARN(fmt, ...) LOG::rootLogger()-warn(fmt, ##__VA_ARGS__)#define ERROR(fmt, ...) LOG::rootLogger()-error(fmt, ##__VA_ARGS__)#define FATAL(fmt, ...) LOG::rootLogger()-fatal(fmt, ##__VA_ARGS__)}
#endif全局接口测试
测试代码
void log_test()
{DEBUG(%s, 测试日志);INFO(%s, 测试日志);WARN(%s, 测试日志);ERROR(%s, 测试日志);FATAL(%s, 测试日志);size_t count 0;while(count 300000){FATAL(测试日志-%d, count);}
}
int main()
{log_test();return 0;
}项目目录结构整理 示例代码
// example/test.cc
#include ../logs/log.h
#include unistd.hvoid log_test(const std::string name)
{INFO(%s, 测试开始);LOG::Logger::ptr logger LOG::LoggerManager::getInstance().getLogger(async_logger);logger-debug(__FILE__, __LINE__, %s, 测试日志);logger-info(__FILE__, __LINE__, %s, 测试日志);logger-warn(__FILE__, __LINE__, %s, 测试日志);logger-error(__FILE__, __LINE__, %s, 测试日志);logger-fatal(__FILE__, __LINE__, %s, 测试日志);INFO(%s, 测试完毕);
}
int main()
{std::unique_ptrLOG::LoggerBuilder builder(new LOG::GlobalLoggerBuilder());builder-buildLoggerName(async_logger);builder-buildLoggerLevel(LOG::LogLevel::value::WARN);builder-buildFormatter([%c][%f:%l]%m%n);builder-buildLoggerType(LOG::LoggerType::LOGGER_ASYNC);builder-buildSinkLOG::FileSink(./logfile/async.log);builder-buildSinkLOG::StdOutSink();builder-buildSinkLOG::RollBySizeSink(./logfile/roll-async-by-size, 1024 * 1024);builder-build();log_test(async_logger);return 0;
}
拓展示例代码
// extent/test.cc
#include ../logs/log.h
#include unistd.henum class TimeGap
{GAP_SECOND,GAP_MINUTE,GAP_HOUR,GAP_DAY
};
class RollByTimeSink : public LOG::LogSink
{
public:// 构造时传入文件名并打开文件将操作句柄管理起来RollByTimeSink(const std::string basename, TimeGap gap_type) : _basename(basename){switch(gap_type){case TimeGap::GAP_SECOND: _gap_size 1; break;case TimeGap::GAP_MINUTE: _gap_size 60; break;case TimeGap::GAP_HOUR: _gap_size 3600; break;case TimeGap::GAP_DAY: _gap_size 3600 * 24; break;}_cur_gap _gap_size 1? LOG::util::Date::getTime() : LOG::util::Date::getTime() % _gap_size; // 获取当前是第几个时间段std::string filename createNewFile();LOG::util::File::createDirectory(LOG::util::File::path(filename));_ofs.open(filename, std::ios::binary | std::ios::app);assert(_ofs.is_open());}// 将日志消息写入到标准输出判断当前时间是否是当前文件的时间段不是则切换文件void log(const char* data, size_t len){time_t cur LOG::util::Date::getTime();if((cur % _gap_size) ! _cur_gap){_ofs.close();std::string filename createNewFile();_ofs.open(filename, std::ios::binary | std::ios::app);assert(_ofs.is_open());}_ofs.write(data, len);assert(_ofs.good());}
private:std::string createNewFile(){time_t t LOG::util::Date::getTime();struct tm lt;localtime_r(t, lt);std::stringstream filename;filename _basename;filename lt.tm_year 1900;filename lt.tm_mon 1;filename lt.tm_mday;filename lt.tm_hour;filename lt.tm_min;filename lt.tm_sec;filename -;filename .log;return filename.str();}
private:std::string _basename;size_t _gap_size; // 时间段的大小int _cur_gap; // 当前是第几个时间段std::ofstream _ofs;
};int main()
{std::unique_ptrLOG::LoggerBuilder builder(new LOG::GlobalLoggerBuilder());builder-buildLoggerName(async_logger);builder-buildLoggerLevel(LOG::LogLevel::value::WARN);builder-buildFormatter([%c][%f:%l]%m%n);builder-buildLoggerType(LOG::LoggerType::LOGGER_ASYNC);builder-buildSinkLOG::FileSink(./logfile/async.log);builder-buildSinkLOG::StdOutSink();builder-buildSinkRollByTimeSink(./logfile/roll-async-by-time, TimeGap::GAP_SECOND);LOG::Logger::ptr logger builder-build();size_t cur LOG::util::Date::getTime();while(LOG::util::Date::getTime() cur 5){logger-fatal(这是一条测试日志);}return 0;
}