I have implemented my own logger based pimpl idiom. As a third party lib, I used spd log. My focus is to provide an interface to the end user who wants to print multiple parameters at once. I also used fold expression and ostringstream to streamline any primitive type of parameter. I would be grateful if you could provide me with your feedback.
//main.cpp
#include <logger.hpp>
int main() {
logger _logger(logger::trace);
_logger.LOG(logger::debug, "test1", "test2", 1, 2, 3.1, 'X');
return 0;
}
//logger.hpp
#pragma once
#include <memory>
#include <sstream>
class logger {
public:
enum level_enum : int {
trace = 0,
debug = 1,
info = 2,
warn = 3,
err = 4,
critical = 5,
off = 6,
n_levels
};
explicit logger(logger::level_enum level);
~logger();
template <typename... T>
void LOG(level_enum level, T... msg) {
auto stream = dump(std::forward<T>(msg)...);
print(level, stream);
}
template <typename... T>
std::ostringstream dump(T... msg) {
std::ostringstream stream;
((stream << msg << ' '), ...);
return stream;
}
void print(level_enum level, std::ostringstream& stream);
private:
class Impl;
std::unique_ptr<Impl> pImpl;
};
//spd_logger.cpp
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"
#include <logger.hpp>
#include <memory>
class logger::Impl {
std::shared_ptr<spdlog::logger> logger;
public:
explicit Impl(spdlog::level::level_enum level) {
logger = std::make_shared<spdlog::logger>("LOG");
logger->sinks().push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
logger->sinks().push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/basic_sink.txt"));
logger->set_level(level);
}
void log(logger::level_enum level, std::ostringstream& msg) {
logger->log(static_cast<spdlog::level::level_enum>(level), msg.str());
}
};
logger::logger(logger::level_enum level)
: pImpl(std::make_unique<Impl>(static_cast<spdlog::level::level_enum>(level))) {}
logger::~logger() = default;
void logger::print(level_enum level, std::ostringstream& msg) {
this->pImpl->log(level, msg);
}