commit a32078fd14563ebdfd20ababbecec5b73ddb0dcd
parent d0dae56e4157bc930030e34347dcf08fe79e4c10
Author: Kaleb Luedtke <jluedtk@jci.com>
Date: Wed, 16 Feb 2022 18:41:42 -0600
Setting for Logging Level (#1945)
Diffstat:
6 files changed, 151 insertions(+), 2 deletions(-)
diff --git a/doc/Settings.md b/doc/Settings.md
@@ -106,6 +106,19 @@ See [details on telemetry](../README.md#datatelemetry), and our [primary privacy
If set to true, the `telemetry.disable` setting will prevent any event from being written by the program.
+## Logging
+
+The `logging` settings control the level of detail in log files. `--verbose-logs` will override this setting and always creates a verbose log.
+Defaults to `info` if value is not set or is invalid
+
+### level
+
+```json
+ "logging": {
+ "level": ["verbose", "info", "warning", "error", "critical"]
+ },
+```
+
## Network
The `network` settings influence how winget uses the network to retrieve packages and metadata.
diff --git a/schemas/JSON/settings/settings.schema.0.2.json b/schemas/JSON/settings/settings.schema.0.2.json
@@ -31,6 +31,23 @@
}
}
},
+ "Logging": {
+ "description": "Logging settings",
+ "type": "object",
+ "properties": {
+ "level": {
+ "description": "Preferred logging level",
+ "type": "string",
+ "enum": [
+ "verbose",
+ "info",
+ "warning",
+ "error",
+ "critical"
+ ]
+ }
+ }
+ },
"InstallPrefReq": {
"description": "Shared schema for preferences and requirements",
"type": "object",
@@ -152,6 +169,12 @@
},
{
"properties": {
+ "logging": { "$ref": "#/definitions/Logging" }
+ },
+ "additionalItems": true
+ },
+ {
+ "properties": {
"source": { "$ref": "#/definitions/Source" }
},
"additionalItems": true
diff --git a/src/AppInstallerCLICore/Core.cpp b/src/AppInstallerCLICore/Core.cpp
@@ -66,7 +66,7 @@ namespace AppInstaller::CLI
// Enable all logging for this phase; we will update once we have the arguments
Logging::Log().EnableChannel(Logging::Channel::All);
- Logging::Log().SetLevel(Logging::Level::Info);
+ Logging::Log().SetLevel(Settings::User().Get<Settings::Setting::LoggingLevelPreference>());
Logging::AddFileLogger();
Logging::EnableWilFailureTelemetry();
diff --git a/src/AppInstallerCLITests/UserSettings.cpp b/src/AppInstallerCLITests/UserSettings.cpp
@@ -5,6 +5,7 @@
#include "TestSettings.h"
#include <AppInstallerRuntime.h>
#include <winget/Settings.h>
+#include "AppInstallerLogging.h"
#include <AppInstallerErrors.h>
@@ -13,6 +14,7 @@
#include <chrono>
using namespace AppInstaller::Settings;
+using namespace AppInstaller::Logging;
using namespace AppInstaller::Runtime;
using namespace TestCommon;
using namespace std::string_literals;
@@ -202,6 +204,82 @@ TEST_CASE("SettingProgressBar", "[settings]")
}
}
+TEST_CASE("SettingLoggingLevelPreference", "[settings]")
+{
+ DeleteUserSettingsFiles();
+
+ SECTION("Default value")
+ {
+ UserSettingsTest userSettingTest;
+
+ REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info);
+ REQUIRE(userSettingTest.GetWarnings().size() == 0);
+ }
+ SECTION("Info")
+ {
+ std::string_view json = R"({ "logging": { "level": "info" } })";
+ SetSetting(Stream::PrimaryUserSettings, json);
+ UserSettingsTest userSettingTest;
+
+ REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info);
+ REQUIRE(userSettingTest.GetWarnings().size() == 0);
+ }
+ SECTION("Verbose")
+ {
+ std::string_view json = R"({ "logging": { "level": "verbose" } })";
+ SetSetting(Stream::PrimaryUserSettings, json);
+ UserSettingsTest userSettingTest;
+
+ REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Verbose);
+ REQUIRE(userSettingTest.GetWarnings().size() == 0);
+ }
+ SECTION("Warning")
+ {
+ std::string_view json = R"({ "logging": { "level": "warning" } })";
+ SetSetting(Stream::PrimaryUserSettings, json);
+ UserSettingsTest userSettingTest;
+
+ REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Warning);
+ REQUIRE(userSettingTest.GetWarnings().size() == 0);
+ }
+ SECTION("Error")
+ {
+ std::string_view json = R"({ "logging": { "level": "error" } })";
+ SetSetting(Stream::PrimaryUserSettings, json);
+ UserSettingsTest userSettingTest;
+
+ REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Error);
+ REQUIRE(userSettingTest.GetWarnings().size() == 0);
+ }
+ SECTION("Critical")
+ {
+ std::string_view json = R"({ "logging": { "level": "critical" } })";
+ SetSetting(Stream::PrimaryUserSettings, json);
+ UserSettingsTest userSettingTest;
+
+ REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Crit);
+ REQUIRE(userSettingTest.GetWarnings().size() == 0);
+ }
+ SECTION("Bad value")
+ {
+ std::string_view json = R"({ "logging": { "level": "fake" } })";
+ SetSetting(Stream::PrimaryUserSettings, json);
+ UserSettingsTest userSettingTest;
+
+ REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info);
+ REQUIRE(userSettingTest.GetWarnings().size() == 1);
+ }
+ SECTION("Bad value type")
+ {
+ std::string_view json = R"({ "logging": { "level": 5 } })";
+ SetSetting(Stream::PrimaryUserSettings, json);
+ UserSettingsTest userSettingTest;
+
+ REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info);
+ REQUIRE(userSettingTest.GetWarnings().size() == 1);
+ }
+}
+
TEST_CASE("SettingAutoUpdateIntervalInMinutes", "[settings]")
{
DeleteUserSettingsFiles();
diff --git a/src/AppInstallerCommonCore/Public/winget/UserSettings.h b/src/AppInstallerCommonCore/Public/winget/UserSettings.h
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
#pragma once
#include "AppInstallerStrings.h"
+#include "AppInstallerLogging.h"
#include "winget/GroupPolicy.h"
#include "winget/Resources.h"
@@ -56,7 +57,6 @@ namespace AppInstaller::Settings
DeliveryOptimization,
};
-
// Enum of settings.
// Must start at 0 to enable direct access to variant in UserSettings.
// Max must be last and unused.
@@ -82,6 +82,7 @@ namespace AppInstaller::Settings
InstallLocaleRequirement,
EFDirectMSI,
EnableSelfInitiatedMinidump,
+ LoggingLevelPreference,
Max
};
@@ -131,6 +132,7 @@ namespace AppInstaller::Settings
SETTINGMAPPING_SPECIALIZATION(Setting::InstallLocaleRequirement, std::vector<std::string>, std::vector<std::string>, {}, ".installBehavior.requirements.locale"sv);
SETTINGMAPPING_SPECIALIZATION(Setting::EFDirectMSI, bool, bool, false, ".experimentalFeatures.directMSI"sv);
SETTINGMAPPING_SPECIALIZATION(Setting::EnableSelfInitiatedMinidump, bool, bool, false, ".debugging.enableSelfInitiatedMinidump"sv);
+ SETTINGMAPPING_SPECIALIZATION(Setting::LoggingLevelPreference, std::string, Logging::Level, Logging::Level::Info, ".logging.level"sv);
// Used to deduce the SettingVariant type; making a variant that includes std::monostate and all SettingMapping types.
template <size_t... I>
diff --git a/src/AppInstallerCommonCore/UserSettings.cpp b/src/AppInstallerCommonCore/UserSettings.cpp
@@ -16,6 +16,7 @@ namespace AppInstaller::Settings
using namespace std::string_view_literals;
using namespace Runtime;
using namespace Utility;
+ using namespace Logging;
static constexpr std::string_view s_SettingEmpty =
R"({
@@ -316,6 +317,38 @@ namespace AppInstaller::Settings
{
return std::chrono::seconds(value);
}
+
+ WINGET_VALIDATE_SIGNATURE(LoggingLevelPreference)
+ {
+ // logging preference possible values
+ static constexpr std::string_view s_logging_verbose = "verbose";
+ static constexpr std::string_view s_logging_info = "info";
+ static constexpr std::string_view s_logging_warning = "warning";
+ static constexpr std::string_view s_logging_error = "error";
+ static constexpr std::string_view s_logging_critical = "critical";
+
+ if (Utility::CaseInsensitiveEquals(value, s_logging_verbose))
+ {
+ return Level::Verbose;
+ }
+ else if (Utility::CaseInsensitiveEquals(value, s_logging_info))
+ {
+ return Level::Info;
+ }
+ else if (Utility::CaseInsensitiveEquals(value, s_logging_warning))
+ {
+ return Level::Warning;
+ }
+ else if (Utility::CaseInsensitiveEquals(value, s_logging_error))
+ {
+ return Level::Error;
+ }
+ else if (Utility::CaseInsensitiveEquals(value, s_logging_critical))
+ {
+ return Level::Crit;
+ }
+ return {};
+ }
}
#ifndef AICLI_DISABLE_TEST_HOOKS