代码拉取完成,页面将自动刷新
#ifndef __M_LOGGER_H__
#define __M_LOGGER_H__
// #define _GNU_SOURCE
#include "utils.hpp"
#include "level.hpp"
#include "format.hpp"
#include "sink.hpp"
#include <string>
#include <atomic>
#include <mutex>
#include <cstdarg>
#include <sstream>
#include <unordered_map>
#include "looper.hpp"
namespace logs
{
class Logger{
public:
Logger(const std::string &logger_name,
LogLevel::value level,
Formatter::ptr &formatter,
std::vector<LogSink::ptr> &sinks):
_logger_name(logger_name),
_limit_level(level),
_formatter(formatter),
_sinks(sinks.begin(),sinks.end()){}
using ptr = std::shared_ptr<Logger>;
const std::string name(){
return _logger_name;
}
void debug(const std::string &file,size_t line, const std::string &fmt, ...){
// 通过传入参数 构造出日志消息对象
// 判断等级->得到消息字符串->构造LogMsg对象->格式化得到日志->进行日志落地
if(LogLevel::value::DEBUG < _limit_level){
return;
}
va_list ap;
va_start(ap,fmt);
char *res;
int ret = vasprintf(&res, fmt.c_str(), ap);
if(ret == -1){
std::cout << "logger.hpp:vasprintf error!\n";
return;
}
va_end(ap);
serialize(LogLevel::value::DEBUG, file, line, res);
free(res);
}
void info(const std::string &file,size_t line, const std::string &fmt, ...){
if(LogLevel::value::INFO < _limit_level){
return;
}
va_list ap;
va_start(ap,fmt);
char *res;
int ret = vasprintf(&res, fmt.c_str(), ap);
if(ret == -1){
std::cout << "logger.hpp:vasprintf error!\n";
return;
}
va_end(ap);
serialize(LogLevel::value::INFO, file, line, res);
free(res);
}
void warn(const std::string &file,size_t line, const std::string &fmt, ...){
if(LogLevel::value::WARN < _limit_level){
return;
}
va_list ap;
va_start(ap,fmt);
char *res;
int ret = vasprintf(&res, fmt.c_str(), ap);
if(ret == -1){
std::cout << "logger.hpp:vasprintf error!\n";
return;
}
va_end(ap);
serialize(LogLevel::value::WARN, file, line, res);
free(res);
}
void error(const std::string &file,size_t line, const std::string &fmt, ...){
if(LogLevel::value::ERROR < _limit_level){
return;
}
va_list ap;
va_start(ap,fmt);
char *res;
int ret = vasprintf(&res, fmt.c_str(), ap);
if(ret == -1){
std::cout << "logger.hpp:vasprintf error!\n";
return;
}
va_end(ap);
serialize(LogLevel::value::ERROR, file, line, res);
free(res);
}
void fatal(const std::string &file,size_t line, const std::string &fmt, ...){
if(LogLevel::value::FATAL < _limit_level){
return;
}
va_list ap;
va_start(ap,fmt);
char *res;
int ret = vasprintf(&res, fmt.c_str(), ap);
if(ret == -1){
std::cout << "logger.hpp:vasprintf error!\n";
return;
}
va_end(ap);
serialize(LogLevel::value::FATAL, file, line, res);
free(res);
}
protected:
// 输出
virtual void log(const char *data, size_t len) = 0;
// 序列化封装
void serialize(LogLevel::value level, const std::string& file,size_t line,char* str){
LogMessage msg(level, line, file, _logger_name, str);
std::stringstream ss;
_formatter->format(ss, msg);
log(ss.str().c_str(), ss.str().size());
}
protected:
std::mutex _mutex;
std::string _logger_name;
std::atomic<LogLevel::value> _limit_level;
Formatter::ptr _formatter;
std::vector<LogSink::ptr> _sinks;
};
class SyncLogger:public Logger{
public:
SyncLogger(const std::string &logger_name,
LogLevel::value level,
Formatter::ptr &formatter,
std::vector<LogSink::ptr> &sinks):
Logger(logger_name,level,formatter,sinks){}
protected:
void log(const char* data, size_t len){
std::unique_lock<std::mutex> lock(_mutex);
if(_sinks.empty() == true) return;
for(auto &sink: _sinks){
sink->log(data, len);
}
}
};
class AsyncLogger : public Logger{
public:
AsyncLogger(const std::string &logger_name,
LogLevel::value level,
Formatter::ptr &formatter,
std::vector<LogSink::ptr> &sinks,
AsyncStatus status):
Logger(logger_name,level,formatter,sinks),
_looper(std::make_shared<AsyncLooper>(std::bind(&AsyncLogger::realLog,this,std::placeholders::_1), status)){}
void log(const char* data,size_t len){
_looper->push(data, len);
}
void realLog(Buffer &buf){
if(_sinks.empty() == true) return;
for(auto &sink: _sinks){
sink->log(buf.begin(), buf.readAbleSize());
}
}
private:
AsyncLooper::ptr _looper;
};
// 建造者模式
// 抽象一个建造者类:可以建造不同类型
// 零部件 + 构造整个
// 派生具体的建造者类:局部、全局
enum class LoggerType{
LOGGER_SYNC,
LOGGER_ASYNC
};
class LoggerBuilder{
public:
LoggerBuilder():
_logger_type(LoggerType::LOGGER_SYNC),
_limit_level(LogLevel::value::DEBUG),
_async_statue(AsyncStatus::ASYNC_SAFE){}
void buildLoggerType(LoggerType type){
_logger_type = type;
}
void buildEnableUnSafeStatue(){
_async_statue = AsyncStatus::ASYNC_UNSAFE;
}
void buildLoggerName(const std::string &name){
_logger_name = name;
}
void buildLoggerLevel(LogLevel::value level){
_limit_level = level;
}
void buildFormatter(const std::string &pattern){
_formatter = std::make_shared<Formatter>(pattern);
}
template<class SinkType,class ...Args>
void buildSink(Args&& ...args){
LogSink::ptr psink = SinkFactory::create<SinkType>(std::forward<Args>(args)...);
_sinks.push_back(psink);
}
virtual Logger::ptr build() = 0;
protected:
AsyncStatus _async_statue;
LoggerType _logger_type;
std::string _logger_name;
std::atomic<LogLevel::value> _limit_level;
Formatter::ptr _formatter;
std::vector<LogSink::ptr> _sinks;
};
class LocalLoggerBuilder : public LoggerBuilder{
public:
Logger::ptr build() override{
// 一定要有
assert(!_logger_name.empty());
if(_formatter.get() == nullptr){
_formatter = std::make_shared<Formatter>();
}
if(_sinks.empty()){
buildSink<StdoutSink>();
}
if(_logger_type == LoggerType::LOGGER_ASYNC){
return std::make_shared<AsyncLogger>(_logger_name, _limit_level, _formatter, _sinks, _async_statue);
}
else{
return std::make_shared<SyncLogger>(_logger_name, _limit_level, _formatter, _sinks);
}
}
};
class LoggerManager{
public:
static LoggerManager& getInstance(){
static LoggerManager eton;
return eton;
}
void addLogger(Logger::ptr &logger){
if(hasLogger(logger->name())) return;
std::unique_lock<std::mutex> lock(_mutex);
_loggers.insert(std::make_pair(logger->name(), logger));
}
bool hasLogger(const std::string &name){
std::unique_lock<std::mutex> lock(_mutex);
auto it = _loggers.find(name);
if(it == _loggers.end()){
return false;
}
return true;
}
Logger::ptr getLogger(const std::string &name){
std::unique_lock<std::mutex> lock(_mutex);
auto it = _loggers.find(name);
if(it == _loggers.end()){
return Logger::ptr();
}
return it->second;
}
Logger::ptr rootLogger(){
return _root_logger;
}
private:
LoggerManager(){
std::unique_ptr<logs::LoggerBuilder> builder(new logs::LocalLoggerBuilder());
builder->buildLoggerName("root");
_root_logger = builder->build();
_loggers.insert(make_pair("root", _root_logger));
}
private:
std::mutex _mutex;
Logger::ptr _root_logger;
std::unordered_map<std::string, Logger::ptr> _loggers;
};
class GoablLoggerBuilder : public LoggerBuilder{
public:
Logger::ptr build() override{
// 一定要有
assert(!_logger_name.empty());
if(_formatter.get() == nullptr){
_formatter = std::make_shared<Formatter>();
}
if(_sinks.empty()){
buildSink<StdoutSink>();
}
Logger::ptr logger;
if(_logger_type == LoggerType::LOGGER_ASYNC){
logger = std::make_shared<AsyncLogger>(_logger_name, _limit_level, _formatter, _sinks, _async_statue);
}
else{
logger = std::make_shared<SyncLogger>(_logger_name, _limit_level, _formatter, _sinks);
}
LoggerManager::getInstance().addLogger(logger);
return logger;
}
};
} // namespace logs
#endif // !__M_LOG_H__
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。