blob: e2bfdb1365bda0d17fa5ac13403bd9fdece6b244 [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 Tanouseb643c22020-10-02 14:51:22 -070022class Logger
Ed Tanous1abe55e2018-09-05 08:30:59 -070023{
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:
Ed Tanouseb643c22020-10-02 14:51:22 -070043 Logger([[maybe_unused]] const std::string& prefix,
Ed Tanouscb13a392020-07-25 19:02:03 +000044 [[maybe_unused]] const std::string& filename,
45 [[maybe_unused]] const size_t line, LogLevel levelIn) :
Ed Tanous271584a2019-07-09 16:24:22 -070046 level(levelIn)
Ed Tanous1abe55e2018-09-05 08:30:59 -070047 {
Ed Tanous55c7b7a2018-05-22 15:27:24 -070048#ifdef BMCWEB_ENABLE_LOGGING
James Feista0dba0f2019-07-08 10:26:14 -070049 stringstream << "(" << timestamp() << ") [" << prefix << " "
50 << std::filesystem::path(filename).filename() << ":"
51 << line << "] ";
Ed Tanous1e439872018-05-18 11:48:52 -070052#endif
Ed Tanous1abe55e2018-09-05 08:30:59 -070053 }
Ed Tanouseb643c22020-10-02 14:51:22 -070054 ~Logger()
Ed Tanous1abe55e2018-09-05 08:30:59 -070055 {
Ed Tanouseb643c22020-10-02 14:51:22 -070056 if (level >= getCurrentLogLevel())
Ed Tanous1abe55e2018-09-05 08:30:59 -070057 {
Ed Tanous43b761d2019-02-13 20:10:56 -080058#ifdef BMCWEB_ENABLE_LOGGING
Ed Tanous1abe55e2018-09-05 08:30:59 -070059 stringstream << std::endl;
Ed Tanous271584a2019-07-09 16:24:22 -070060 std::cerr << stringstream.str();
Ed Tanous1abe55e2018-09-05 08:30:59 -070061#endif
Ed Tanous43b761d2019-02-13 20:10:56 -080062 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070063 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070064
Ed Tanousecd6a3a2022-01-07 09:18:40 -080065 Logger(const Logger&) = delete;
66 Logger(Logger&&) = delete;
67 Logger& operator=(const Logger&) = delete;
68 Logger& operator=(const Logger&&) = delete;
69
Ed Tanous1abe55e2018-09-05 08:30:59 -070070 //
Gunnar Mills1214b7e2020-06-04 10:11:30 -050071 template <typename T>
Ed Tanouseb643c22020-10-02 14:51:22 -070072 Logger& operator<<([[maybe_unused]] T const& value)
Ed Tanous1abe55e2018-09-05 08:30:59 -070073 {
Ed Tanouseb643c22020-10-02 14:51:22 -070074 if (level >= getCurrentLogLevel())
Ed Tanous1abe55e2018-09-05 08:30:59 -070075 {
Ed Tanous43b761d2019-02-13 20:10:56 -080076#ifdef BMCWEB_ENABLE_LOGGING
Ed Tanous1abe55e2018-09-05 08:30:59 -070077 stringstream << value;
Ed Tanous1abe55e2018-09-05 08:30:59 -070078#endif
Ed Tanous43b761d2019-02-13 20:10:56 -080079 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070080 return *this;
81 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070082
Ed Tanous1abe55e2018-09-05 08:30:59 -070083 //
84 static void setLogLevel(LogLevel level)
85 {
86 getLogLevelRef() = level;
87 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070088
Ed Tanouseb643c22020-10-02 14:51:22 -070089 static LogLevel getCurrentLogLevel()
Ed Tanous1abe55e2018-09-05 08:30:59 -070090 {
91 return getLogLevelRef();
92 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070093
Ed Tanous1abe55e2018-09-05 08:30:59 -070094 private:
95 //
96 static LogLevel& getLogLevelRef()
97 {
98 static auto currentLevel = static_cast<LogLevel>(1);
99 return currentLevel;
100 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700101
102 //
103 std::ostringstream stringstream;
104 LogLevel level;
Ed Tanous1e439872018-05-18 11:48:52 -0700105};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700106} // namespace crow
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700107
Ed Tanous1abe55e2018-09-05 08:30:59 -0700108#define BMCWEB_LOG_CRITICAL \
Ed Tanouseb643c22020-10-02 14:51:22 -0700109 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Critical) \
110 crow::Logger("CRITICAL", __FILE__, __LINE__, crow::LogLevel::Critical)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700111#define BMCWEB_LOG_ERROR \
Ed Tanouseb643c22020-10-02 14:51:22 -0700112 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Error) \
113 crow::Logger("ERROR", __FILE__, __LINE__, crow::LogLevel::Error)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700114#define BMCWEB_LOG_WARNING \
Ed Tanouseb643c22020-10-02 14:51:22 -0700115 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Warning) \
116 crow::Logger("WARNING", __FILE__, __LINE__, crow::LogLevel::Warning)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700117#define BMCWEB_LOG_INFO \
Ed Tanouseb643c22020-10-02 14:51:22 -0700118 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Info) \
119 crow::Logger("INFO", __FILE__, __LINE__, crow::LogLevel::Info)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700120#define BMCWEB_LOG_DEBUG \
Ed Tanouseb643c22020-10-02 14:51:22 -0700121 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Debug) \
122 crow::Logger("DEBUG", __FILE__, __LINE__, crow::LogLevel::Debug)