blob: 526d1866f5fb50d5dcf25b47747d5cc1007eff5e [file] [log] [blame]
Ed Tanous7045c8d2017-04-03 10:04:37 -07001#pragma once
2
Myung Bae662aa6e2023-01-10 14:20:28 -06003#include "bmcweb_config.h"
4
Ed Tanous62598e32023-07-17 17:06:25 -07005#include <bit>
6#include <format>
Ed Tanous4d92cbf2017-06-22 15:41:02 -07007#include <iostream>
Ed Tanous62598e32023-07-17 17:06:25 -07008#include <source_location>
Myung Bae662aa6e2023-01-10 14:20:28 -06009#include <string_view>
Ed Tanous62598e32023-07-17 17:06:25 -070010#include <system_error>
11
Ed Tanous62598e32023-07-17 17:06:25 -070012// NOLINTBEGIN(readability-convert-member-functions-to-static, cert-dcl58-cpp)
13template <>
Ed Tanous62598e32023-07-17 17:06:25 -070014struct std::formatter<void*>
15{
16 constexpr auto parse(std::format_parse_context& ctx)
17 {
18 return ctx.begin();
19 }
20 auto format(const void*& ptr, auto& ctx) const
21 {
22 return std::format_to(ctx.out(), "{}",
23 std::to_string(std::bit_cast<size_t>(ptr)));
24 }
25};
Ed Tanous62598e32023-07-17 17:06:25 -070026// NOLINTEND(readability-convert-member-functions-to-static, cert-dcl58-cpp)
Ed Tanous4d92cbf2017-06-22 15:41:02 -070027
Ed Tanous1abe55e2018-09-05 08:30:59 -070028namespace crow
29{
30enum class LogLevel
31{
Myung Bae662aa6e2023-01-10 14:20:28 -060032 Disabled = 0,
Ed Tanous1abe55e2018-09-05 08:30:59 -070033 Critical,
Ed Tanouse7245fe2023-07-24 17:01:38 -070034 Error,
35 Warning,
36 Info,
37 Debug,
38 Enabled,
Ed Tanous1e439872018-05-18 11:48:52 -070039};
Ed Tanous4d92cbf2017-06-22 15:41:02 -070040
Myung Bae662aa6e2023-01-10 14:20:28 -060041// Mapping of the external loglvl name to internal loglvl
Ed Tanouse7245fe2023-07-24 17:01:38 -070042constexpr std::array<std::string_view, 7> mapLogLevelFromName{
43 "DISABLED", "CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "ENABLED"};
Myung Bae662aa6e2023-01-10 14:20:28 -060044
45constexpr crow::LogLevel getLogLevelFromName(std::string_view name)
46{
Ed Tanouse7245fe2023-07-24 17:01:38 -070047 const auto* iter = std::ranges::find(mapLogLevelFromName, name);
48 if (iter != mapLogLevelFromName.end())
Myung Bae662aa6e2023-01-10 14:20:28 -060049 {
Ed Tanouse7245fe2023-07-24 17:01:38 -070050 return static_cast<LogLevel>(iter - mapLogLevelFromName.begin());
Myung Bae662aa6e2023-01-10 14:20:28 -060051 }
52 return crow::LogLevel::Disabled;
53}
54
55// configured bmcweb LogLevel
Aushim Nagarkattibd1299b2024-08-12 17:11:04 -070056inline crow::LogLevel& getBmcwebCurrentLoggingLevel()
57{
58 static crow::LogLevel level = getLogLevelFromName(BMCWEB_LOGGING_LEVEL);
59 return level;
60}
61
62struct FormatString
63{
64 std::string_view str;
65 std::source_location loc;
66
67 // NOLINTNEXTLINE(google-explicit-constructor)
68 FormatString(const char* stringIn, const std::source_location& locIn =
69 std::source_location::current()) :
70 str(stringIn),
71 loc(locIn)
72 {}
73};
Myung Bae662aa6e2023-01-10 14:20:28 -060074
Ed Tanous62598e32023-07-17 17:06:25 -070075template <typename T>
76const void* logPtr(T p)
77{
78 static_assert(std::is_pointer<T>::value,
79 "Can't use logPtr without pointer");
80 return std::bit_cast<const void*>(p);
81}
82
Ed Tanous6ea90762024-04-07 08:38:44 -070083template <LogLevel level, typename... Args>
Ed Tanous17c47242024-04-08 17:18:12 -070084inline void vlog(std::format_string<Args...>&& format, Args&&... args,
Ed Tanous6ea90762024-04-07 08:38:44 -070085 const std::source_location& loc) noexcept
Ed Tanous62598e32023-07-17 17:06:25 -070086{
Aushim Nagarkattibd1299b2024-08-12 17:11:04 -070087 if (getBmcwebCurrentLoggingLevel() < level)
Ed Tanous62598e32023-07-17 17:06:25 -070088 {
89 return;
90 }
91 constexpr size_t stringIndex = static_cast<size_t>(level);
92 static_assert(stringIndex < mapLogLevelFromName.size(),
93 "Missing string for level");
Ed Tanouse7245fe2023-07-24 17:01:38 -070094 constexpr std::string_view levelString = mapLogLevelFromName[stringIndex];
Ed Tanous6ea90762024-04-07 08:38:44 -070095 std::string_view filename = loc.file_name();
Ed Tanousea5e2242024-08-06 10:28:35 -070096 filename = filename.substr(filename.rfind('/'));
97 if (!filename.empty())
98 {
99 filename.remove_prefix(1);
100 }
Ed Tanous17c47242024-04-08 17:18:12 -0700101 std::string logLocation;
Ed Tanous17c47242024-04-08 17:18:12 -0700102 try
103 {
104 // TODO, multiple static analysis tools flag that this could potentially
105 // throw Based on the documentation, it shouldn't throw, so long as none
106 // of the formatters throw, so unclear at this point why this try/catch
107 // is required, but add it to silence the static analysis tools.
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400108 logLocation =
109 std::format("[{} {}:{}] ", levelString, filename, loc.line());
110 logLocation +=
111 std::format(std::move(format), std::forward<Args>(args)...);
Ed Tanous17c47242024-04-08 17:18:12 -0700112 }
113 catch (const std::format_error& /*error*/)
114 {
115 logLocation += "Failed to format";
116 // Nothing more we can do here if logging is broken.
117 }
118 logLocation += '\n';
119 // Intentionally ignore error return.
120 fwrite(logLocation.data(), sizeof(std::string::value_type),
121 logLocation.size(), stdout);
122 fflush(stdout);
Ed Tanous62598e32023-07-17 17:06:25 -0700123}
Ed Tanous1abe55e2018-09-05 08:30:59 -0700124} // namespace crow
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700125
Ed Tanous62598e32023-07-17 17:06:25 -0700126template <typename... Args>
Ed Tanous6ea90762024-04-07 08:38:44 -0700127struct BMCWEB_LOG_CRITICAL
Ed Tanous62598e32023-07-17 17:06:25 -0700128{
Ed Tanous6ea90762024-04-07 08:38:44 -0700129 // NOLINTNEXTLINE(google-explicit-constructor)
130 BMCWEB_LOG_CRITICAL(std::format_string<Args...> format, Args&&... args,
131 const std::source_location& loc =
132 std::source_location::current()) noexcept
133 {
Ed Tanous17c47242024-04-08 17:18:12 -0700134 crow::vlog<crow::LogLevel::Critical, Args...>(
135 std::move(format), std::forward<Args>(args)..., loc);
Ed Tanous6ea90762024-04-07 08:38:44 -0700136 }
137};
Patrick Williamseb8a3992023-05-12 09:57:16 -0500138
Ed Tanous62598e32023-07-17 17:06:25 -0700139template <typename... Args>
Ed Tanous6ea90762024-04-07 08:38:44 -0700140struct BMCWEB_LOG_ERROR
Ed Tanous62598e32023-07-17 17:06:25 -0700141{
Ed Tanous6ea90762024-04-07 08:38:44 -0700142 // NOLINTNEXTLINE(google-explicit-constructor)
143 BMCWEB_LOG_ERROR(std::format_string<Args...> format, Args&&... args,
144 const std::source_location& loc =
145 std::source_location::current()) noexcept
146 {
Ed Tanous17c47242024-04-08 17:18:12 -0700147 crow::vlog<crow::LogLevel::Error, Args...>(
148 std::move(format), std::forward<Args>(args)..., loc);
Ed Tanous6ea90762024-04-07 08:38:44 -0700149 }
150};
Ed Tanous600d2392022-01-07 09:32:03 -0800151
Ed Tanous62598e32023-07-17 17:06:25 -0700152template <typename... Args>
Ed Tanous6ea90762024-04-07 08:38:44 -0700153struct BMCWEB_LOG_WARNING
Ed Tanous62598e32023-07-17 17:06:25 -0700154{
Ed Tanous6ea90762024-04-07 08:38:44 -0700155 // NOLINTNEXTLINE(google-explicit-constructor)
156 BMCWEB_LOG_WARNING(std::format_string<Args...> format, Args&&... args,
157 const std::source_location& loc =
158 std::source_location::current()) noexcept
159 {
Ed Tanous17c47242024-04-08 17:18:12 -0700160 crow::vlog<crow::LogLevel::Warning, Args...>(
161 std::move(format), std::forward<Args>(args)..., loc);
Ed Tanous6ea90762024-04-07 08:38:44 -0700162 }
163};
Ed Tanous600d2392022-01-07 09:32:03 -0800164
Ed Tanous62598e32023-07-17 17:06:25 -0700165template <typename... Args>
Ed Tanous6ea90762024-04-07 08:38:44 -0700166struct BMCWEB_LOG_INFO
Ed Tanous62598e32023-07-17 17:06:25 -0700167{
Ed Tanous6ea90762024-04-07 08:38:44 -0700168 // NOLINTNEXTLINE(google-explicit-constructor)
169 BMCWEB_LOG_INFO(std::format_string<Args...> format, Args&&... args,
170 const std::source_location& loc =
171 std::source_location::current()) noexcept
172 {
Ed Tanous17c47242024-04-08 17:18:12 -0700173 crow::vlog<crow::LogLevel::Info, Args...>(
174 std::move(format), std::forward<Args>(args)..., loc);
Ed Tanous6ea90762024-04-07 08:38:44 -0700175 }
176};
Ed Tanous600d2392022-01-07 09:32:03 -0800177
Ed Tanous62598e32023-07-17 17:06:25 -0700178template <typename... Args>
Ed Tanous6ea90762024-04-07 08:38:44 -0700179struct BMCWEB_LOG_DEBUG
Ed Tanous62598e32023-07-17 17:06:25 -0700180{
Ed Tanous6ea90762024-04-07 08:38:44 -0700181 // NOLINTNEXTLINE(google-explicit-constructor)
182 BMCWEB_LOG_DEBUG(std::format_string<Args...> format, Args&&... args,
183 const std::source_location& loc =
184 std::source_location::current()) noexcept
185 {
Ed Tanous17c47242024-04-08 17:18:12 -0700186 crow::vlog<crow::LogLevel::Debug, Args...>(
187 std::move(format), std::forward<Args>(args)..., loc);
Ed Tanous6ea90762024-04-07 08:38:44 -0700188 }
189};
190
191template <typename... Args>
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400192BMCWEB_LOG_CRITICAL(std::format_string<Args...>,
193 Args&&...) -> BMCWEB_LOG_CRITICAL<Args...>;
Ed Tanous6ea90762024-04-07 08:38:44 -0700194
195template <typename... Args>
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400196BMCWEB_LOG_ERROR(std::format_string<Args...>,
197 Args&&...) -> BMCWEB_LOG_ERROR<Args...>;
Ed Tanous6ea90762024-04-07 08:38:44 -0700198
199template <typename... Args>
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400200BMCWEB_LOG_WARNING(std::format_string<Args...>,
201 Args&&...) -> BMCWEB_LOG_WARNING<Args...>;
Ed Tanous6ea90762024-04-07 08:38:44 -0700202
203template <typename... Args>
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400204BMCWEB_LOG_INFO(std::format_string<Args...>,
205 Args&&...) -> BMCWEB_LOG_INFO<Args...>;
Ed Tanous6ea90762024-04-07 08:38:44 -0700206
207template <typename... Args>
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400208BMCWEB_LOG_DEBUG(std::format_string<Args...>,
209 Args&&...) -> BMCWEB_LOG_DEBUG<Args...>;