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