Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting for Logging Level #1945

Merged
merged 5 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions doc/Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ 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.
Trenly marked this conversation as resolved.
Show resolved Hide resolved

### level

```json
"logging": {
"level": ["verbose", "info", "warning", "error", "critical"]
},
```

## Network

The `network` settings influence how winget uses the network to retrieve packages and metadata.
Expand Down
23 changes: 23 additions & 0 deletions schemas/JSON/settings/settings.schema.0.2.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -150,6 +167,12 @@
},
"additionalItems": true
},
{
"properties": {
"logging": { "$ref": "#/definitions/Logging" }
},
"additionalItems": true
},
{
"properties": {
"source": { "$ref": "#/definitions/Source" }
Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCLICore/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
78 changes: 78 additions & 0 deletions src/AppInstallerCLITests/UserSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "TestSettings.h"
#include <AppInstallerRuntime.h>
#include <winget/Settings.h>
#include "AppInstallerLogging.h"

#include <AppInstallerErrors.h>

Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 3 additions & 1 deletion src/AppInstallerCommonCore/Public/winget/UserSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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.
Expand All @@ -82,6 +82,7 @@ namespace AppInstaller::Settings
InstallLocaleRequirement,
EFDirectMSI,
EnableSelfInitiatedMinidump,
LoggingLevelPreference,
Max
};

Expand Down Expand Up @@ -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>
Expand Down
33 changes: 33 additions & 0 deletions src/AppInstallerCommonCore/UserSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"({
Expand Down Expand Up @@ -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
Expand Down