#include <iostream>
#include <vector>
#include <memory>
#include <chrono>
#include "boost/noncopyable.hpp"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/base_sink.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/rotating_file_sink.h"
template <class T>
class SingleInstance : public boost::noncopyable {
public:
static inline T *instance() {
static T obj;
return &obj;
}
};
enum LogLevel {
LOG_DEBUG,
LOG_INFO,
LOG_WARNING,
LOG_ERROR,
LOG_CRITICAL
};
class Logger {
public:
Logger() : log_ptr_(nullptr) {
max_log_file_size = 10 * 1024 * 1024;
}
void set_max_log_file_size(size_t size) {
max_log_file_size = size;
}
bool init_log(const char *log_file) {
try {
const char *pattern = "[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%t] %v";
spdlog::flush_every(std::chrono::seconds(3));
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(log_file, max_log_file_size, 3);
log_ptr_ = std::unique_ptr<spdlog::logger>(new spdlog::logger("multi_sink", {console_sink, file_sink}));
log_ptr_->set_pattern(pattern);
log_ptr_->flush_on(spdlog::level::debug);
log_ptr_->set_level(spdlog::level::trace);
}
catch(const spdlog::spdlog_ex &ex) {
std::cerr << "log inittialization failed:" << ex.what() << std::endl;
return false;
}
return true;
}
inline void write_log(spdlog::level::level_enum level, const char *msg) {
log_ptr_->log(level, msg);
}
private:
static const size_t S_MAX_LOG_FILE_SIZE = 1024 * 1024 * 1024;
private:
std::unique_ptr<spdlog::logger>log_ptr_;
size_t max_log_file_size;
};
#define G_LOGGER SingleInstance<Logger>::instance()
bool InitLog(const char *log_path) {
return G_LOGGER->init_log(log_path);
}
inline void Log(unsigned level, const char *fmt, ...) {
char buffer[1024 * 8] = "";
va_list args;
va_start(args , fmt);
vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
va_end(args);
static std::vector<spdlog::level::level_enum>s_index_array{spdlog::level::debug, spdlog::level::info, spdlog::level::warn, spdlog::level::err, spdlog::level::critical};
if (level > LOG_CRITICAL) {
level = LOG_CRITICAL;
}
G_LOGGER->write_log(s_index_array[level], buffer);
}
int main() {
if (false == InitLog("./test.log")) {
return -1;
}
Log(LOG_INFO, "hello I am %d", 100);
return 0;
}