osrm-backend/include/util/log.hpp
2022-12-20 18:00:11 +01:00

108 lines
2.1 KiB
C++

#ifndef LOG_HPP
#define LOG_HPP
#include <atomic>
#include <mutex>
#include <sstream>
enum LogLevel
{
logNONE,
logERROR,
logWARNING,
logINFO,
logDEBUG
};
namespace osrm::util
{
class LogPolicy
{
public:
void Unmute();
void Mute();
bool IsMute() const;
LogLevel GetLevel() const;
void SetLevel(LogLevel level);
void SetLevel(std::string const &level);
static LogPolicy &GetInstance();
static std::string GetLevels();
LogPolicy(const LogPolicy &) = delete;
LogPolicy &operator=(const LogPolicy &) = delete;
private:
LogPolicy() : m_is_mute(true), m_level(logINFO) {}
std::atomic<bool> m_is_mute;
LogLevel m_level;
};
class Log
{
public:
Log(LogLevel level_ = logINFO);
Log(LogLevel level_, std::ostream &ostream);
virtual ~Log();
std::mutex &get_mutex();
template <typename T> inline Log &operator<<(const T &data)
{
const auto &policy = LogPolicy::GetInstance();
if (!policy.IsMute() && level <= policy.GetLevel())
{
stream << data;
}
return *this;
}
template <typename T> inline Log &operator<<(const std::atomic<T> &data)
{
const auto &policy = LogPolicy::GetInstance();
if (!policy.IsMute() && level <= policy.GetLevel())
{
stream << T(data);
}
return *this;
}
using manip = std::ostream &(std::ostream &);
inline Log &operator<<(manip &m)
{
const auto &policy = LogPolicy::GetInstance();
if (!policy.IsMute() && level <= policy.GetLevel())
{
stream << m;
}
return *this;
}
private:
void Init();
protected:
const LogLevel level;
std::ostringstream buffer;
std::ostream &stream;
};
/**
* Modified logger - this one doesn't buffer - it writes directly to stdout,
* and the final newline is only printed when the object is destructed.
* Useful for logging situations where you don't want to newline right away
*/
class UnbufferedLog : public Log
{
public:
UnbufferedLog(LogLevel level_ = logINFO);
};
} // namespace osrm::util
#endif /* LOG_HPP */