Update Logging option for the setting log level
In order to be able to more easily debug bmcweb related issue,
a new meson option is added to set a specific logging level
Which generates the targeted logging traces rather than all of
debug traces.
The current option -Dbmcweb-logging which can be either
disabled or enabled is changed to allow to set the log level
for the specific level traces (e.g. error or critical traces)
to be written to the journal.
-Dbmcweb-logging=<log-level>
where <log-level> can be disabled, enabled, debug, info,
warning, error, or critical.
- `disabled`: Turns off all bmcweb log traces.
- `enabled` : treated as `debug`
- Other option can be described in
[Logging Levels](DEVELOPING.md).
For an example, to enable only 'error', 'critical' log
entries, bmcweb can be built with
-Dbmcweb-logging=error
Testing:
- Verified that only the specific logs (e.g. error and
critical logs) were displayed by compiling bmcweb with the
specific bmcweb-logging level.
Change-Id: I522ca26700ea420fee1a5cf688d3e8c6661f2f55
Signed-off-by: Myung Bae <myungbae@us.ibm.com>
diff --git a/DEVELOPING.md b/DEVELOPING.md
index ae6b5c0..5468f79 100644
--- a/DEVELOPING.md
+++ b/DEVELOPING.md
@@ -234,15 +234,15 @@
### Enabling logging
bmcweb by default is compiled with runtime logging disabled, as a performance
-consideration. To enable it in a standalone build, add the
+consideration. To enable it in a standalone build, add the logging level
```ascii
--Dlogging='enabled'
+-Dlogging='debug'
```
option to your configure flags. If building within Yocto, add the following to
your local.conf.
```bash
-EXTRA_OEMESON:pn-bmcweb:append = "-Dbmcweb-logging='enabled'"
+EXTRA_OEMESON:pn-bmcweb:append = "-Dbmcweb-logging='debug'"
```
diff --git a/config/bmcweb_config.h.in b/config/bmcweb_config.h.in
index b0a3a7b..ae98675 100644
--- a/config/bmcweb_config.h.in
+++ b/config/bmcweb_config.h.in
@@ -14,4 +14,6 @@
constexpr const char* mesonInstallPrefix = "@MESON_INSTALL_PREFIX@";
constexpr const bool bmcwebInsecureEnableHttpPushStyleEventing = @BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING@ == 1;
+
+constexpr const char* bmcwebLoggingLevel = "@BMCWEB_LOGGING_LEVEL@";
// clang-format on
diff --git a/config/meson.build b/config/meson.build
index f42656b..b13a023 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -13,6 +13,14 @@
conf_data.set('MESON_INSTALL_PREFIX', get_option('prefix'))
conf_data.set('HTTPS_PORT', get_option('https_port'))
+# Logging level
+loglvlopt = get_option('bmcweb-logging')
+if get_option('buildtype').startswith('debug') and loglvlopt == 'disabled'
+ # Override logging level as 'debug' if 'bmcweb-logging' is set as 'dsiabled'
+ loglvlopt = 'debug'
+endif
+conf_data.set('BMCWEB_LOGGING_LEVEL', loglvlopt)
+
conf_h_dep = declare_dependency(
include_directories: include_directories('.'),
sources: configure_file(
@@ -41,4 +49,5 @@
output : 'webserver',
copy : true,
install_dir: '/etc/pam.d',
- install : true)
\ No newline at end of file
+ install : true)
+
diff --git a/http/logging.hpp b/http/logging.hpp
index 5f268f4..6543b73 100644
--- a/http/logging.hpp
+++ b/http/logging.hpp
@@ -1,5 +1,9 @@
#pragma once
+#include "bmcweb_config.h"
+
+#include <algorithm>
+#include <array>
#include <cstdio>
#include <cstdlib>
#include <ctime>
@@ -7,18 +11,46 @@
#include <iostream>
#include <sstream>
#include <string>
+#include <string_view>
namespace crow
{
enum class LogLevel
{
- Debug = 0,
+ Disabled = 0,
+ Debug,
Info,
Warning,
Error,
Critical,
};
+// Mapping of the external loglvl name to internal loglvl
+constexpr std::array<std::pair<std::string_view, crow::LogLevel>, 7>
+ mapLogLevelFromName{{{"disabled", crow::LogLevel::Disabled},
+ {"enabled", crow::LogLevel::Debug},
+ {"debug", crow::LogLevel::Debug},
+ {"info", crow::LogLevel::Info},
+ {"warning", crow::LogLevel::Warning},
+ {"error", crow::LogLevel::Error},
+ {"critical", crow::LogLevel::Critical}}};
+
+constexpr crow::LogLevel getLogLevelFromName(std::string_view name)
+{
+ const auto* iter =
+ std::find_if(begin(mapLogLevelFromName), end(mapLogLevelFromName),
+ [&name](const auto& v) { return v.first == name; });
+ if (iter != end(mapLogLevelFromName))
+ {
+ return iter->second;
+ }
+ return crow::LogLevel::Disabled;
+}
+
+// configured bmcweb LogLevel
+constexpr crow::LogLevel bmcwebCurrentLoggingLevel =
+ getLogLevelFromName(bmcwebLoggingLevel);
+
class Logger
{
private:
@@ -42,24 +74,16 @@
public:
Logger([[maybe_unused]] const std::string& prefix,
[[maybe_unused]] const std::string& filename,
- [[maybe_unused]] const size_t line, LogLevel levelIn) :
- level(levelIn)
+ [[maybe_unused]] const size_t line)
{
-#ifdef BMCWEB_ENABLE_LOGGING
stringstream << "(" << timestamp() << ") [" << prefix << " "
<< std::filesystem::path(filename).filename() << ":"
<< line << "] ";
-#endif
}
~Logger()
{
- if (level >= getCurrentLogLevel())
- {
-#ifdef BMCWEB_ENABLE_LOGGING
- stringstream << std::endl;
- std::cerr << stringstream.str();
-#endif
- }
+ stringstream << std::endl;
+ std::cerr << stringstream.str();
}
Logger(const Logger&) = delete;
@@ -71,41 +95,32 @@
template <typename T>
Logger& operator<<([[maybe_unused]] T const& value)
{
- if (level >= getCurrentLogLevel())
- {
-#ifdef BMCWEB_ENABLE_LOGGING
- // Somewhere in the code we're implicitly casting an array to a
- // pointer in logging code. It's non-trivial to find, so disable
- // the check here for now
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
- stringstream << value;
-#endif
- }
+ // Somewhere in the code we're implicitly casting an array to a
+ // pointer in logging code. It's non-trivial to find,
+ // so disable the check here for now
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
+ stringstream << value;
return *this;
}
- //
- static void setLogLevel(LogLevel level)
+ constexpr static LogLevel getCurrentLogLevel()
{
- getLogLevelRef() = level;
+ return bmcwebCurrentLoggingLevel;
}
- static LogLevel getCurrentLogLevel()
+ constexpr static bool isLoggingEnabled()
{
- return getLogLevelRef();
+ return getCurrentLogLevel() >= crow::LogLevel::Debug;
+ }
+
+ constexpr static bool checkLoggingLevel(const LogLevel level)
+ {
+ return isLoggingEnabled() && (getCurrentLogLevel() <= level);
}
private:
//
- static LogLevel& getLogLevelRef()
- {
- static auto currentLevel = static_cast<LogLevel>(1);
- return currentLevel;
- }
-
- //
std::ostringstream stringstream;
- LogLevel level;
};
} // namespace crow
@@ -115,25 +130,25 @@
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define BMCWEB_LOG_CRITICAL \
- if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Critical) \
- crow::Logger("CRITICAL", __FILE__, __LINE__, crow::LogLevel::Critical)
+ if constexpr (crow::Logger::checkLoggingLevel(crow::LogLevel::Critical)) \
+ crow::Logger("CRITICAL", __FILE__, __LINE__)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define BMCWEB_LOG_ERROR \
- if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Error) \
- crow::Logger("ERROR", __FILE__, __LINE__, crow::LogLevel::Error)
+ if constexpr (crow::Logger::checkLoggingLevel(crow::LogLevel::Error)) \
+ crow::Logger("ERROR", __FILE__, __LINE__)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define BMCWEB_LOG_WARNING \
- if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Warning) \
- crow::Logger("WARNING", __FILE__, __LINE__, crow::LogLevel::Warning)
+ if constexpr (crow::Logger::checkLoggingLevel(crow::LogLevel::Warning)) \
+ crow::Logger("WARNING", __FILE__, __LINE__)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define BMCWEB_LOG_INFO \
- if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Info) \
- crow::Logger("INFO", __FILE__, __LINE__, crow::LogLevel::Info)
+ if constexpr (crow::Logger::checkLoggingLevel(crow::LogLevel::Info)) \
+ crow::Logger("INFO", __FILE__, __LINE__)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define BMCWEB_LOG_DEBUG \
- if (crow::Logger::getCurrentLogLevel() <= crow::LogLevel::Debug) \
- crow::Logger("DEBUG", __FILE__, __LINE__, crow::LogLevel::Debug)
+ if constexpr (crow::Logger::checkLoggingLevel(crow::LogLevel::Debug)) \
+ crow::Logger("DEBUG", __FILE__, __LINE__)
diff --git a/meson.build b/meson.build
index cf4c658..5405548 100644
--- a/meson.build
+++ b/meson.build
@@ -198,18 +198,14 @@
endif
endif
-if( get_option('bmcweb-logging').enabled() or \
+if( get_option('bmcweb-logging') != 'disabled' or \
get_option('buildtype').startswith('debug'))
add_project_arguments([
- '-DBMCWEB_ENABLE_LOGGING',
'-DBMCWEB_ENABLE_DEBUG'
],
language : 'cpp')
- summary({'debug' :'-DBMCWEB_ENABLE_DEBUG',
- 'logging' : '-DBMCWEB_ENABLE_LOGGING',
-
- },section : 'Enabled Features')
+ summary('debug', '-DBMCWEB_ENABLE_DEBUG', section : 'Enabled Features')
endif
# Set Compiler Security flags
diff --git a/meson_options.txt b/meson_options.txt
index 57fb8ce..0bf2c35 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -128,9 +128,13 @@
option(
'bmcweb-logging',
- type: 'feature',
+ type: 'combo',
+ choices : [ 'disabled', 'enabled', 'debug', 'info', 'warning', 'error', 'critical' ],
value: 'disabled',
- description: 'Enable output the extended debug logs'
+ description: '''Enable output the extended logging level.
+ - disabled: disable bmcweb log traces.
+ - enabled: treated as 'debug'
+ - For the other logging level option, see DEVELOPING.md.'''
)
option(
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index b13ab27..a7f06b8 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -64,8 +64,6 @@
static int run()
{
- crow::Logger::setLogLevel(crow::LogLevel::Debug);
-
auto io = std::make_shared<boost::asio::io_context>();
App app(io);