xref: /openbmc/bmcweb/http/logging.hpp (revision 25b54dba775b31021a3a4677eb79e9771bcb97f7)
104e438cbSEd Tanous #pragma once
204e438cbSEd Tanous 
3662aa6e3SMyung Bae #include "bmcweb_config.h"
4662aa6e3SMyung Bae 
562598e31SEd Tanous #include <bit>
662598e31SEd Tanous #include <format>
704e438cbSEd Tanous #include <iostream>
862598e31SEd Tanous #include <source_location>
9662aa6e3SMyung Bae #include <string_view>
1062598e31SEd Tanous #include <system_error>
1162598e31SEd Tanous 
1262598e31SEd Tanous // NOLINTBEGIN(readability-convert-member-functions-to-static, cert-dcl58-cpp)
1362598e31SEd Tanous template <>
1462598e31SEd Tanous struct std::formatter<void*>
1562598e31SEd Tanous {
1662598e31SEd Tanous     constexpr auto parse(std::format_parse_context& ctx)
1762598e31SEd Tanous     {
1862598e31SEd Tanous         return ctx.begin();
1962598e31SEd Tanous     }
2062598e31SEd Tanous     auto format(const void*& ptr, auto& ctx) const
2162598e31SEd Tanous     {
2262598e31SEd Tanous         return std::format_to(ctx.out(), "{}",
2362598e31SEd Tanous                               std::to_string(std::bit_cast<size_t>(ptr)));
2462598e31SEd Tanous     }
2562598e31SEd Tanous };
2662598e31SEd Tanous // NOLINTEND(readability-convert-member-functions-to-static, cert-dcl58-cpp)
2704e438cbSEd Tanous 
2804e438cbSEd Tanous namespace crow
2904e438cbSEd Tanous {
3004e438cbSEd Tanous enum class LogLevel
3104e438cbSEd Tanous {
32662aa6e3SMyung Bae     Disabled = 0,
3304e438cbSEd Tanous     Critical,
34e7245fe8SEd Tanous     Error,
35e7245fe8SEd Tanous     Warning,
36e7245fe8SEd Tanous     Info,
37e7245fe8SEd Tanous     Debug,
38e7245fe8SEd Tanous     Enabled,
3904e438cbSEd Tanous };
4004e438cbSEd Tanous 
41662aa6e3SMyung Bae // Mapping of the external loglvl name to internal loglvl
42e7245fe8SEd Tanous constexpr std::array<std::string_view, 7> mapLogLevelFromName{
43e7245fe8SEd Tanous     "DISABLED", "CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "ENABLED"};
44662aa6e3SMyung Bae 
45662aa6e3SMyung Bae constexpr crow::LogLevel getLogLevelFromName(std::string_view name)
46662aa6e3SMyung Bae {
47e7245fe8SEd Tanous     const auto* iter = std::ranges::find(mapLogLevelFromName, name);
48e7245fe8SEd Tanous     if (iter != mapLogLevelFromName.end())
49662aa6e3SMyung Bae     {
50e7245fe8SEd Tanous         return static_cast<LogLevel>(iter - mapLogLevelFromName.begin());
51662aa6e3SMyung Bae     }
52662aa6e3SMyung Bae     return crow::LogLevel::Disabled;
53662aa6e3SMyung Bae }
54662aa6e3SMyung Bae 
55662aa6e3SMyung Bae // configured bmcweb LogLevel
56662aa6e3SMyung Bae constexpr crow::LogLevel bmcwebCurrentLoggingLevel =
57*25b54dbaSEd Tanous     getLogLevelFromName(BMCWEB_LOGGING_LEVEL);
58662aa6e3SMyung Bae 
5962598e31SEd Tanous template <typename T>
6062598e31SEd Tanous const void* logPtr(T p)
6162598e31SEd Tanous {
6262598e31SEd Tanous     static_assert(std::is_pointer<T>::value,
6362598e31SEd Tanous                   "Can't use logPtr without pointer");
6462598e31SEd Tanous     return std::bit_cast<const void*>(p);
6562598e31SEd Tanous }
6662598e31SEd Tanous 
676ea90760SEd Tanous template <LogLevel level, typename... Args>
686ea90760SEd Tanous inline void vlog(std::format_string<Args...> format, Args... args,
696ea90760SEd Tanous                  const std::source_location& loc) noexcept
7062598e31SEd Tanous {
71d518a9beSMyung Bae     if constexpr (bmcwebCurrentLoggingLevel < level)
7262598e31SEd Tanous     {
7362598e31SEd Tanous         return;
7462598e31SEd Tanous     }
7562598e31SEd Tanous     constexpr size_t stringIndex = static_cast<size_t>(level);
7662598e31SEd Tanous     static_assert(stringIndex < mapLogLevelFromName.size(),
7762598e31SEd Tanous                   "Missing string for level");
78e7245fe8SEd Tanous     constexpr std::string_view levelString = mapLogLevelFromName[stringIndex];
796ea90760SEd Tanous     std::string_view filename = loc.file_name();
80e7245fe8SEd Tanous     filename = filename.substr(filename.rfind('/') + 1);
816ea90760SEd Tanous     std::cout << std::format("[{} {}:{}] ", levelString, filename, loc.line())
826ea90760SEd Tanous               << std::format(format, std::forward<Args>(args)...) << '\n'
83dce4d230SEd Tanous               << std::flush;
8462598e31SEd Tanous }
8504e438cbSEd Tanous } // namespace crow
8604e438cbSEd Tanous 
8762598e31SEd Tanous template <typename... Args>
886ea90760SEd Tanous struct BMCWEB_LOG_CRITICAL
8962598e31SEd Tanous {
906ea90760SEd Tanous     // NOLINTNEXTLINE(google-explicit-constructor)
916ea90760SEd Tanous     BMCWEB_LOG_CRITICAL(std::format_string<Args...> format, Args&&... args,
926ea90760SEd Tanous                         const std::source_location& loc =
936ea90760SEd Tanous                             std::source_location::current()) noexcept
946ea90760SEd Tanous     {
956ea90760SEd Tanous         crow::vlog<crow::LogLevel::Critical, Args...>(format, args..., loc);
9662598e31SEd Tanous     }
976ea90760SEd Tanous };
98eb8a3998SPatrick Williams 
9962598e31SEd Tanous template <typename... Args>
1006ea90760SEd Tanous struct BMCWEB_LOG_ERROR
10162598e31SEd Tanous {
1026ea90760SEd Tanous     // NOLINTNEXTLINE(google-explicit-constructor)
1036ea90760SEd Tanous     BMCWEB_LOG_ERROR(std::format_string<Args...> format, Args&&... args,
1046ea90760SEd Tanous                      const std::source_location& loc =
1056ea90760SEd Tanous                          std::source_location::current()) noexcept
1066ea90760SEd Tanous     {
1076ea90760SEd Tanous         crow::vlog<crow::LogLevel::Error, Args...>(format, args..., loc);
10862598e31SEd Tanous     }
1096ea90760SEd Tanous };
110600d2394SEd Tanous 
11162598e31SEd Tanous template <typename... Args>
1126ea90760SEd Tanous struct BMCWEB_LOG_WARNING
11362598e31SEd Tanous {
1146ea90760SEd Tanous     // NOLINTNEXTLINE(google-explicit-constructor)
1156ea90760SEd Tanous     BMCWEB_LOG_WARNING(std::format_string<Args...> format, Args&&... args,
1166ea90760SEd Tanous                        const std::source_location& loc =
1176ea90760SEd Tanous                            std::source_location::current()) noexcept
1186ea90760SEd Tanous     {
1196ea90760SEd Tanous         crow::vlog<crow::LogLevel::Warning, Args...>(format, args..., loc);
12062598e31SEd Tanous     }
1216ea90760SEd Tanous };
122600d2394SEd Tanous 
12362598e31SEd Tanous template <typename... Args>
1246ea90760SEd Tanous struct BMCWEB_LOG_INFO
12562598e31SEd Tanous {
1266ea90760SEd Tanous     // NOLINTNEXTLINE(google-explicit-constructor)
1276ea90760SEd Tanous     BMCWEB_LOG_INFO(std::format_string<Args...> format, Args&&... args,
1286ea90760SEd Tanous                     const std::source_location& loc =
1296ea90760SEd Tanous                         std::source_location::current()) noexcept
1306ea90760SEd Tanous     {
1316ea90760SEd Tanous         crow::vlog<crow::LogLevel::Info, Args...>(format, args..., loc);
13262598e31SEd Tanous     }
1336ea90760SEd Tanous };
134600d2394SEd Tanous 
13562598e31SEd Tanous template <typename... Args>
1366ea90760SEd Tanous struct BMCWEB_LOG_DEBUG
13762598e31SEd Tanous {
1386ea90760SEd Tanous     // NOLINTNEXTLINE(google-explicit-constructor)
1396ea90760SEd Tanous     BMCWEB_LOG_DEBUG(std::format_string<Args...> format, Args&&... args,
1406ea90760SEd Tanous                      const std::source_location& loc =
1416ea90760SEd Tanous                          std::source_location::current()) noexcept
1426ea90760SEd Tanous     {
1436ea90760SEd Tanous         crow::vlog<crow::LogLevel::Debug, Args...>(format, args..., loc);
14462598e31SEd Tanous     }
1456ea90760SEd Tanous };
1466ea90760SEd Tanous 
1476ea90760SEd Tanous template <typename... Args>
1486ea90760SEd Tanous BMCWEB_LOG_CRITICAL(std::format_string<Args...>, Args&&...)
1496ea90760SEd Tanous     -> BMCWEB_LOG_CRITICAL<Args...>;
1506ea90760SEd Tanous 
1516ea90760SEd Tanous template <typename... Args>
1526ea90760SEd Tanous BMCWEB_LOG_ERROR(std::format_string<Args...>, Args&&...)
1536ea90760SEd Tanous     -> BMCWEB_LOG_ERROR<Args...>;
1546ea90760SEd Tanous 
1556ea90760SEd Tanous template <typename... Args>
1566ea90760SEd Tanous BMCWEB_LOG_WARNING(std::format_string<Args...>, Args&&...)
1576ea90760SEd Tanous     -> BMCWEB_LOG_WARNING<Args...>;
1586ea90760SEd Tanous 
1596ea90760SEd Tanous template <typename... Args>
1606ea90760SEd Tanous BMCWEB_LOG_INFO(std::format_string<Args...>, Args&&...)
1616ea90760SEd Tanous     -> BMCWEB_LOG_INFO<Args...>;
1626ea90760SEd Tanous 
1636ea90760SEd Tanous template <typename... Args>
1646ea90760SEd Tanous BMCWEB_LOG_DEBUG(std::format_string<Args...>, Args&&...)
1656ea90760SEd Tanous     -> BMCWEB_LOG_DEBUG<Args...>;
166