blob: 0121729542fe5c7284ce85b01f7f205f64f8dff6 [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 Tanous1abe55e2018-09-05 08:30:59 -070065 //
Gunnar Mills1214b7e2020-06-04 10:11:30 -050066 template <typename T>
Ed Tanouseb643c22020-10-02 14:51:22 -070067 Logger& operator<<([[maybe_unused]] T const& value)
Ed Tanous1abe55e2018-09-05 08:30:59 -070068 {
Ed Tanouseb643c22020-10-02 14:51:22 -070069 if (level >= getCurrentLogLevel())
Ed Tanous1abe55e2018-09-05 08:30:59 -070070 {
Ed Tanous43b761d2019-02-13 20:10:56 -080071#ifdef BMCWEB_ENABLE_LOGGING
Ed Tanous1abe55e2018-09-05 08:30:59 -070072 stringstream << value;
Ed Tanous1abe55e2018-09-05 08:30:59 -070073#endif
Ed Tanous43b761d2019-02-13 20:10:56 -080074 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070075 return *this;
76 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070077
Ed Tanous1abe55e2018-09-05 08:30:59 -070078 //
79 static void setLogLevel(LogLevel level)
80 {
81 getLogLevelRef() = level;
82 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070083
Ed Tanouseb643c22020-10-02 14:51:22 -070084 static LogLevel getCurrentLogLevel()
Ed Tanous1abe55e2018-09-05 08:30:59 -070085 {
86 return getLogLevelRef();
87 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070088
Ed Tanous1abe55e2018-09-05 08:30:59 -070089 private:
90 //
91 static LogLevel& getLogLevelRef()
92 {
93 static auto currentLevel = static_cast<LogLevel>(1);
94 return currentLevel;
95 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070096
97 //
98 std::ostringstream stringstream;
99 LogLevel level;
Ed Tanous1e439872018-05-18 11:48:52 -0700100};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700101} // namespace crow
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700102
Ed Tanous1abe55e2018-09-05 08:30:59 -0700103#define BMCWEB_LOG_CRITICAL \
Ed Tanouseb643c22020-10-02 14:51:22 -0700104 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Critical) \
105 crow::Logger("CRITICAL", __FILE__, __LINE__, crow::LogLevel::Critical)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700106#define BMCWEB_LOG_ERROR \
Ed Tanouseb643c22020-10-02 14:51:22 -0700107 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Error) \
108 crow::Logger("ERROR", __FILE__, __LINE__, crow::LogLevel::Error)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700109#define BMCWEB_LOG_WARNING \
Ed Tanouseb643c22020-10-02 14:51:22 -0700110 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Warning) \
111 crow::Logger("WARNING", __FILE__, __LINE__, crow::LogLevel::Warning)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700112#define BMCWEB_LOG_INFO \
Ed Tanouseb643c22020-10-02 14:51:22 -0700113 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Info) \
114 crow::Logger("INFO", __FILE__, __LINE__, crow::LogLevel::Info)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700115#define BMCWEB_LOG_DEBUG \
Ed Tanouseb643c22020-10-02 14:51:22 -0700116 if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Debug) \
117 crow::Logger("DEBUG", __FILE__, __LINE__, crow::LogLevel::Debug)