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

Add ODS logger and use it during init #4969

Merged
merged 2 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions src/AppInstallerCLICore/COMContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "COMContext.h"
#include <AppInstallerFileLogger.h>
#include <winget/TraceLogger.h>
#include <winget/OutputDebugStringLogger.h>

namespace AppInstaller::CLI::Execution
{
Expand Down Expand Up @@ -77,12 +78,19 @@ namespace AppInstaller::CLI::Execution

void COMContext::SetLoggers(std::optional<AppInstaller::Logging::Channel> channel, std::optional<AppInstaller::Logging::Level> level)
{
// Set up debug string logging during initialization
Logging::OutputDebugStringLogger::Add();
Logging::Log().EnableChannel(Logging::Channel::All);
Logging::Log().SetLevel(Logging::Level::Verbose);

Logging::Log().EnableChannel(channel.has_value() ? channel.value() : Settings::User().Get<Settings::Setting::LoggingChannelPreference>());
Logging::Log().SetLevel(level.has_value() ? level.value() : Settings::User().Get<Settings::Setting::LoggingLevelPreference>());

// TODO: Log to file for COM API calls only when debugging in visual studio
Logging::FileLogger::Add(s_comLogFileNamePrefix);

Logging::OutputDebugStringLogger::Remove();

#ifndef AICLI_DISABLE_TEST_HOOKS
if (!Settings::User().Get<Settings::Setting::KeepAllLogFiles>())
#endif
Expand Down
44 changes: 36 additions & 8 deletions src/AppInstallerCLICore/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "Commands/InstallCommand.h"
#include "COMContext.h"
#include <AppInstallerFileLogger.h>
#include <winget/OutputDebugStringLogger.h>

#ifndef AICLI_DISABLE_TEST_HOOKS
#include <winget/Debugging.h>
Expand Down Expand Up @@ -66,21 +67,34 @@ namespace AppInstaller::CLI

init_apartment();

#ifndef AICLI_DISABLE_TEST_HOOKS
#ifndef AICLI_DISABLE_TEST_HOOKS
// We have to do this here so the auto minidump config initialization gets caught
Logging::OutputDebugStringLogger::Add();
Logging::Log().EnableChannel(Logging::Channel::All);
Logging::Log().SetLevel(Logging::Level::Verbose);

if (Settings::User().Get<Settings::Setting::EnableSelfInitiatedMinidump>())
{
Debugging::EnableSelfInitiatedMinidump();
}
}

Logging::OutputDebugStringLogger::Remove();
#endif

Logging::UseGlobalTelemetryLoggerActivityIdOnly();

Execution::Context context{ std::cout, std::cin };
auto previousThreadGlobals = context.SetForCurrentThread();
auto previousThreadGlobals = context.SetForCurrentThread();

// Set up debug string logging during initialization
Logging::OutputDebugStringLogger::Add();
Comment on lines +81 to +90
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why we have to remove the ODS logger only to add it immediately after. Couldn't we just add it before the #ifndef and remove it once in line 97?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first one is added to the global logger, while the second one is added to the context logger.

Logging::Log().EnableChannel(Logging::Channel::All);
Logging::Log().SetLevel(Logging::Level::Verbose);

Logging::Log().EnableChannel(Settings::User().Get<Settings::Setting::LoggingChannelPreference>());
Logging::Log().SetLevel(Settings::User().Get<Settings::Setting::LoggingLevelPreference>());
Logging::FileLogger::Add();
Logging::FileLogger::Add();
Logging::OutputDebugStringLogger::Remove();
Logging::EnableWilFailureTelemetry();

// Set output to UTF8
Expand Down Expand Up @@ -171,23 +185,37 @@ namespace AppInstaller::CLI

void ServerInitialize()
{
#ifndef AICLI_DISABLE_TEST_HOOKS
#ifndef AICLI_DISABLE_TEST_HOOKS
// We have to do this here so the auto minidump config initialization gets caught
Logging::OutputDebugStringLogger::Add();
Logging::Log().EnableChannel(Logging::Channel::All);
Logging::Log().SetLevel(Logging::Level::Verbose);

if (Settings::User().Get<Settings::Setting::EnableSelfInitiatedMinidump>())
{
Debugging::EnableSelfInitiatedMinidump();
}
}

Logging::OutputDebugStringLogger::Remove();
#endif

AppInstaller::CLI::Execution::COMContext::SetLoggers();
}

void InProcInitialize()
{
#ifndef AICLI_DISABLE_TEST_HOOKS
#ifndef AICLI_DISABLE_TEST_HOOKS
// We have to do this here so the auto minidump config initialization gets caught
Logging::OutputDebugStringLogger::Add();
Logging::Log().EnableChannel(Logging::Channel::All);
Logging::Log().SetLevel(Logging::Level::Verbose);

if (Settings::User().Get<Settings::Setting::EnableSelfInitiatedMinidump>())
{
Debugging::EnableSelfInitiatedMinidump();
}
}

Logging::OutputDebugStringLogger::Remove();
#endif

// Explicitly set default channel and level before user settings from PackageManagerSettings
Expand Down
2 changes: 2 additions & 0 deletions src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@
</ClInclude>
<ClInclude Include="Public\winget\NameNormalization.h" />
<ClInclude Include="Public\winget\NetworkSettings.h" />
<ClInclude Include="Public\winget\OutputDebugStringLogger.h" />
<ClInclude Include="Public\winget\PackageDependenciesValidationUtil.h" />
<ClInclude Include="Public\winget\PackageVersionDataManifest.h" />
<ClInclude Include="Public\winget\Pin.h" />
Expand Down Expand Up @@ -504,6 +505,7 @@
</ClCompile>
<ClCompile Include="NameNormalization.cpp" />
<ClCompile Include="NetworkSettings.cpp" />
<ClCompile Include="OutputDebugStringLogger.cpp" />
<ClCompile Include="PackageDependenciesValidationUtil.cpp" />
<ClCompile Include="PackageVersionDataManifest.cpp" />
<ClCompile Include="Pin.cpp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@
<ClInclude Include="Public\winget\Fonts.h">
<Filter>Public\winget</Filter>
</ClInclude>
<ClInclude Include="Public\winget\OutputDebugStringLogger.h">
<Filter>Public\winget</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
Expand Down Expand Up @@ -374,6 +377,9 @@
<ClCompile Include="Fonts.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OutputDebugStringLogger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="PropertySheet.props" />
Expand Down
50 changes: 50 additions & 0 deletions src/AppInstallerCommonCore/OutputDebugStringLogger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"
#include "winget/OutputDebugStringLogger.h"

namespace AppInstaller::Logging
{
namespace
{
static constexpr std::string_view s_OutputDebugStringLoggerName = "OutputDebugStringLogger";
}

std::string OutputDebugStringLogger::GetName() const
{
return std::string{ s_OutputDebugStringLoggerName };
}

void OutputDebugStringLogger::Write(Channel channel, Level, std::string_view message) noexcept try
{
std::stringstream strstr;
strstr << "[" << std::setw(GetMaxChannelNameLength()) << std::left << std::setfill(' ') << GetChannelName(channel) << "] " << message << std::endl;
std::string formattedMessage = std::move(strstr).str();

OutputDebugStringA(formattedMessage.c_str());
}
catch (...)
{
// Just eat any exceptions here; better than losing logs
}

void OutputDebugStringLogger::WriteDirect(Channel, Level, std::string_view message) noexcept try
{
std::string nullTerminatedMessage{ message };
OutputDebugStringA(nullTerminatedMessage.c_str());
}
catch (...)
{
// Just eat any exceptions here; better than losing logs
}

void OutputDebugStringLogger::Add()
{
Log().AddLogger(std::make_unique<OutputDebugStringLogger>());
}

void OutputDebugStringLogger::Remove()
{
Log().RemoveLogger(std::string{ s_OutputDebugStringLoggerName });
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma once
#include <AppInstallerLogging.h>

namespace AppInstaller::Logging
{
// Sends logs to the OutputDebugString function.
// Intended for use during initialization debugging.
struct OutputDebugStringLogger : ILogger
{
OutputDebugStringLogger() = default;

~OutputDebugStringLogger() = default;

// ILogger
std::string GetName() const override;

void Write(Channel channel, Level, std::string_view message) noexcept override;

void WriteDirect(Channel channel, Level level, std::string_view message) noexcept override;

// Adds OutputDebugStringLogger to the current Log
static void Add();

// Removes OutputDebugStringLogger from the current Log
static void Remove();
};
}
Loading