1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 #include "boost_formatters.hpp" 4 #include "logging.hpp" 5 6 #include <CLI/CLI.hpp> 7 #include <boost/asio/io_context.hpp> 8 #include <sdbusplus/asio/connection.hpp> 9 10 #include <algorithm> 11 #include <array> 12 #include <cctype> 13 #include <memory> 14 #include <string> 15 16 // Override default log option: 17 static void cliLogLevel(const std::string& logLevel) 18 { 19 crow::getBmcwebCurrentLoggingLevel() = crow::getLogLevelFromName(logLevel); 20 } 21 22 static constexpr std::array<std::string, 7> levels{ 23 "DISABLED", "CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "ENABLED"}; 24 25 // Check if debug level is valid 26 static std::string validateLogLevel(std::string& input) 27 { 28 std::transform(input.begin(), input.end(), input.begin(), ::toupper); 29 const std::string* iter = std::ranges::find(levels, input); 30 if (iter == levels.end()) 31 { 32 return {"Invalid log level"}; 33 } 34 return {}; 35 } 36 37 static std::string helpMsg() 38 { 39 std::string help = "\nLog levels to choose from:\n"; 40 for (const std::string& prompt : levels) 41 { 42 std::string level = prompt; 43 std::transform(level.begin(), level.end(), level.begin(), ::tolower); 44 help.append(level + "\n"); 45 } 46 return help; 47 } 48 49 int main(int argc, char** argv) noexcept(false) 50 { 51 CLI::App app("BMCWeb SetLogLevel CLI"); 52 53 cliLogLevel("INFO"); 54 55 // Define sdbus interfaces: 56 std::string service = "xyz.openbmc_project.bmcweb"; 57 std::string path = "/xyz/openbmc_project/bmcweb"; 58 std::string iface = "xyz.openbmc_project.bmcweb"; 59 std::string method = "SetLogLevel"; 60 61 std::string loglevel; 62 app.require_subcommand(1); 63 64 const CLI::Validator levelValidator = 65 CLI::Validator(validateLogLevel, "valid level"); 66 67 CLI::App* sub = app.add_subcommand("loglevel", "Set bmcweb log level"); 68 sub->add_option("level", loglevel, helpMsg()) 69 ->required() 70 ->check(levelValidator); 71 72 CLI11_PARSE(app, argc, argv) 73 74 std::transform(loglevel.begin(), loglevel.end(), loglevel.begin(), 75 ::toupper); 76 // Set up dbus connection: 77 boost::asio::io_context io; 78 auto conn = std::make_shared<sdbusplus::asio::connection>(io); 79 80 // Attempt to async_call to set logging level 81 conn->async_method_call( 82 [&io, &loglevel](boost::system::error_code& ec) mutable { 83 if (ec) 84 { 85 BMCWEB_LOG_ERROR("SetLogLevel returned error with {}", ec); 86 return; 87 } 88 BMCWEB_LOG_INFO("logging level changed to: {}", loglevel); 89 io.stop(); 90 }, 91 service, path, iface, method, loglevel); 92 93 io.run(); 94 95 return 0; 96 } 97