单例模式(Singleton Pattern,也称为单件模式),使用最广泛的设计模式之一。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
这种模式在我们的程序设计中有着广泛应用,比如日志操作、数据库的操作等,下面以日志类为例介绍这种类的应用。
下面是使用spdlog作为日志系统写的日志类部分代码:类的定义
#include <string>
#include <mutex>
#include <pthread.h>
#include "spdlog/logger.h"
#define LOG_BUFFER_SIZE 8192
class CLogger{
public:
CLogger();
~CLogger();
//此处关键,一定要定为静态的
static CLogger *getInstance();
void destroy();
void init(std::string filename, int file_size, std::string tag, int level);
//仅打印
void log_i(const char* format, ...);
void log_w(const char* format, ...);
void log_e(const char* format, ...);
void log_d(const char* format, ...);
private:
pthread_mutex_t c_mutex;
int c_log_level;
int c_file_size;
std::string c_filename;
std::string c_tag;
std::shared_ptr<spdlog::logger> c_async_file_logger;
private:
CLogger *c_logger; //此处定义为static或者 实例化时用静态指针赋值
char *c_log_buf;
static std::mutex c_singleton_mutex;
void set_log_tag(std::string tag);
void set_log_level(int level);
void set_log_file_path(std::string filename);
void set_log_file_size(int size);
}
类的实现(部分,不全)
#include "CLogger.h"
#include "spdlog/spdlog.h"
#include "spdlog/async.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#define LOG_FORMAT "%^[%Y-%m-%d %H:%M:%S.%e] %l [%n] %v %$"
#define get_params(func) { \
pthread_mutex_lock(&c_mutex); \
va_list ap;\
va_start(ap, format);\
vsnprintf(c_log_buf, LOG_BUFFER_SIZE, format, ap);\
va_end(ap);\
func("{}", c_log_buf); \
pthread_mutex_unlock(&c_mutex); \
}
std::mutex CLogger::c_singleton_mutex;
CLogger::CLogger(){
c_logger = NULL;
c_log_buf = (char *)malloc(LOG_BUFFER_SIZE);
pthread_mutex_init(&c_mutex, NULL);
}
CLogger::~CLogger(){
destroy();
}
void CLogger::destroy(){
if(NULL != c_logger){
delete c_logger;
c_logger = NULL;
}
if(NULL !=c_log_buf){
free(c_log_buf);
c_log_buf = NULL;
}
}
CLogger *CLogger::getInstance(){
std::lock_guard<std::mutex> lock(c_singleton_mutex);
static CLogger *logger = new CLogger(); //注意,此处是静态的
logger->c_logger = logger;
return logger;
}
void CLogger::init(std::string filename, int file_size, std::string tag, int level){
pthread_mutex_lock(&c_mutex);
set_log_file_path(filename);
set_log_file_size(file_size);
set_log_tag(tag);
set_log_level(level);
//
spdlog::stdout_color_mt(c_tag);
//
spdlog::set_pattern(LOG_FORMAT);
//
std::string f_tag = "-"+c_tag+"-";
c_async_file_logger = spdlog::rotating_logger_mt<spdlog::async_factory>(f_tag, filename, file_size, 1);
c_async_file_logger->set_pattern(LOG_FORMAT);
spdlog::flush_every(std::chrono::seconds(3));
pthread_mutex_unlock(&c_mutex);
}
void CLogger::set_log_tag(std::string tag){
c_tag = tag;
}
void CLogger::set_log_level(int level){
c_log_level = level;
spdlog::set_level((spdlog::level::level_enum)level);
}
void CLogger::set_log_file_path(std::string filename){
c_filename = filename;
}
void CLogger::set_log_file_size(int size){
c_file_size = size;
}
template<typename... Args>
void CLogger::i(fmt::format_string<Args...> fmt, Args &&...args){
spdlog::get(c_tag)->info(std::forward<fmt::format_string<Args...>>(fmt), std::forward<Args>(args)...);
}
template<typename... Args>
void CLogger::w(fmt::format_string<Args...> fmt, Args &&...args){
spdlog::get(c_tag)->warn(std::forward<fmt::format_string<Args...>>(fmt), std::forward<Args>(args)...);
}
template<typename... Args>
void CLogger::e(fmt::format_string<Args...> fmt, Args &&...args){
spdlog::get(c_tag)->error(std::forward<fmt::format_string<Args...>>(fmt), std::forward<Args>(args)...);
}
template<typename... Args>
void CLogger::d(fmt::format_string<Args...> fmt, Args &&...args){
spdlog::get(c_tag)->debug(std::forward<fmt::format_string<Args...>>(fmt), std::forward<Args>(args)...);
}
调用:
包含头文件"CLogger.h"
#include "CLogger.h"
CLogger::getInstance()->log_d("logger test num =%d", items.size());
2386





