From c6545725fc09ea7ad6ac0e30f80f3b2597c0171e Mon Sep 17 00:00:00 2001 From: Olasoji Denloye Date: Fri, 8 May 2026 13:58:58 -0700 Subject: [PATCH] logging: add LOG_DEBUG level; qat: map log level to QATzip log level (#56) * Adds test to validate log_stats_samples config Signed-off-by: Olasoji * Reduces excessive error logging in QAT mode Signed-off-by: Olasoji * Bugfix for the log stream Signed-off-by: Olasoji * Treats QPL_STS_MORE_OUTPUT_NEEDED as a non error condition for IAA Signed-off-by: Olasoji * Fixed formatting Signed-off-by: Olasoji * - Modifies iaa behavior so that when QPL_STS_MORE_OUTPUT_NEEDED is returned eos isnt erronously set. Signed-off-by: Olasoji * -Adds proper formatting Signed-off-by: Olasoji * logging: add LOG_DEBUG level; qat: map log level to QATzip log level Introduce LOG_DEBUG (value=1) as the most verbose log level, shifting LOG_INFO to 2 and LOG_ERROR to 3. This follows the conventional ordering used by syslog, Log4j, Python logging, and QATzip itself (where higher values mean more verbose). The default log level remains LOG_ERROR (now value=3), so existing deployments see no behavioral change unless they explicitly set a lower value in /etc/zlib-accel.conf. The config parser max for log_level is updated from 2 to 3 accordingly. In qat.cpp, replace the hardcoded qzSetLogLevel(LOG_NONE) with a dynamic mapping from the configured log_level: LOG_DEBUG -> LOG_DEBUG3 (maximum QATzip verbosity) LOG_INFO -> LOG_INFO LOG_ERROR -> LOG_ERROR default -> LOG_NONE This corrects an inversion present in PR #55 of intel/zlib-accel, where LOG_ERROR was incorrectly mapped to LOG_DEBUG3. New tests: LogDebugLevel, LogDebugFilteredByInfo; LogLevelFiltering extended to cover DEBUG filtering. Builds on: intel/zlib-accel#55 Signed-off-by: Olasoji * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * qat: gate qzSetLogLevel mapping behind DEBUG_LOG; apply formatting Without the DEBUG_LOG guard, a release build (DEBUG_LOG=OFF) with a non-zero log_level in the config would cause QATzip to emit verbose output, contradicting the documented behaviour that log_level only applies when built with DEBUG_LOG=ON. Gate the dynamic mapping behind #ifdef DEBUG_LOG and unconditionally set LOG_NONE in the else branch, matching the original behaviour for non-debug builds. Addresses Copilot review comment on PR #56. Signed-off-by: Olasoji * address review comments: enum ordering, call_once, explicit LOG_NONE case - logging.h: reorder LogLevel enum to match QATzip's QzLogLevel_T convention {LOG_NONE=0, LOG_ERROR=1, LOG_INFO=2, LOG_DEBUG=3}; flip filter direction from 'level < config' to 'level > config' so higher values = more verbose. Apply same fix to PrintDeflateBlockHeader. - qat.cpp: call qzSetLogLevel once per process via std::call_once instead of per session; add explicit case LogLevel::LOG_NONE; move default to end with comment; restructure #ifdef to be inside the once lambda. - config/config.cpp, config/default_config: update default log_level from 3 to 1 (LOG_ERROR = errors only, matching previous error-only default). - README.md: update log_level documentation to describe new ordering. - tests/zlib_accel_test.cpp: update expected log_level default to 1. --------- Signed-off-by: Olasoji Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- README.md | 5 ++-- config/config.cpp | 4 ++-- config/default_config | 2 +- logging.h | 16 ++++++++++--- qat.cpp | 32 ++++++++++++++++++++++++- tests/logging_test.cpp | 50 +++++++++++++++++++++++++++++++++++---- tests/zlib_accel_test.cpp | 2 +- 7 files changed, 97 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b36a23b..4ed2712 100644 --- a/README.md +++ b/README.md @@ -212,9 +212,10 @@ ignore_zlib_dictionary - If set to 0, zlib-accel honors inflateSetDictionary and deflateSetDictionary. log_level -- Values: 0,1,2. Default 2 +- Values: 0,1,2,3. Default: 1 - This option applies only if the shim is built with DEBUG_LOG=ON. -- If 1, error and info log messages are shown. If 2, only error log messages are shown. If 0, no log messages are shown. +- Matches QATzip's verbosity convention: 0 = silent, 1 = errors only, 2 = info and errors, 3 = debug, info, and errors (most verbose). +- Migration note: the numeric meanings changed from earlier versions. Older configurations that used `log_level=2` for error-only output must now use `log_level=1`. Review existing `log_level` settings when upgrading. log_stats_samples - Values: 0-INT_MAX. Default 1000 diff --git a/config/config.cpp b/config/config.cpp index 29f93cf..aefe066 100644 --- a/config/config.cpp +++ b/config/config.cpp @@ -28,7 +28,7 @@ uint32_t configs[CONFIG_MAX] = { 1, /*qat_compression_level*/ 0, /*qat_compression_allow_chunking*/ 0, /*ignore_zlib_dictionary*/ - 2, /*log_level*/ + 1, /*log_level*/ 1000 /*log_stats_samples*/ }; @@ -85,7 +85,7 @@ bool LoadConfigFile(std::string& file_content, const char* file_path) { trySetConfig(QAT_COMPRESSION_LEVEL, 9, 1); trySetConfig(QAT_COMPRESSION_ALLOW_CHUNKING, 1, 0); trySetConfig(IGNORE_ZLIB_DICTIONARY, 1, 0); - trySetConfig(LOG_LEVEL, 2, 0); + trySetConfig(LOG_LEVEL, 3, 0); trySetConfig(LOG_STATS_SAMPLES, UINT32_MAX, 0); config_reader.GetValue("log_file", log_file); diff --git a/config/default_config b/config/default_config index 6ae0cc8..827b7b2 100644 --- a/config/default_config +++ b/config/default_config @@ -11,5 +11,5 @@ qat_periodical_polling = 0 qat_compression_level = 1 qat_compression_allow_chunking = 0 ignore_zlib_dictionary = 0 -log_level = 2 +log_level = 1 log_file = /tmp/zlib-accel.log diff --git a/logging.h b/logging.h index b5e8301..d384cdb 100644 --- a/logging.h +++ b/logging.h @@ -15,7 +15,14 @@ using namespace config; -enum class LogLevel { LOG_NONE = 0, LOG_INFO = 1, LOG_ERROR = 2 }; +// Log verbosity levels. 0 = silent; higher values = more verbose. +// Matches QATzip's QzLogLevel_T convention. +enum class LogLevel { + LOG_NONE = 0, + LOG_ERROR = 1, + LOG_INFO = 2, + LOG_DEBUG = 3 +}; #if defined(DEBUG_LOG) || defined(ENABLE_STATISTICS) @@ -56,7 +63,7 @@ inline void Log(LogLevel level, Args&&... args) { return; } - if (static_cast(level) < current_level) { + if (static_cast(level) > current_level) { return; } @@ -69,6 +76,9 @@ inline void Log(LogLevel level, Args&&... args) { case LogLevel::LOG_INFO: stream << "Info: "; break; + case LogLevel::LOG_DEBUG: + stream << "Debug: "; + break; case LogLevel::LOG_NONE: return; } @@ -105,7 +115,7 @@ inline void PrintDeflateBlockHeader(LogLevel level, uint8_t* data, uint32_t len, return; } - if (static_cast(level) < current_level) { + if (static_cast(level) > current_level) { return; } diff --git a/qat.cpp b/qat.cpp index d5bc57e..e897479 100644 --- a/qat.cpp +++ b/qat.cpp @@ -99,8 +99,38 @@ void QATJob::Init(QzSessionPtr &qzSession, CompressedFormat format, return; } + // Map zlib-accel log level to QATzip log level. + // qzSetLogLevel is a QATzip global; call it once per process regardless + // of how many QAT sessions are created. + static std::once_flag qz_log_level_flag; + std::call_once(qz_log_level_flag, []() { + QzLogLevel_T qzLogLevel = LOG_NONE; +#ifdef DEBUG_LOG + LogLevel logLevel = + static_cast(config::GetConfig(config::LOG_LEVEL)); + switch (logLevel) { + case LogLevel::LOG_NONE: + qzLogLevel = LOG_NONE; + break; + case LogLevel::LOG_ERROR: + qzLogLevel = LOG_ERROR; + break; + case LogLevel::LOG_INFO: + qzLogLevel = LOG_INFO; + break; + case LogLevel::LOG_DEBUG: + qzLogLevel = LOG_DEBUG3; + break; + default: + // Unreachable: all LogLevel values are handled above. + qzLogLevel = LOG_NONE; + break; + } +#endif + qzSetLogLevel(qzLogLevel); + }); + // Initialize QAT hardware - qzSetLogLevel(LOG_NONE); int status = qzInit(session.get(), 0); if (status != QZ_OK && status != QZ_DUPLICATE) { Log(LogLevel::LOG_ERROR, "qzInit() failure Line ", __LINE__, " session ", diff --git a/tests/logging_test.cpp b/tests/logging_test.cpp index b359208..c00f7e1 100644 --- a/tests/logging_test.cpp +++ b/tests/logging_test.cpp @@ -152,6 +152,46 @@ TEST_F(LoggingTest, LogErrorLevel) { EXPECT_NE(c.find("error occurred"), std::string::npos); } +/** + * @test Verifies that DEBUG-level messages appear when LOG_LEVEL=DEBUG. + */ +TEST_F(LoggingTest, LogDebugLevel) { + CreateLogFile(test_log_file.c_str()); + config::SetConfig(config::LOG_LEVEL, + static_cast(LogLevel::LOG_DEBUG)); + + Log(LogLevel::LOG_DEBUG, "debug message"); + CloseLogFile(); + + std::ifstream f(test_log_file); + std::string c((std::istreambuf_iterator(f)), + std::istreambuf_iterator()); + + EXPECT_NE(c.find("Debug:"), std::string::npos); + EXPECT_NE(c.find("debug message"), std::string::npos); +} + +/** + * @test Verifies that DEBUG-level messages are filtered out when + * LOG_LEVEL=INFO. + */ +TEST_F(LoggingTest, LogDebugFilteredByInfo) { + CreateLogFile(test_log_file.c_str()); + config::SetConfig(config::LOG_LEVEL, + static_cast(LogLevel::LOG_INFO)); + + Log(LogLevel::LOG_DEBUG, "filtered debug"); // Should NOT appear + Log(LogLevel::LOG_INFO, "visible info"); // Should appear + CloseLogFile(); + + std::ifstream f(test_log_file); + std::string c((std::istreambuf_iterator(f)), + std::istreambuf_iterator()); + + EXPECT_EQ(c.find("filtered debug"), std::string::npos); + EXPECT_NE(c.find("visible info"), std::string::npos); +} + /** * @test Verifies that LOG_NONE prevents any message from being logged. */ @@ -191,7 +231,7 @@ TEST_F(LoggingTest, LogMultipleArguments) { /** * @test Validates that log-level filtering works correctly: - * - INFO log should be filtered out under LOG_ERROR + * - DEBUG and INFO logs should be filtered out under LOG_ERROR * - ERROR log should appear. */ TEST_F(LoggingTest, LogLevelFiltering) { @@ -199,15 +239,17 @@ TEST_F(LoggingTest, LogLevelFiltering) { config::SetConfig(config::LOG_LEVEL, static_cast(LogLevel::LOG_ERROR)); - Log(LogLevel::LOG_INFO, "filtered"); // Should NOT appear - Log(LogLevel::LOG_ERROR, "visible"); // Should appear + Log(LogLevel::LOG_DEBUG, "filtered debug"); // Should NOT appear + Log(LogLevel::LOG_INFO, "filtered info"); // Should NOT appear + Log(LogLevel::LOG_ERROR, "visible"); // Should appear CloseLogFile(); std::ifstream f(test_log_file); std::string c((std::istreambuf_iterator(f)), std::istreambuf_iterator()); - EXPECT_EQ(c.find("filtered"), std::string::npos); + EXPECT_EQ(c.find("filtered debug"), std::string::npos); + EXPECT_EQ(c.find("filtered info"), std::string::npos); EXPECT_NE(c.find("visible"), std::string::npos); } diff --git a/tests/zlib_accel_test.cpp b/tests/zlib_accel_test.cpp index c8ec0ce..61a7189 100644 --- a/tests/zlib_accel_test.cpp +++ b/tests/zlib_accel_test.cpp @@ -1274,7 +1274,7 @@ TEST_F(ConfigLoaderTest, LoadValidConfig) { EXPECT_EQ(GetConfig(USE_IAA_UNCOMPRESS), 0); EXPECT_EQ(GetConfig(USE_ZLIB_COMPRESS), 1); EXPECT_EQ(GetConfig(USE_ZLIB_UNCOMPRESS), 1); - EXPECT_EQ(GetConfig(LOG_LEVEL), 2); + EXPECT_EQ(GetConfig(LOG_LEVEL), 1); LoadConfigFile(file_content); }