#46 - C++ Logger Class
Date: 2019-02-02 12:00 - C++
Simple classes to help you log events or errors to a file or anywhere you need.
// Logger.h
#pragma once
#include <string>
#include <mutex>
#define LOG_MSG(msg) YourNamespace::Logger::defaultLogger()->log(YourNamespace::Severity::NONE, (msg))
#define LOG_INFO(msg) YourNamespace::Logger::defaultLogger()->log(YourNamespace::Severity::INFO, (msg))
#define LOG_WARNING(msg) YourNamespace::Logger::defaultLogger()->log(YourNamespace::Severity::WARNING, (msg))
#define LOG_DEBUG(msg) YourNamespace::Logger::defaultLogger()->log(YourNamespace::Severity::DEBUG, (msg))
#define LOG_ERROR(msg) YourNamespace::Logger::defaultLogger()->log(YourNamespace::Severity::ERROR, (msg))
#define LOG_FATAL(msg) YourNamespace::Logger::defaultLogger()->log(YourNamespace::Severity::FATAL, (msg))
namespace YourNamespace {
enum class Severity { NONE, INFO, WARNING, DEBUG, ERROR, FATAL };
class Logger {
static Logger* _defaultLogger;
public:
static Logger* defaultLogger();
private:
std::mutex writeMutex;
std::string getSeverityName(Severity severity);
protected:
virtual void write(const std::string& msg) = 0;
virtual std::string getHeader();
public:
Logger(const std::string& name);
void log(Severity severity, const std::string& msg);
virtual ~Logger();
};
}
// Logger.cpp
#include "Logger.h"
#include <sstream>
#include <iomanip>
#include <ctime>
#include "FileLogger.h"
using namespace YourNamespace;
Logger* Logger::_defaultLogger = new FileLogger("default.log");
Logger* Logger::defaultLogger() {
return _defaultLogger;
}
std::string Logger::getSeverityName(Severity severity) {
switch(severity) {
case Severity::NONE:
return " ";
case Severity::INFO:
return "[INFO] ";
case Severity::WARNING:
return "[WARNING] ";
case Severity::DEBUG:
return "[DEBUG] ";
case Severity::ERROR:
return "[ERROR] ";
case Severity::FATAL:
return "[FATAL] ";
}
return "[UNKNOWN] ";
}
std::string Logger::getHeader() {
std::time_t t = std::time(nullptr);
std::tm tm;
localtime_s(&tm, &t);
std::stringstream header;
header << "[" << std::put_time(&tm, "%H:%M:%S") << "]";
return header.str();
}
Logger::Logger(const std::string& name) {
}
void Logger::log(Severity severity, const std::string& msg) {
std::lock_guard<std::mutex> lock(writeMutex);
write(getHeader() + getSeverityName(severity) + msg);
}
Logger::~Logger() {
}
// FileLogger.h
#pragma once
#include "Logger.h"
#include <fstream>
#include <memory>
namespace YourNamespace {
class FileLogger : public YourNamespace::Logger {
std::unique_ptr<std::ofstream> fileOut;
protected:
void write(const std::string& msg);
public:
FileLogger(const std::string& name);
~FileLogger();
};
}
// FileLogger.cpp
#include "FileLogger.h"
using namespace YourNamespace;
void FileLogger::write(const std::string& msg) {
(*fileOut) << msg << std::endl;
fileOut->flush();
}
FileLogger::FileLogger(const std::string& name) : Logger(name), fileOut(new std::ofstream) {
fileOut->open(name, std::ios_base::binary|std::ios_base::out);
if(!fileOut->is_open())
throw std::runtime_error("LOGGER: Unable to open an output stream.");
}
FileLogger::~FileLogger() {
if(fileOut)
fileOut->close();
}