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