blob: a608f1f1f5bbf8a28448300061657826bde467de [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 Tanous1abe55e2018-09-05 08:30:59 -070030 time_t t = time(0);
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 //
65 template <typename T> logger& operator<<(T const& value)
66 {
Ed Tanous1abe55e2018-09-05 08:30:59 -070067 if (level >= get_current_log_level())
68 {
Ed Tanous43b761d2019-02-13 20:10:56 -080069#ifdef BMCWEB_ENABLE_LOGGING
Ed Tanous1abe55e2018-09-05 08:30:59 -070070 stringstream << value;
Ed Tanous1abe55e2018-09-05 08:30:59 -070071#endif
Ed Tanous43b761d2019-02-13 20:10:56 -080072 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070073 return *this;
74 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070075
Ed Tanous1abe55e2018-09-05 08:30:59 -070076 //
77 static void setLogLevel(LogLevel level)
78 {
79 getLogLevelRef() = level;
80 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070081
Ed Tanous1abe55e2018-09-05 08:30:59 -070082 static LogLevel get_current_log_level()
83 {
84 return getLogLevelRef();
85 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070086
Ed Tanous1abe55e2018-09-05 08:30:59 -070087 private:
88 //
89 static LogLevel& getLogLevelRef()
90 {
91 static auto currentLevel = static_cast<LogLevel>(1);
92 return currentLevel;
93 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070094
95 //
96 std::ostringstream stringstream;
97 LogLevel level;
Ed Tanous1e439872018-05-18 11:48:52 -070098};
Ed Tanous1abe55e2018-09-05 08:30:59 -070099} // namespace crow
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700100
Ed Tanous1abe55e2018-09-05 08:30:59 -0700101#define BMCWEB_LOG_CRITICAL \
102 if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \
James Feista0dba0f2019-07-08 10:26:14 -0700103 crow::logger("CRITICAL", __FILE__, __LINE__, crow::LogLevel::Critical)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700104#define BMCWEB_LOG_ERROR \
105 if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \
James Feista0dba0f2019-07-08 10:26:14 -0700106 crow::logger("ERROR", __FILE__, __LINE__, crow::LogLevel::Error)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700107#define BMCWEB_LOG_WARNING \
108 if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \
James Feista0dba0f2019-07-08 10:26:14 -0700109 crow::logger("WARNING", __FILE__, __LINE__, crow::LogLevel::Warning)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700110#define BMCWEB_LOG_INFO \
111 if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \
James Feista0dba0f2019-07-08 10:26:14 -0700112 crow::logger("INFO", __FILE__, __LINE__, crow::LogLevel::Info)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700113#define BMCWEB_LOG_DEBUG \
114 if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \
James Feista0dba0f2019-07-08 10:26:14 -0700115 crow::logger("DEBUG", __FILE__, __LINE__, crow::LogLevel::Debug)