2016-12-06 15:30:46 -05:00
|
|
|
#ifndef LOG_HPP
|
|
|
|
#define LOG_HPP
|
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <mutex>
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
enum LogLevel
|
|
|
|
{
|
2017-08-28 15:20:13 -04:00
|
|
|
logNONE,
|
2016-12-06 15:30:46 -05:00
|
|
|
logERROR,
|
2017-08-28 15:20:13 -04:00
|
|
|
logWARNING,
|
|
|
|
logINFO,
|
2016-12-06 15:30:46 -05:00
|
|
|
logDEBUG
|
|
|
|
};
|
|
|
|
|
2022-12-11 04:10:26 -05:00
|
|
|
namespace osrm::util
|
2016-12-06 15:30:46 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
class LogPolicy
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void Unmute();
|
|
|
|
|
|
|
|
void Mute();
|
|
|
|
|
|
|
|
bool IsMute() const;
|
|
|
|
|
2017-08-28 15:20:13 -04:00
|
|
|
LogLevel GetLevel() const;
|
|
|
|
void SetLevel(LogLevel level);
|
|
|
|
void SetLevel(std::string const &level);
|
|
|
|
|
2016-12-06 15:30:46 -05:00
|
|
|
static LogPolicy &GetInstance();
|
2017-08-28 15:20:13 -04:00
|
|
|
static std::string GetLevels();
|
2016-12-06 15:30:46 -05:00
|
|
|
|
|
|
|
LogPolicy(const LogPolicy &) = delete;
|
|
|
|
LogPolicy &operator=(const LogPolicy &) = delete;
|
|
|
|
|
|
|
|
private:
|
2017-08-28 15:20:13 -04:00
|
|
|
LogPolicy() : m_is_mute(true), m_level(logINFO) {}
|
2016-12-06 15:30:46 -05:00
|
|
|
std::atomic<bool> m_is_mute;
|
2017-08-28 15:20:13 -04:00
|
|
|
LogLevel m_level;
|
2016-12-06 15:30:46 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
class Log
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Log(LogLevel level_ = logINFO);
|
|
|
|
Log(LogLevel level_, std::ostream &ostream);
|
|
|
|
|
|
|
|
virtual ~Log();
|
|
|
|
std::mutex &get_mutex();
|
|
|
|
|
2017-09-15 04:45:07 -04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-11-06 07:21:45 -05:00
|
|
|
using manip = std::ostream &(std::ostream &);
|
2017-09-15 04:45:07 -04:00
|
|
|
|
|
|
|
inline Log &operator<<(manip &m)
|
|
|
|
{
|
|
|
|
const auto &policy = LogPolicy::GetInstance();
|
|
|
|
if (!policy.IsMute() && level <= policy.GetLevel())
|
|
|
|
{
|
|
|
|
stream << m;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
2016-12-06 15:30:46 -05:00
|
|
|
|
2022-08-01 17:40:26 -04:00
|
|
|
private:
|
|
|
|
void Init();
|
|
|
|
|
2016-12-06 15:30:46 -05:00
|
|
|
protected:
|
2017-09-15 04:45:07 -04:00
|
|
|
const LogLevel level;
|
2016-12-06 15:30:46 -05:00
|
|
|
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);
|
|
|
|
};
|
2022-12-20 12:00:11 -05:00
|
|
|
} // namespace osrm::util
|
2016-12-06 15:30:46 -05:00
|
|
|
|
|
|
|
#endif /* LOG_HPP */
|