Improve bmcweb CLI app
Enhance bmcweb CLI app error messages. Replace the loglevel flag with a
subcommand called "loglevel". Handle case where empty log levels were
being propagated to bmcwebd.
Invalid logging values are handled by the CLI. List of available states
can be determined by using the command:
bmcweb loglevel -h
Example:
bmcweb loglevel DEBUG
bmcweb loglevel debug
Change-Id: Iaac3f674109e5d86f6c0cd7c1b930ee1c9c594e2
Signed-off-by: Aushim Nagarkatti <anagarkatti@nvidia.com>
diff --git a/DEVELOPING.md b/DEVELOPING.md
index bf5c42f..3412e24 100644
--- a/DEVELOPING.md
+++ b/DEVELOPING.md
@@ -252,5 +252,5 @@
example, to set logging level to INFO:
```bash
-bmcweb -l INFO
+bmcweb loglevel info
```
diff --git a/src/webserver_cli.cpp b/src/webserver_cli.cpp
index 821d592..f6642c7 100644
--- a/src/webserver_cli.cpp
+++ b/src/webserver_cli.cpp
@@ -5,6 +5,9 @@
#include <boost/asio/io_context.hpp>
#include <sdbusplus/asio/connection.hpp>
+#include <algorithm>
+#include <array>
+#include <cctype>
#include <memory>
#include <string>
@@ -14,6 +17,33 @@
crow::getBmcwebCurrentLoggingLevel() = crow::getLogLevelFromName(logLevel);
}
+static constexpr std::array<std::string, 7> levels{
+ "DISABLED", "CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "ENABLED"};
+
+// Check if debug level is valid
+static std::string validateLogLevel(std::string& input)
+{
+ std::transform(input.begin(), input.end(), input.begin(), ::toupper);
+ const std::string* iter = std::ranges::find(levels, input);
+ if (iter == levels.end())
+ {
+ return {"Invalid log level"};
+ }
+ return {};
+}
+
+static std::string helpMsg()
+{
+ std::string help = "\nLog levels to choose from:\n";
+ for (const std::string& prompt : levels)
+ {
+ std::string level = prompt;
+ std::transform(level.begin(), level.end(), level.begin(), ::tolower);
+ help.append(level + "\n");
+ }
+ return help;
+}
+
int main(int argc, char** argv) noexcept(false)
{
CLI::App app("BMCWeb SetLogLevel CLI");
@@ -27,25 +57,33 @@
std::string method = "SetLogLevel";
std::string loglevel;
- app.add_option("-l,--loglevel", loglevel, "Set bmcweb log level");
+ app.require_subcommand(1);
+
+ const CLI::Validator levelValidator =
+ CLI::Validator(validateLogLevel, "valid level");
+
+ CLI::App* sub = app.add_subcommand("loglevel", "Set bmcweb log level");
+ sub->add_option("level", loglevel, helpMsg())
+ ->required()
+ ->check(levelValidator);
CLI11_PARSE(app, argc, argv)
- BMCWEB_LOG_INFO("Working on log-level: {}", loglevel);
-
+ std::transform(loglevel.begin(), loglevel.end(), loglevel.begin(),
+ ::toupper);
// Set up dbus connection:
boost::asio::io_context io;
auto conn = std::make_shared<sdbusplus::asio::connection>(io);
// Attempt to async_call to set logging level
conn->async_method_call(
- [&io](boost::system::error_code& ec) mutable {
+ [&io, &loglevel](boost::system::error_code& ec) mutable {
if (ec)
{
BMCWEB_LOG_ERROR("SetLogLevel returned error with {}", ec);
return;
}
- BMCWEB_LOG_INFO("Successfully changed log-level ");
+ BMCWEB_LOG_INFO("logging level changed to: {}", loglevel);
io.stop();
},
service, path, iface, method, loglevel);