winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 0a66b935c728292b03d0e606483ac351cfeddb10
parent f66e3301faa1359e75327d79d36e82dd1b33c17d
Author: JohnMcPMS <johnmcp@microsoft.com>
Date:   Tue, 26 Jul 2022 16:21:38 -0700

Logging improvements (#2378)

Add a connection identifier and log it when opening the connection and with each statement.  This makes it somewhat easier to follow the (extremely) verbose SQLite logging.

Also changes the file logger to append by default, enabling logging to the same file repeatedly a possibility (a util scenario mostly).
Diffstat:
M.github/actions/spelling/expect.txt | 1+
Msrc/AppInstallerCommonCore/FileLogger.cpp | 5+++--
Msrc/AppInstallerRepositoryCore/SQLiteWrapper.cpp | 25+++++++++++++++++++------
Msrc/AppInstallerRepositoryCore/SQLiteWrapper.h | 7++++++-
4 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt @@ -296,6 +296,7 @@ NX objbase objidl ofile +openmode Outptr packageinuse PARAMETERMAP diff --git a/src/AppInstallerCommonCore/FileLogger.cpp b/src/AppInstallerCommonCore/FileLogger.cpp @@ -15,6 +15,7 @@ namespace AppInstaller::Logging static constexpr std::string_view s_fileLoggerDefaultFilePrefix = "WinGet"sv; static constexpr std::string_view s_fileLoggerDefaultFileExt = ".log"sv; + static constexpr std::ios_base::openmode s_fileLoggerDefaultOpenMode = std::ios_base::out | std::ios_base::app; FileLogger::FileLogger() : FileLogger(s_fileLoggerDefaultFilePrefix) {} @@ -23,7 +24,7 @@ namespace AppInstaller::Logging m_name = GetNameForPath(filePath); m_filePath = filePath; - m_stream.open(m_filePath); + m_stream.open(m_filePath, s_fileLoggerDefaultOpenMode); } FileLogger::FileLogger(const std::string_view fileNamePrefix) @@ -32,7 +33,7 @@ namespace AppInstaller::Logging m_filePath = Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation); m_filePath /= fileNamePrefix.data() + ('-' + Utility::GetCurrentTimeForFilename() + s_fileLoggerDefaultFileExt.data()); - m_stream.open(m_filePath); + m_stream.open(m_filePath, s_fileLoggerDefaultOpenMode); } FileLogger::~FileLogger() diff --git a/src/AppInstallerRepositoryCore/SQLiteWrapper.cpp b/src/AppInstallerRepositoryCore/SQLiteWrapper.cpp @@ -37,6 +37,12 @@ namespace AppInstaller::Repository::SQLite namespace { + size_t GetNextConnectionId() + { + static std::atomic_size_t connectionId(0); + return ++connectionId; + } + size_t GetNextStatementId() { static std::atomic_size_t statementId(0); @@ -141,7 +147,8 @@ namespace AppInstaller::Repository::SQLite Connection::Connection(const std::string& target, OpenDisposition disposition, OpenFlags flags) { - AICLI_LOG(SQL, Info, << "Opening SQLite connection: '" << target << "' [" << std::hex << static_cast<int>(disposition) << ", " << std::hex << static_cast<int>(flags) << "]"); + m_id = GetNextConnectionId(); + AICLI_LOG(SQL, Info, << "Opening SQLite connection #" << m_id << ": '" << target << "' [" << std::hex << static_cast<int>(disposition) << ", " << std::hex << static_cast<int>(flags) << "]"); // Always force connection serialization until we determine that there are situations where it is not needed int resultingFlags = static_cast<int>(disposition) | static_cast<int>(flags) | SQLITE_OPEN_FULLMUTEX; THROW_IF_SQLITE_FAILED(sqlite3_open_v2(target.c_str(), &m_dbconn, resultingFlags, nullptr), nullptr); @@ -172,10 +179,16 @@ namespace AppInstaller::Repository::SQLite return sqlite3_changes(m_dbconn.get()); } + size_t Connection::GetID() const + { + return m_id; + } + Statement::Statement(const Connection& connection, std::string_view sql) { + m_connectionId = connection.GetID(); m_id = GetNextStatementId(); - AICLI_LOG(SQL, Verbose, << "Preparing statement #" << m_id << ": " << sql); + AICLI_LOG(SQL, Verbose, << "Preparing statement #" << m_connectionId << '-' << m_id << ": " << sql); // SQL string size should include the null terminator (https://www.sqlite.org/c3ref/prepare.html) assert(sql.data()[sql.size()] == '\0'); THROW_IF_SQLITE_FAILED(sqlite3_prepare_v2(connection, sql.data(), static_cast<int>(sql.size() + 1), &m_stmt, nullptr), connection); @@ -241,18 +254,18 @@ namespace AppInstaller::Repository::SQLite bool Statement::Step(bool failFastOnError) { - AICLI_LOG(SQL, Verbose, << "Stepping statement #" << m_id); + AICLI_LOG(SQL, Verbose, << "Stepping statement #" << m_connectionId << '-' << m_id); int result = sqlite3_step(m_stmt.get()); if (result == SQLITE_ROW) { - AICLI_LOG(SQL, Verbose, << "Statement #" << m_id << " has data"); + AICLI_LOG(SQL, Verbose, << "Statement #" << m_connectionId << '-' << m_id << " has data"); m_state = State::HasRow; return true; } else if (result == SQLITE_DONE) { - AICLI_LOG(SQL, Verbose, << "Statement #" << m_id << " has completed"); + AICLI_LOG(SQL, Verbose, << "Statement #" << m_connectionId << '-' << m_id << " has completed"); m_state = State::Completed; return false; } @@ -283,7 +296,7 @@ namespace AppInstaller::Repository::SQLite void Statement::Reset() { - AICLI_LOG(SQL, Verbose, << "Reset statement #" << m_id); + AICLI_LOG(SQL, Verbose, << "Reset statement #" << m_connectionId << '-' << m_id); // Ignore return value from reset, as if it is an error, it was the error from the last call to step. sqlite3_reset(m_stmt.get()); m_state = State::Prepared; diff --git a/src/AppInstallerRepositoryCore/SQLiteWrapper.h b/src/AppInstallerRepositoryCore/SQLiteWrapper.h @@ -177,11 +177,15 @@ namespace AppInstaller::Repository::SQLite // Gets the count of changed rows for the last executed statement. int GetChanges() const; + //. Gets the (fixed but arbitrary) identifier for this connection. + size_t GetID() const; + operator sqlite3* () const { return m_dbconn.get(); } private: Connection(const std::string& target, OpenDisposition disposition, OpenFlags flags); + size_t m_id = 0; wil::unique_any<sqlite3*, decltype(sqlite3_close_v2), sqlite3_close_v2> m_dbconn; }; @@ -223,7 +227,7 @@ namespace AppInstaller::Repository::SQLite template <typename Value> void Bind(int index, Value&& v) { - AICLI_LOG(SQL, Verbose, << "Binding statement #" << m_id << ": " << index << " => " << details::ParameterSpecifics<Value>::ToLog(std::forward<Value>(v))); + AICLI_LOG(SQL, Verbose, << "Binding statement #" << m_connectionId << '-' << m_id << ": " << index << " => " << details::ParameterSpecifics<Value>::ToLog(std::forward<Value>(v))); details::ParameterSpecifics<Value>::Bind(m_stmt.get(), index, std::forward<Value>(v)); } @@ -278,6 +282,7 @@ namespace AppInstaller::Repository::SQLite return std::make_tuple(details::ParameterSpecifics<Values>::GetColumn(m_stmt.get(), I)...); } + size_t m_connectionId = 0; size_t m_id = 0; wil::unique_any<sqlite3_stmt*, decltype(sqlite3_finalize), sqlite3_finalize> m_stmt; State m_state = State::Prepared;