blob: fcac94de186e4a6bd1914e0ea6a947399bcd031a [file] [log] [blame]
Ed Tanous7045c8d2017-04-03 10:04:37 -07001#pragma once
2
Ed Tanous4d92cbf2017-06-22 15:41:02 -07003#include <cstdio>
4#include <cstdlib>
5#include <ctime>
James Feista0dba0f2019-07-08 10:26:14 -07006#include <filesystem>
Ed Tanous4d92cbf2017-06-22 15:41:02 -07007#include <iostream>
8#include <sstream>
Ed Tanous1e439872018-05-18 11:48:52 -07009#include <string>
Ed Tanous4d92cbf2017-06-22 15:41:02 -070010
Ed Tanous1abe55e2018-09-05 08:30:59 -070011namespace crow
12{
13enum class LogLevel
14{
Ed Tanous1abe55e2018-09-05 08:30:59 -070015 Debug = 0,
16 Info,
17 Warning,
18 Error,
19 Critical,
Ed Tanous1e439872018-05-18 11:48:52 -070020};
Ed Tanous4d92cbf2017-06-22 15:41:02 -070021
Ed Tanous1abe55e2018-09-05 08:30:59 -070022class logger
23{
24 private:
25 //
26 static std::string timestamp()
27 {
Ed Tanous271584a2019-07-09 16:24:22 -070028 std::string date;
29 date.resize(32, '\0');
Ed Tanous99131cd2019-10-24 11:12:47 -070030 time_t t = time(nullptr);
Ed Tanous4d92cbf2017-06-22 15:41:02 -070031
Ed Tanous1abe55e2018-09-05 08:30:59 -070032 tm myTm{};
Ed Tanous4d92cbf2017-06-22 15:41:02 -070033
Ed Tanous1abe55e2018-09-05 08:30:59 -070034 gmtime_r(&t, &myTm);
Ed Tanous4d92cbf2017-06-22 15:41:02 -070035
Ed Tanous271584a2019-07-09 16:24:22 -070036 size_t sz =
37 strftime(date.data(), date.size(), "%Y-%m-%d %H:%M:%S", &myTm);
38 date.resize(sz);
39 return date;
Ed Tanous1e439872018-05-18 11:48:52 -070040 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070041
Ed Tanous1abe55e2018-09-05 08:30:59 -070042 public:
James Feista0dba0f2019-07-08 10:26:14 -070043 logger(const std::string& prefix, const std::string& filename,
Ed Tanous271584a2019-07-09 16:24:22 -070044 const size_t line, LogLevel levelIn) :
45 level(levelIn)
Ed Tanous1abe55e2018-09-05 08:30:59 -070046 {
Ed Tanous55c7b7a2018-05-22 15:27:24 -070047#ifdef BMCWEB_ENABLE_LOGGING
James Feista0dba0f2019-07-08 10:26:14 -070048 stringstream << "(" << timestamp() << ") [" << prefix << " "
49 << std::filesystem::path(filename).filename() << ":"
50 << line << "] ";
Ed Tanous1e439872018-05-18 11:48:52 -070051#endif
Ed Tanous1abe55e2018-09-05 08:30:59 -070052 }
53 ~logger()
54 {
Ed Tanous1abe55e2018-09-05 08:30:59 -070055 if (level >= get_current_log_level())
56 {
Ed Tanous43b761d2019-02-13 20:10:56 -080057#ifdef BMCWEB_ENABLE_LOGGING
Ed Tanous1abe55e2018-09-05 08:30:59 -070058 stringstream << std::endl;
Ed Tanous271584a2019-07-09 16:24:22 -070059 std::cerr << stringstream.str();
Ed Tanous1abe55e2018-09-05 08:30:59 -070060#endif
Ed Tanous43b761d2019-02-13 20:10:56 -080061 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070062 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070063
Ed Tanous1abe55e2018-09-05 08:30:59 -070064 //
Gunnar Mills1214b7e2020-06-04 10:11:30 -050065 template <typename T>
66 logger& operator<<(T const& value)
Ed Tanous1abe55e2018-09-05 08:30:59 -070067 {
Ed Tanous1abe55e2018-09-05 08:30:59 -070068 if (level >= get_current_log_level())
69 {
Ed Tanous43b761d2019-02-13 20:10:56 -080070#ifdef BMCWEB_ENABLE_LOGGING
Ed Tanous1abe55e2018-09-05 08:30:59 -070071 stringstream << value;
Ed Tanous1abe55e2018-09-05 08:30:59 -070072#endif
Ed Tanous43b761d2019-02-13 20:10:56 -080073 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070074 return *this;
75 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070076
Ed Tanous1abe55e2018-09-05 08:30:59 -070077 //
78 static void setLogLevel(LogLevel level)
79 {
80 getLogLevelRef() = level;
81 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070082
Ed Tanous1abe55e2018-09-05 08:30:59 -070083 static LogLevel get_current_log_level()
84 {
85 return getLogLevelRef();
86 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070087
Ed Tanous1abe55e2018-09-05 08:30:59 -070088 private:
89 //
90 static LogLevel& getLogLevelRef()
91 {
92 static auto currentLevel = static_cast<LogLevel>(1);
93 return currentLevel;
94 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070095
96 //
97 std::ostringstream stringstream;
98 LogLevel level;
Ed Tanous1e439872018-05-18 11:48:52 -070099};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700100} // namespace crow
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700101
Ed Tanous1abe55e2018-09-05 08:30:59 -0700102#define BMCWEB_LOG_CRITICAL \
103 if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \
James Feista0dba0f2019-07-08 10:26:14 -0700104 crow::logger("CRITICAL", __FILE__, __LINE__, crow::LogLevel::Critical)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700105#define BMCWEB_LOG_ERROR \
106 if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \
James Feista0dba0f2019-07-08 10:26:14 -0700107 crow::logger("ERROR", __FILE__, __LINE__, crow::LogLevel::Error)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700108#define BMCWEB_LOG_WARNING \
109 if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \
James Feista0dba0f2019-07-08 10:26:14 -0700110 crow::logger("WARNING", __FILE__, __LINE__, crow::LogLevel::Warning)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700111#define BMCWEB_LOG_INFO \
112 if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \
James Feista0dba0f2019-07-08 10:26:14 -0700113 crow::logger("INFO", __FILE__, __LINE__, crow::LogLevel::Info)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700114#define BMCWEB_LOG_DEBUG \
115 if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \
James Feista0dba0f2019-07-08 10:26:14 -0700116 crow::logger("DEBUG", __FILE__, __LINE__, crow::LogLevel::Debug)