cpputil/include/logger.h

105 lines
2.1 KiB
C++

#ifndef _LOGGER_H_
#define _LOGGER_H_
#include "log_queue.h"
#include <sstream>
#include <fstream>
#include <stdexcept>
#include <iostream>
#include <atomic>
#include <functional>
#include <ctime>
enum class log_type
{
std_output,
file
};
class logger
{
private:
std::atomic<bool> _enabled;
std::stringstream _logLine;
std::ofstream _outFile;
log_queue _queue;
log_type _type;
public:
logger();
logger(std::string path);
void set_enabled(bool enabled);
template<typename... Args> void log_info(const char* s, const Args&... args)
{
log("info", s, args...);
}
template<typename... Args> void log_warning(const char* s, const Args&... args)
{
log("warning", s, args...);
}
template<typename... Args> void log_error(const char* s, const Args&... args)
{
log("error", s, args...);
}
private:
template<typename... Args> void log(const char* log_level, const char* s, const Args&... args)
{
if (_enabled)
{
auto hrc = std::chrono::high_resolution_clock::now();
auto sc = std::chrono::system_clock::now();
_queue.add_log([this, s, args..., sc, hrc, log_level]{
_logLine.str("");
//_logLine << "[" << hrc.time_since_epoch().count() << "] ";
char tm_buffer[50];
std::time_t tm = std::chrono::system_clock::to_time_t(sc);
std::strftime(tm_buffer, 50, "%F %T", std::localtime(&tm));
_logLine << "[" << tm_buffer << "] ";
_logLine << "[" << log_level << "] ";
form_log_line(s, args...);
switch(_type)
{
case log_type::std_output:
std::cout << _logLine.str() << std::endl;
break;
case log_type::file:
_outFile << _logLine.str() << std::endl;
break;
}
});
}
}
void form_log_line(const char* s);
template<typename T, typename... Args> void form_log_line(const char* s, const T& value, const Args&... args)
{
while (*s)
{
if (*s == '%' && *++s != '%')
{
_logLine << value;
return form_log_line(s, args...);
}
_logLine << *s++;
}
throw std::runtime_error("extra arguments provided");
}
};
extern logger ulog;
#endif // _LOGGER_H_