From 650bb43f8d575cc4e302180e4234ed585de6ee16 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 8 Nov 2024 16:21:49 -0800 Subject: [PATCH 01/35] SNOW-834781: Remove log4net and delegate logging to consumers --- Snowflake.Data/Client/SnowflakeDbCommand.cs | 35 ++-- .../Client/SnowflakeDbConnection.cs | 49 ++--- .../Client/SnowflakeDbConnectionPool.cs | 39 ++-- .../Client/SnowflakeDbDataReader.cs | 5 +- .../Client/SnowflakeDbTransaction.cs | 15 +- .../Configuration/EasyLoggingConfigFinder.cs | 118 ----------- .../Configuration/EasyLoggingConfigParser.cs | 84 -------- .../EasyLoggingConfigProvider.cs | 31 --- .../Configuration/EasyLoggingLogLevel.cs | 26 --- Snowflake.Data/Core/ArrowResultSet.cs | 11 +- .../Core/Authenticator/BasicAuthenticator.cs | 3 +- .../ExternalBrowserAuthenticator.cs | 33 +-- .../Core/Authenticator/IAuthenticator.cs | 11 +- .../Authenticator/KeyPairAuthenticator.cs | 10 +- .../Core/Authenticator/OAuthAuthenticator.cs | 5 +- .../Core/Authenticator/OktaAuthenticator.cs | 57 ++--- Snowflake.Data/Core/ChunkDownloaderFactory.cs | 7 +- Snowflake.Data/Core/ChunkParserFactory.cs | 7 +- .../StructuredTypesReadingHandler.cs | 7 +- Snowflake.Data/Core/FastParser.cs | 11 +- .../Core/FileTransfer/EncryptionProvider.cs | 5 +- .../Core/FileTransfer/SFFileTransferAgent.cs | 57 ++--- .../FileTransfer/StorageClient/SFGCSClient.cs | 17 +- .../FileTransfer/StorageClient/SFS3Client.cs | 11 +- .../StorageClient/SFSnowflakeAzureClient.cs | 5 +- Snowflake.Data/Core/HttpUtil.cs | 33 +-- Snowflake.Data/Core/QueryContextCache.cs | 27 +-- Snowflake.Data/Core/QueryResultsAwaiter.cs | 11 +- Snowflake.Data/Core/RestRequester.cs | 9 +- Snowflake.Data/Core/SFBindUploader.cs | 9 +- .../Core/SFBlockingChunkDownloaderV3.cs | 11 +- .../Core/SFMultiStatementsResultSet.cs | 3 +- Snowflake.Data/Core/SFResultSet.cs | 11 +- Snowflake.Data/Core/SFResultSetMetaData.cs | 5 +- Snowflake.Data/Core/SFStatement.cs | 41 ++-- .../Core/Session/ConnectionPoolManager.cs | 27 +-- .../Core/Session/EasyLoggingStarter.cs | 195 ------------------ Snowflake.Data/Core/Session/SFSession.cs | 73 +++---- .../Session/SFSessionHttpClientProperties.cs | 27 +-- .../Core/Session/SFSessionProperty.cs | 35 ++-- Snowflake.Data/Core/Session/SessionPool.cs | 91 ++++---- ...ionPropertiesWithDefaultValuesExtractor.cs | 13 +- Snowflake.Data/Core/Tools/Diagnostics.cs | 5 +- .../Core/Tools/EnvironmentOperations.cs | 5 +- .../Core/Tools/HomeDirectoryProvider.cs | 7 +- Snowflake.Data/Logger/EasyLoggerManager.cs | 137 ------------ .../Logger/EasyLoggingLevelMapper.cs | 29 --- Snowflake.Data/Logger/Log4netImpl.cs | 78 ------- Snowflake.Data/Logger/SFLogger.cs | 39 ---- Snowflake.Data/Logger/SFLoggerEmptyImpl.cs | 50 +---- Snowflake.Data/Logger/SFLoggerFactory.cs | 30 +-- Snowflake.Data/Snowflake.Data.csproj | 4 +- 52 files changed, 464 insertions(+), 1200 deletions(-) delete mode 100644 Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs delete mode 100644 Snowflake.Data/Configuration/EasyLoggingConfigParser.cs delete mode 100644 Snowflake.Data/Configuration/EasyLoggingConfigProvider.cs delete mode 100644 Snowflake.Data/Configuration/EasyLoggingLogLevel.cs delete mode 100644 Snowflake.Data/Core/Session/EasyLoggingStarter.cs delete mode 100644 Snowflake.Data/Logger/EasyLoggerManager.cs delete mode 100644 Snowflake.Data/Logger/EasyLoggingLevelMapper.cs delete mode 100755 Snowflake.Data/Logger/Log4netImpl.cs delete mode 100755 Snowflake.Data/Logger/SFLogger.cs diff --git a/Snowflake.Data/Client/SnowflakeDbCommand.cs b/Snowflake.Data/Client/SnowflakeDbCommand.cs index b52d53643..4d5c6b61b 100755 --- a/Snowflake.Data/Client/SnowflakeDbCommand.cs +++ b/Snowflake.Data/Client/SnowflakeDbCommand.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Client { @@ -22,13 +23,13 @@ public class SnowflakeDbCommand : DbCommand private SnowflakeDbParameterCollection parameterCollection; - private SFLogger logger = SFLoggerFactory.GetLogger(); + private ILogger logger = SFLoggerFactory.GetLogger(); private readonly QueryResultsAwaiter _queryResultsAwaiter = QueryResultsAwaiter.Instance; public SnowflakeDbCommand() { - logger.Debug("Constructing SnowflakeDbCommand class"); + logger.LogDebug("Constructing SnowflakeDbCommand class"); // by default, no query timeout this.CommandTimeout = 0; parameterCollection = new SnowflakeDbParameterCollection(); @@ -165,7 +166,7 @@ public override void Cancel() public override int ExecuteNonQuery() { - logger.Debug($"ExecuteNonQuery"); + logger.LogDebug($"ExecuteNonQuery"); SFBaseResultSet resultSet = ExecuteInternal(); long total = 0; do @@ -190,7 +191,7 @@ public override int ExecuteNonQuery() public override async Task ExecuteNonQueryAsync(CancellationToken cancellationToken) { - logger.Debug($"ExecuteNonQueryAsync"); + logger.LogDebug($"ExecuteNonQueryAsync"); cancellationToken.ThrowIfCancellationRequested(); var resultSet = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -217,7 +218,7 @@ public override async Task ExecuteNonQueryAsync(CancellationToken cancellat public override object ExecuteScalar() { - logger.Debug($"ExecuteScalar"); + logger.LogDebug($"ExecuteScalar"); SFBaseResultSet resultSet = ExecuteInternal(); if(resultSet.Next()) @@ -228,7 +229,7 @@ public override object ExecuteScalar() public override async Task ExecuteScalarAsync(CancellationToken cancellationToken) { - logger.Debug($"ExecuteScalarAsync"); + logger.LogDebug($"ExecuteScalarAsync"); cancellationToken.ThrowIfCancellationRequested(); var result = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -263,14 +264,14 @@ protected override DbParameter CreateDbParameter() protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) { - logger.Debug($"ExecuteDbDataReader"); + logger.LogDebug($"ExecuteDbDataReader"); SFBaseResultSet resultSet = ExecuteInternal(); return new SnowflakeDbDataReader(this, resultSet); } protected override async Task ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) { - logger.Debug($"ExecuteDbDataReaderAsync"); + logger.LogDebug($"ExecuteDbDataReaderAsync"); try { var result = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -278,7 +279,7 @@ protected override async Task ExecuteDbDataReaderAsync(CommandBeha } catch (Exception ex) { - logger.Error("The command failed to execute.", ex); + logger.LogError("The command failed to execute.", ex); throw; } } @@ -290,7 +291,7 @@ protected override async Task ExecuteDbDataReaderAsync(CommandBeha /// The query id. public string ExecuteInAsyncMode() { - logger.Debug($"ExecuteInAsyncMode"); + logger.LogDebug($"ExecuteInAsyncMode"); SFBaseResultSet resultSet = ExecuteInternal(asyncExec: true); return resultSet.queryId; } @@ -303,7 +304,7 @@ public string ExecuteInAsyncMode() /// The query id. public async Task ExecuteAsyncInAsyncMode(CancellationToken cancellationToken) { - logger.Debug($"ExecuteAsyncInAsyncMode"); + logger.LogDebug($"ExecuteAsyncInAsyncMode"); var resultSet = await ExecuteInternalAsync(cancellationToken, asyncExec: true).ConfigureAwait(false); return resultSet.queryId; } @@ -315,7 +316,7 @@ public async Task ExecuteAsyncInAsyncMode(CancellationToken cancellation /// The query status. public QueryStatus GetQueryStatus(string queryId) { - logger.Debug($"GetQueryStatus"); + logger.LogDebug($"GetQueryStatus"); return _queryResultsAwaiter.GetQueryStatus(connection, queryId); } @@ -327,7 +328,7 @@ public QueryStatus GetQueryStatus(string queryId) /// The query status. public async Task GetQueryStatusAsync(string queryId, CancellationToken cancellationToken) { - logger.Debug($"GetQueryStatusAsync"); + logger.LogDebug($"GetQueryStatusAsync"); return await _queryResultsAwaiter.GetQueryStatusAsync(connection, queryId, cancellationToken); } @@ -338,7 +339,7 @@ public async Task GetQueryStatusAsync(string queryId, CancellationT /// The query results. public DbDataReader GetResultsFromQueryId(string queryId) { - logger.Debug($"GetResultsFromQueryId"); + logger.LogDebug($"GetResultsFromQueryId"); Task task = _queryResultsAwaiter.RetryUntilQueryResultIsAvailable(connection, queryId, CancellationToken.None, false); task.Wait(); @@ -356,7 +357,7 @@ public DbDataReader GetResultsFromQueryId(string queryId) /// The query results. public async Task GetResultsFromQueryIdAsync(string queryId, CancellationToken cancellationToken) { - logger.Debug($"GetResultsFromQueryIdAsync"); + logger.LogDebug($"GetResultsFromQueryIdAsync"); await _queryResultsAwaiter.RetryUntilQueryResultIsAvailable(connection, queryId, cancellationToken, true); @@ -464,7 +465,7 @@ private void CheckIfCommandTextIsSet() if (string.IsNullOrEmpty(CommandText)) { var errorMessage = "Unable to execute command due to command text not being set"; - logger.Error(errorMessage); + logger.LogError(errorMessage); throw new Exception(errorMessage); } } diff --git a/Snowflake.Data/Client/SnowflakeDbConnection.cs b/Snowflake.Data/Client/SnowflakeDbConnection.cs index 9acb24f06..fbe58375a 100755 --- a/Snowflake.Data/Client/SnowflakeDbConnection.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnection.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved. */ @@ -10,13 +10,14 @@ using System.Data; using System.Threading; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Client { [System.ComponentModel.DesignerCategory("Code")] public class SnowflakeDbConnection : DbConnection { - private SFLogger logger = SFLoggerFactory.GetLogger(); + private ILogger logger = SFLoggerFactory.GetLogger(); internal SFSession SfSession { get; set; } @@ -113,7 +114,7 @@ public void PreventPooling() throw new Exception("Session not yet created for this connection. Unable to prevent the session from pooling"); } SfSession.SetPooling(false); - logger.Debug($"Session {SfSession.sessionId} marked not to be pooled any more"); + logger.LogDebug($"Session {SfSession.sessionId} marked not to be pooled any more"); } internal bool HasActiveExplicitTransaction() => ExplicitTransaction != null && ExplicitTransaction.IsActive; @@ -131,7 +132,7 @@ private bool TryToReturnSessionToPool() var sessionReturnedToPool = SnowflakeDbConnectionPool.AddSession(SfSession); if (sessionReturnedToPool) { - logger.Debug($"Session pooled: {SfSession.sessionId}"); + logger.LogDebug($"Session pooled: {SfSession.sessionId}"); } return sessionReturnedToPool; } @@ -142,13 +143,13 @@ private TransactionRollbackStatus TerminateTransactionForDirtyConnectionReturnin return TransactionRollbackStatus.Success; try { - logger.Debug("Closing dirty connection: an active transaction exists in session: " + SfSession.sessionId); + logger.LogDebug("Closing dirty connection: an active transaction exists in session: " + SfSession.sessionId); using (IDbCommand command = CreateCommand()) { command.CommandText = "ROLLBACK"; command.ExecuteNonQuery(); // error to indicate a problem within application code that a connection was closed while still having a pending transaction - logger.Error("Closing dirty connection: rollback transaction in session " + SfSession.sessionId + " succeeded."); + logger.LogError("Closing dirty connection: rollback transaction in session " + SfSession.sessionId + " succeeded."); ExplicitTransaction = null; return TransactionRollbackStatus.Success; } @@ -156,14 +157,14 @@ private TransactionRollbackStatus TerminateTransactionForDirtyConnectionReturnin catch (Exception exception) { // error to indicate a problem with rollback of an active transaction and inability to return dirty connection to the pool - logger.Error("Closing dirty connection: rollback transaction in session: " + SfSession.sessionId + " failed, exception: " + exception.Message); + logger.LogError("Closing dirty connection: rollback transaction in session: " + SfSession.sessionId + " failed, exception: " + exception.Message); return TransactionRollbackStatus.Failure; // connection won't be pooled } } public override void ChangeDatabase(string databaseName) { - logger.Debug($"ChangeDatabase to:{databaseName}"); + logger.LogDebug($"ChangeDatabase to:{databaseName}"); string alterDbCommand = $"use database {databaseName}"; @@ -176,7 +177,7 @@ public override void ChangeDatabase(string databaseName) public override void Close() { - logger.Debug("Close Connection."); + logger.LogDebug("Close Connection."); if (IsNonClosedWithSession()) { var returnedToPool = TryToReturnSessionToPool(); @@ -200,7 +201,7 @@ public override async Task CloseAsync() public virtual async Task CloseAsync(CancellationToken cancellationToken) { - logger.Debug("Close Connection."); + logger.LogDebug("Close Connection."); TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); if (cancellationToken.IsCancellationRequested) @@ -225,18 +226,18 @@ await SfSession.CloseAsync(cancellationToken).ContinueWith( if (previousTask.IsFaulted) { // Exception from SfSession.CloseAsync - logger.Error("Error closing the session", previousTask.Exception); + logger.LogError("Error closing the session", previousTask.Exception); taskCompletionSource.SetException(previousTask.Exception); } else if (previousTask.IsCanceled) { _connectionState = ConnectionState.Closed; - logger.Debug("Session close canceled"); + logger.LogDebug("Session close canceled"); taskCompletionSource.SetCanceled(); } else { - logger.Debug("Session closed successfully"); + logger.LogDebug("Session closed successfully"); _connectionState = ConnectionState.Closed; taskCompletionSource.SetResult(null); } @@ -245,7 +246,7 @@ await SfSession.CloseAsync(cancellationToken).ContinueWith( } else { - logger.Debug("Session not opened. Nothing to do."); + logger.LogDebug("Session not opened. Nothing to do."); taskCompletionSource.SetResult(null); } } @@ -260,10 +261,10 @@ protected virtual bool CanReuseSession(TransactionRollbackStatus transactionRoll public override void Open() { - logger.Debug("Open Connection."); + logger.LogDebug("Open Connection."); if (_connectionState != ConnectionState.Closed) { - logger.Debug($"Open with a connection already opened: {_connectionState}"); + logger.LogDebug($"Open with a connection already opened: {_connectionState}"); return; } try @@ -272,14 +273,14 @@ public override void Open() SfSession = SnowflakeDbConnectionPool.GetSession(ConnectionString, Password); if (SfSession == null) throw new SnowflakeDbException(SFError.INTERNAL_ERROR, "Could not open session"); - logger.Debug($"Connection open with pooled session: {SfSession.sessionId}"); + logger.LogDebug($"Connection open with pooled session: {SfSession.sessionId}"); OnSessionEstablished(); } catch (Exception e) { // Otherwise when Dispose() is called, the close request would timeout. _connectionState = ConnectionState.Closed; - logger.Error("Unable to connect: ", e); + logger.LogError("Unable to connect: ", e); if (e is SnowflakeDbException) { throw; @@ -294,10 +295,10 @@ public override void Open() public override Task OpenAsync(CancellationToken cancellationToken) { - logger.Debug("Open Connection Async."); + logger.LogDebug("Open Connection Async."); if (_connectionState != ConnectionState.Closed) { - logger.Debug($"Open with a connection already opened: {_connectionState}"); + logger.LogDebug($"Open with a connection already opened: {_connectionState}"); return Task.CompletedTask; } registerConnectionCancellationCallback(cancellationToken); @@ -311,7 +312,7 @@ public override Task OpenAsync(CancellationToken cancellationToken) // Exception from SfSession.OpenAsync Exception sfSessionEx = previousTask.Exception; _connectionState = ConnectionState.Closed; - logger.Error("Unable to connect", sfSessionEx); + logger.LogError("Unable to connect", sfSessionEx); throw new SnowflakeDbException( sfSessionEx, SnowflakeDbException.CONNECTION_FAILURE_SSTATE, @@ -321,14 +322,14 @@ public override Task OpenAsync(CancellationToken cancellationToken) else if (previousTask.IsCanceled) { _connectionState = ConnectionState.Closed; - logger.Debug("Connection canceled"); + logger.LogDebug("Connection canceled"); throw new TaskCanceledException("Connecting was cancelled"); } else { // Only continue if the session was opened successfully SfSession = previousTask.Result; - logger.Debug($"Connection open with pooled session: {SfSession.sessionId}"); + logger.LogDebug($"Connection open with pooled session: {SfSession.sessionId}"); OnSessionEstablished(); } }, TaskContinuationOptions.None); // this continuation should be executed always (even if the whole operation was canceled) because it sets the proper state of the connection @@ -392,7 +393,7 @@ protected override void Dispose(bool disposing) catch (Exception ex) { // Prevent an exception from being thrown when disposing of this object - logger.Error("Unable to close connection", ex); + logger.LogError("Unable to close connection", ex); } } else diff --git a/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs b/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs index fcee66e1a..64c47703b 100644 --- a/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2024 Snowflake Computing Inc. All rights reserved. */ @@ -10,12 +10,13 @@ using Snowflake.Data.Core.Session; using Snowflake.Data.Core.Tools; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Client { public class SnowflakeDbConnectionPool { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); private static readonly Object s_connectionManagerInstanceLock = new Object(); private static IConnectionManager s_connectionManager; internal const ConnectionPoolType DefaultConnectionPoolType = ConnectionPoolType.MultipleConnectionPool; @@ -33,91 +34,91 @@ private static IConnectionManager ConnectionManager internal static SFSession GetSession(string connectionString, SecureString password) { - s_logger.Debug($"SnowflakeDbConnectionPool::GetSession"); + s_logger.LogDebug($"SnowflakeDbConnectionPool::GetSession"); return ConnectionManager.GetSession(connectionString, password); } internal static Task GetSessionAsync(string connectionString, SecureString password, CancellationToken cancellationToken) { - s_logger.Debug($"SnowflakeDbConnectionPool::GetSessionAsync"); + s_logger.LogDebug($"SnowflakeDbConnectionPool::GetSessionAsync"); return ConnectionManager.GetSessionAsync(connectionString, password, cancellationToken); } public static SnowflakeDbSessionPool GetPool(string connectionString, SecureString password) { - s_logger.Debug($"SnowflakeDbConnectionPool::GetPool"); + s_logger.LogDebug($"SnowflakeDbConnectionPool::GetPool"); return new SnowflakeDbSessionPool(ConnectionManager.GetPool(connectionString, password)); } public static SnowflakeDbSessionPool GetPool(string connectionString) { - s_logger.Debug($"SnowflakeDbConnectionPool::GetPool"); + s_logger.LogDebug($"SnowflakeDbConnectionPool::GetPool"); return new SnowflakeDbSessionPool(ConnectionManager.GetPool(connectionString)); } internal static SessionPool GetPoolInternal(string connectionString) { - s_logger.Debug($"SnowflakeDbConnectionPool::GetPoolInternal"); + s_logger.LogDebug($"SnowflakeDbConnectionPool::GetPoolInternal"); return ConnectionManager.GetPool(connectionString); } internal static bool AddSession(SFSession session) { - s_logger.Debug("SnowflakeDbConnectionPool::AddSession"); + s_logger.LogDebug("SnowflakeDbConnectionPool::AddSession"); return ConnectionManager.AddSession(session); } internal static void ReleaseBusySession(SFSession session) { - s_logger.Debug("SnowflakeDbConnectionPool::ReleaseBusySession"); + s_logger.LogDebug("SnowflakeDbConnectionPool::ReleaseBusySession"); ConnectionManager.ReleaseBusySession(session); } public static void ClearAllPools() { - s_logger.Debug("SnowflakeDbConnectionPool::ClearAllPools"); + s_logger.LogDebug("SnowflakeDbConnectionPool::ClearAllPools"); ConnectionManager.ClearAllPools(); } public static void SetMaxPoolSize(int maxPoolSize) { - s_logger.Debug("SnowflakeDbConnectionPool::SetMaxPoolSize"); + s_logger.LogDebug("SnowflakeDbConnectionPool::SetMaxPoolSize"); ConnectionManager.SetMaxPoolSize(maxPoolSize); } public static int GetMaxPoolSize() { - s_logger.Debug("SnowflakeDbConnectionPool::GetMaxPoolSize"); + s_logger.LogDebug("SnowflakeDbConnectionPool::GetMaxPoolSize"); return ConnectionManager.GetMaxPoolSize(); } public static void SetTimeout(long connectionTimeout) { - s_logger.Debug("SnowflakeDbConnectionPool::SetTimeout"); + s_logger.LogDebug("SnowflakeDbConnectionPool::SetTimeout"); ConnectionManager.SetTimeout(connectionTimeout); } public static long GetTimeout() { - s_logger.Debug("SnowflakeDbConnectionPool::GetTimeout"); + s_logger.LogDebug("SnowflakeDbConnectionPool::GetTimeout"); return ConnectionManager.GetTimeout(); } public static int GetCurrentPoolSize() { - s_logger.Debug("SnowflakeDbConnectionPool::GetCurrentPoolSize"); + s_logger.LogDebug("SnowflakeDbConnectionPool::GetCurrentPoolSize"); return ConnectionManager.GetCurrentPoolSize(); } public static bool SetPooling(bool isEnable) { - s_logger.Debug("SnowflakeDbConnectionPool::SetPooling"); + s_logger.LogDebug("SnowflakeDbConnectionPool::SetPooling"); return ConnectionManager.SetPooling(isEnable); } public static bool GetPooling() { - s_logger.Debug("SnowflakeDbConnectionPool::GetPooling"); + s_logger.LogDebug("SnowflakeDbConnectionPool::GetPooling"); return ConnectionManager.GetPooling(); } @@ -137,12 +138,12 @@ private static void SetConnectionPoolVersion(ConnectionPoolType requestedPoolTyp if (requestedPoolType == ConnectionPoolType.MultipleConnectionPool) { s_connectionManager = new ConnectionPoolManager(); - s_logger.Info("SnowflakeDbConnectionPool - multiple connection pools enabled"); + s_logger.LogInformation("SnowflakeDbConnectionPool - multiple connection pools enabled"); } if (requestedPoolType == ConnectionPoolType.SingleConnectionCache) { s_connectionManager = new ConnectionCacheManager(); - s_logger.Warn("SnowflakeDbConnectionPool - connection cache enabled"); + s_logger.LogWarning("SnowflakeDbConnectionPool - connection cache enabled"); } } } diff --git a/Snowflake.Data/Client/SnowflakeDbDataReader.cs b/Snowflake.Data/Client/SnowflakeDbDataReader.cs index b7bc1615e..ee6e3cb1e 100755 --- a/Snowflake.Data/Client/SnowflakeDbDataReader.cs +++ b/Snowflake.Data/Client/SnowflakeDbDataReader.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -13,12 +13,13 @@ using Snowflake.Data.Log; using Newtonsoft.Json.Linq; using Snowflake.Data.Core.Converter; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Client { public class SnowflakeDbDataReader : DbDataReader { - static private readonly SFLogger logger = SFLoggerFactory.GetLogger(); + static private readonly ILogger logger = SFLoggerFactory.GetLogger(); private SnowflakeDbCommand dbCommand; diff --git a/Snowflake.Data/Client/SnowflakeDbTransaction.cs b/Snowflake.Data/Client/SnowflakeDbTransaction.cs index 539ca225a..c10dd44ba 100755 --- a/Snowflake.Data/Client/SnowflakeDbTransaction.cs +++ b/Snowflake.Data/Client/SnowflakeDbTransaction.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -7,12 +7,13 @@ using System.Data.Common; using Snowflake.Data.Core; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Client { public class SnowflakeDbTransaction : DbTransaction { - private SFLogger logger = SFLoggerFactory.GetLogger(); + private ILogger logger = SFLoggerFactory.GetLogger(); private IsolationLevel isolationLevel; @@ -25,19 +26,19 @@ public class SnowflakeDbTransaction : DbTransaction public SnowflakeDbTransaction(IsolationLevel isolationLevel, SnowflakeDbConnection connection) { - logger.Debug("Begin transaction."); + logger.LogDebug("Begin transaction."); if (isolationLevel != IsolationLevel.ReadCommitted) { throw new SnowflakeDbException(SFError.UNSUPPORTED_FEATURE); } if (connection == null) { - logger.Error("Transaction cannot be started for an unknown connection"); + logger.LogError("Transaction cannot be started for an unknown connection"); throw new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY); } if (!connection.IsOpen()) { - logger.Error("Transaction cannot be started for a closed connection"); + logger.LogError("Transaction cannot be started for a closed connection"); throw new SnowflakeDbException(SFError.UNSUPPORTED_FEATURE); } @@ -71,7 +72,7 @@ protected override DbConnection DbConnection public override void Commit() { - logger.Debug("Commit transaction."); + logger.LogDebug("Commit transaction."); if (!isCommittedOrRollbacked) { using (IDbCommand command = connection.CreateCommand()) @@ -85,7 +86,7 @@ public override void Commit() public override void Rollback() { - logger.Debug("Rollback transaction."); + logger.LogDebug("Rollback transaction."); if (!isCommittedOrRollbacked) { using (IDbCommand command = connection.CreateCommand()) diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs b/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs deleted file mode 100644 index d417eb4d8..000000000 --- a/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using System.IO; -using System.Runtime.InteropServices; -using Mono.Unix; -using Snowflake.Data.Core.Tools; -using Snowflake.Data.Log; - -namespace Snowflake.Data.Configuration -{ - internal class EasyLoggingConfigFinder - { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); - - internal const string ClientConfigFileName = "sf_client_config.json"; - internal const string ClientConfigEnvironmentName = "SF_CLIENT_CONFIG_FILE"; - - private readonly FileOperations _fileOperations; - private readonly UnixOperations _unixOperations; - private readonly EnvironmentOperations _environmentOperations; - - public static readonly EasyLoggingConfigFinder Instance = new EasyLoggingConfigFinder(FileOperations.Instance, UnixOperations.Instance, EnvironmentOperations.Instance); - - internal EasyLoggingConfigFinder(FileOperations fileOperations, UnixOperations unixFileOperations, EnvironmentOperations environmentOperations) - { - _fileOperations = fileOperations; - _unixOperations = unixFileOperations; - _environmentOperations = environmentOperations; - } - - internal EasyLoggingConfigFinder() - { - } - - public virtual string FindConfigFilePath(string configFilePathFromConnectionString) - { - var configFilePath = GetFilePathFromInputParameter(configFilePathFromConnectionString, "connection string") - ?? GetFilePathEnvironmentVariable() - ?? GetFilePathFromDriverLocation() - ?? GetFilePathFromHomeDirectory(); - if (configFilePath != null) - { - CheckIfValidPermissions(configFilePath); - } - return configFilePath; - } - - private string GetFilePathEnvironmentVariable() - { - var filePath = _environmentOperations.GetEnvironmentVariable(ClientConfigEnvironmentName); - return GetFilePathFromInputParameter(filePath, "environment variable"); - } - - private string GetFilePathFromHomeDirectory() => SearchForConfigInDirectory(GetHomeDirectory, "home"); - - private string GetFilePathFromInputParameter(string filePath, string inputDescription) - { - if (string.IsNullOrEmpty(filePath)) - { - return null; - } - s_logger.Info($"Using config file specified from {inputDescription}: {filePath}"); - return filePath; - } - - private string GetHomeDirectory() => HomeDirectoryProvider.HomeDirectory(_environmentOperations); - - private string GetFilePathFromDriverLocation() => SearchForConfigInDirectory(() => _environmentOperations.GetExecutionDirectory(), "driver"); - - private string SearchForConfigInDirectory(Func directoryProvider, string directoryDescription) - { - try - { - var directory = directoryProvider.Invoke(); - if (string.IsNullOrEmpty(directory)) - { - s_logger.Warn($"The {directoryDescription} directory could not be determined and will be skipped"); - return null; - } - - var filePath = Path.Combine(directory, ClientConfigFileName); - return OnlyIfFileExists(filePath, directoryDescription); - } - catch (Exception e) - { - s_logger.Error($"Error while searching for the client config in {directoryDescription} directory: {e}"); - return null; - } - } - - private string OnlyIfFileExists(string filePath, string directoryDescription) - { - if (_fileOperations.Exists(filePath)) - { - s_logger.Info($"Using config file specified from {directoryDescription} directory: {filePath}"); - return filePath; - } - return null; - } - - private void CheckIfValidPermissions(string filePath) - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - return; - - // Check if others have permissions to modify the file and fail if so - if (_unixOperations.CheckFileHasAnyOfPermissions(filePath, FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite)) - { - var errorMessage = $"Error due to other users having permission to modify the config file: {filePath}"; - s_logger.Error(errorMessage); - throw new Exception(errorMessage); - } - } - } -} diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs b/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs deleted file mode 100644 index dbc6820b4..000000000 --- a/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Snowflake.Data.Log; - -namespace Snowflake.Data.Configuration -{ - internal class EasyLoggingConfigParser - { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); - - public static readonly EasyLoggingConfigParser Instance = new EasyLoggingConfigParser(); - - public virtual ClientConfig Parse(string filePath) - { - var configFile = TryToReadFile(filePath); - return configFile == null ? null : TryToParseFile(configFile); - } - - private string TryToReadFile(string filePath) - { - if (string.IsNullOrEmpty(filePath)) - { - return null; - } - try - { - return File.ReadAllText(filePath); - } - catch (Exception e) - { - var errorMessage = "Finding easy logging configuration failed"; - s_logger.Error(errorMessage, e); - throw new Exception(errorMessage); - } - } - - private ClientConfig TryToParseFile(string fileContent) - { - try { - var config = JsonConvert.DeserializeObject(fileContent); - Validate(config); - CheckForUnknownFields(fileContent); - return config; - } - catch (Exception e) - { - var errorMessage = "Parsing easy logging configuration failed"; - s_logger.Error(errorMessage, e); - throw new Exception(errorMessage); - } - } - - private void Validate(ClientConfig config) - { - if (config.CommonProps.LogLevel != null) - { - EasyLoggingLogLevelExtensions.From(config.CommonProps.LogLevel); - } - } - - private void CheckForUnknownFields(string fileContent) - { - // Parse the specified config file and get the key-value pairs from the "common" section - List knownProperties = typeof(ClientConfigCommonProps).GetProperties() - .Select(property => property.GetCustomAttribute().PropertyName) - .ToList(); - - JObject.Parse(fileContent).GetValue("common", StringComparison.OrdinalIgnoreCase)? - .Cast() - .Where(property => !knownProperties.Contains(property.Name, StringComparer.OrdinalIgnoreCase)) - .ToList() - .ForEach(unknownKey => s_logger.Warn($"Unknown field from config: {unknownKey.Name}")); - } - } -} diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigProvider.cs b/Snowflake.Data/Configuration/EasyLoggingConfigProvider.cs deleted file mode 100644 index 32788fae0..000000000 --- a/Snowflake.Data/Configuration/EasyLoggingConfigProvider.cs +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -namespace Snowflake.Data.Configuration -{ - internal class EasyLoggingConfigProvider - { - private readonly EasyLoggingConfigFinder _finder; - - private readonly EasyLoggingConfigParser _configParser; - - public static readonly EasyLoggingConfigProvider Instance = new EasyLoggingConfigProvider(); - - internal EasyLoggingConfigProvider() : this(EasyLoggingConfigFinder.Instance, EasyLoggingConfigParser.Instance) - { - } - - internal EasyLoggingConfigProvider(EasyLoggingConfigFinder finder, EasyLoggingConfigParser configParser) - { - _finder = finder; - _configParser = configParser; - } - - public virtual ClientConfig ProvideConfig(string configFilePathFromConnectionString) - { - var filePath = _finder.FindConfigFilePath(configFilePathFromConnectionString); - return filePath == null ? null : _configParser.Parse(filePath); - } - } -} diff --git a/Snowflake.Data/Configuration/EasyLoggingLogLevel.cs b/Snowflake.Data/Configuration/EasyLoggingLogLevel.cs deleted file mode 100644 index 450a9bcf1..000000000 --- a/Snowflake.Data/Configuration/EasyLoggingLogLevel.cs +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; - -namespace Snowflake.Data.Configuration -{ - internal enum EasyLoggingLogLevel - { - Off, - Error, - Warn, - Info, - Debug, - Trace - } - - internal static class EasyLoggingLogLevelExtensions - { - public static EasyLoggingLogLevel From(string logLevel) - { - return (EasyLoggingLogLevel) Enum.Parse(typeof(EasyLoggingLogLevel), logLevel, true); - } - } -} diff --git a/Snowflake.Data/Core/ArrowResultSet.cs b/Snowflake.Data/Core/ArrowResultSet.cs index 56a636c4e..fb63b40d6 100755 --- a/Snowflake.Data/Core/ArrowResultSet.cs +++ b/Snowflake.Data/Core/ArrowResultSet.cs @@ -10,6 +10,7 @@ using Apache.Arrow.Ipc; using Snowflake.Data.Client; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -17,7 +18,7 @@ class ArrowResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => ResultFormat.ARROW; - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); private readonly int _totalChunkCount; private BaseResultChunk _currentChunk; @@ -49,7 +50,7 @@ public ArrowResultSet(QueryExecResponseData responseData, SFStatement sfStatemen } catch(Exception ex) { - s_logger.Error("Result set error queryId="+responseData.queryId, ex); + s_logger.LogError("Result set error queryId="+responseData.queryId, ex); throw; } } @@ -86,7 +87,7 @@ internal override async Task NextAsync() if (_totalChunkCount > 0) { - s_logger.Debug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_logger.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); _currentChunk = await _chunkDownloader.GetNextChunkAsync().ConfigureAwait(false); @@ -105,7 +106,7 @@ internal override bool Next() if (_totalChunkCount > 0) { - s_logger.Debug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_logger.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); _currentChunk = Task.Run(async() => await (_chunkDownloader.GetNextChunkAsync()).ConfigureAwait(false)).Result; @@ -149,7 +150,7 @@ internal override bool Rewind() if (_currentChunk.ChunkIndex > 0) { - s_logger.Warn("Unable to rewind to the previous chunk"); + s_logger.LogWarning("Unable to rewind to the previous chunk"); } return false; diff --git a/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs b/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs index a26d542d3..84f58404e 100644 --- a/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs @@ -5,13 +5,14 @@ using Snowflake.Data.Log; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { class BasicAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "snowflake"; - private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); internal BasicAuthenticator(SFSession session) : base(session, AUTH_NAME) { diff --git a/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs b/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs index e39ec18f8..83e47dcbf 100644 --- a/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs @@ -13,6 +13,7 @@ using Snowflake.Data.Client; using System.Text.RegularExpressions; using System.Collections.Generic; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { @@ -22,7 +23,7 @@ namespace Snowflake.Data.Core.Authenticator class ExternalBrowserAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "externalbrowser"; - private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); private static readonly string TOKEN_REQUEST_PREFIX = "?token="; private static readonly byte[] SUCCESS_RESPONSE = System.Text.Encoding.UTF8.GetBytes( "" + @@ -47,14 +48,14 @@ internal ExternalBrowserAuthenticator(SFSession session) : base(session, AUTH_NA /// async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) { - logger.Info("External Browser Authentication"); + logger.LogInformation("External Browser Authentication"); int localPort = GetRandomUnusedPort(); using (var httpListener = GetHttpListener(localPort)) { httpListener.Start(); - logger.Debug("Get IdpUrl and ProofKey"); + logger.LogDebug("Get IdpUrl and ProofKey"); string loginUrl; if (session._disableConsoleLogin) { @@ -75,37 +76,37 @@ await session.restRequester.PostAsync( loginUrl = GetLoginUrl(_proofKey, localPort); } - logger.Debug("Open browser"); + logger.LogDebug("Open browser"); StartBrowser(loginUrl); - logger.Debug("Get the redirect SAML request"); + logger.LogDebug("Get the redirect SAML request"); _successEvent = new ManualResetEvent(false); httpListener.BeginGetContext(GetContextCallback, httpListener); var timeoutInSec = int.Parse(session.properties[SFSessionProperty.BROWSER_RESPONSE_TIMEOUT]); if (!_successEvent.WaitOne(timeoutInSec * 1000)) { - logger.Warn("Browser response timeout"); + logger.LogWarning("Browser response timeout"); throw new SnowflakeDbException(SFError.BROWSER_RESPONSE_TIMEOUT, timeoutInSec); } httpListener.Stop(); } - logger.Debug("Send login request"); + logger.LogDebug("Send login request"); await base.LoginAsync(cancellationToken).ConfigureAwait(false); } /// void IAuthenticator.Authenticate() { - logger.Info("External Browser Authentication"); + logger.LogInformation("External Browser Authentication"); int localPort = GetRandomUnusedPort(); using (var httpListener = GetHttpListener(localPort)) { httpListener.Start(); - logger.Debug("Get IdpUrl and ProofKey"); + logger.LogDebug("Get IdpUrl and ProofKey"); string loginUrl; if (session._disableConsoleLogin) { @@ -122,23 +123,23 @@ void IAuthenticator.Authenticate() loginUrl = GetLoginUrl(_proofKey, localPort); } - logger.Debug("Open browser"); + logger.LogDebug("Open browser"); StartBrowser(loginUrl); - logger.Debug("Get the redirect SAML request"); + logger.LogDebug("Get the redirect SAML request"); _successEvent = new ManualResetEvent(false); httpListener.BeginGetContext(GetContextCallback, httpListener); var timeoutInSec = int.Parse(session.properties[SFSessionProperty.BROWSER_RESPONSE_TIMEOUT]); if (!_successEvent.WaitOne(timeoutInSec * 1000)) { - logger.Warn("Browser response timeout"); + logger.LogWarning("Browser response timeout"); throw new SnowflakeDbException(SFError.BROWSER_RESPONSE_TIMEOUT, timeoutInSec); } httpListener.Stop(); } - logger.Debug("Send login request"); + logger.LogDebug("Send login request"); base.Login(); } @@ -163,7 +164,7 @@ private void GetContextCallback(IAsyncResult result) catch { // Ignore the exception as it does not affect the overall authentication flow - logger.Warn("External browser response not sent out"); + logger.LogWarning("External browser response not sent out"); } } @@ -193,13 +194,13 @@ private static void StartBrowser(string url) Match m = Regex.Match(url, regexStr, RegexOptions.IgnoreCase); if (!m.Success) { - logger.Error("Failed to start browser. Invalid url."); + logger.LogError("Failed to start browser. Invalid url."); throw new SnowflakeDbException(SFError.INVALID_BROWSER_URL); } if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) { - logger.Error("Failed to start browser. Invalid url."); + logger.LogError("Failed to start browser. Invalid url."); throw new SnowflakeDbException(SFError.INVALID_BROWSER_URL); } diff --git a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs index 7a41a8335..e077f2966 100644 --- a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Snowflake.Data.Client; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { @@ -45,7 +46,7 @@ internal enum SFAuthenticatorType internal abstract class BaseAuthenticator { // The logger. - private static readonly SFLogger logger = + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); // The name of the authenticator. @@ -134,7 +135,7 @@ private SFRestRequest BuildLoginRequest() /// internal class AuthenticatorFactory { - private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); /// /// Generate the authenticator given the session /// @@ -164,7 +165,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) var error = new SnowflakeDbException( SFError.INVALID_CONNECTION_STRING, new object[] { invalidStringDetail }); - logger.Error(error.Message, error); + logger.LogError(error.Message, error); throw error; } @@ -181,7 +182,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) var error = new SnowflakeDbException( SFError.INVALID_CONNECTION_STRING, new object[] { invalidStringDetail }); - logger.Error(error.Message, error); + logger.LogError(error.Message, error); throw error; } @@ -192,7 +193,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) { return new OktaAuthenticator(session, type); } - logger.Error($"Unknown authenticator {type}"); + logger.LogError($"Unknown authenticator {type}"); throw new SnowflakeDbException(SFError.UNKNOWN_AUTHENTICATOR, type); } } diff --git a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs index 7d86d02c9..fea927b57 100644 --- a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs @@ -19,6 +19,8 @@ using Org.BouncyCastle.X509; using System.Security.Claims; using Microsoft.IdentityModel.Tokens; +using Microsoft.Extensions.Logging; + namespace Snowflake.Data.Core.Authenticator { /// @@ -31,7 +33,7 @@ class KeyPairAuthenticator : BaseAuthenticator, IAuthenticator public const string AUTH_NAME = "snowflake_jwt"; // The logger. - private static readonly SFLogger logger = + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); // The RSA provider to use to sign the tokens @@ -56,7 +58,7 @@ async public Task AuthenticateAsync(CancellationToken cancellationToken) jwtToken = GenerateJwtToken(); // Send the http request with the generate token - logger.Debug("Send login request"); + logger.LogDebug("Send login request"); await base.LoginAsync(cancellationToken).ConfigureAwait(false); } @@ -66,7 +68,7 @@ public void Authenticate() jwtToken = GenerateJwtToken(); // Send the http request with the generate token - logger.Debug("Send login request"); + logger.LogDebug("Send login request"); base.Login(); } @@ -83,7 +85,7 @@ protected override void SetSpecializedAuthenticatorData(ref LoginRequestData dat /// The generated JWT token. private string GenerateJwtToken() { - logger.Info("Key-pair Authentication"); + logger.LogInformation("Key-pair Authentication"); bool hasPkPath = session.properties.TryGetValue(SFSessionProperty.PRIVATE_KEY_FILE, out var pkPath); diff --git a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs index f36d0353e..74f39d99c 100644 --- a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs @@ -1,9 +1,10 @@ -using Snowflake.Data.Log; +using Snowflake.Data.Log; using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { @@ -17,7 +18,7 @@ class OAuthAuthenticator : BaseAuthenticator, IAuthenticator public const string AUTH_NAME = "oauth"; // The logger. - private static readonly SFLogger logger = + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); /// diff --git a/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs b/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs index 7c364d3c5..77a9a41cf 100644 --- a/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs @@ -14,6 +14,7 @@ using System.Web; using System.Linq; using Snowflake.Data.Core.Tools; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { @@ -23,7 +24,7 @@ namespace Snowflake.Data.Core.Authenticator class OktaAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "okta"; - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); internal const string RetryCountHeader = "RetryCount"; internal const string TimeoutElapsedHeader = "TimeoutElapsed"; @@ -49,19 +50,19 @@ internal OktaAuthenticator(SFSession session, string oktaUriString) : /// async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) { - s_logger.Info("Okta Authentication"); + s_logger.LogInformation("Okta Authentication"); - s_logger.Debug("step 1: Get SSO and token URL"); + s_logger.LogDebug("step 1: Get SSO and token URL"); var authenticatorRestRequest = BuildAuthenticatorRestRequest(); var authenticatorResponse = await session.restRequester.PostAsync(authenticatorRestRequest, cancellationToken).ConfigureAwait(false); authenticatorResponse.FilterFailedResponse(); Uri ssoUrl = new Uri(authenticatorResponse.data.ssoUrl); Uri tokenUrl = new Uri(authenticatorResponse.data.tokenUrl); - s_logger.Debug("step 2: Verify URLs fetched from step 1"); - s_logger.Debug("Checking SSO Okta URL"); + s_logger.LogDebug("step 2: Verify URLs fetched from step 1"); + s_logger.LogDebug("Checking SSO Okta URL"); VerifyUrls(ssoUrl, _oktaUrl); - s_logger.Debug("Checking token URL"); + s_logger.LogDebug("Checking token URL"); VerifyUrls(tokenUrl, _oktaUrl); int retryCount = 0; @@ -74,26 +75,26 @@ async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) { try { - s_logger.Debug("step 3: Get IdP one-time token"); + s_logger.LogDebug("step 3: Get IdP one-time token"); IdpTokenRestRequest idpTokenRestRequest = BuildIdpTokenRestRequest(tokenUrl); var idpResponse = await session.restRequester.PostAsync(idpTokenRestRequest, cancellationToken).ConfigureAwait(false); string onetimeToken = idpResponse.SessionToken ?? idpResponse.CookieToken; - s_logger.Debug("step 4: Get SAML response from SSO"); + s_logger.LogDebug("step 4: Get SAML response from SSO"); var samlRestRequest = BuildSamlRestRequest(ssoUrl, onetimeToken); samlRawResponse = await session.restRequester.GetAsync(samlRestRequest, cancellationToken).ConfigureAwait(false); _rawSamlTokenHtmlString = await samlRawResponse.Content.ReadAsStringAsync().ConfigureAwait(false); - s_logger.Debug("step 5: Verify postback URL in SAML response"); + s_logger.LogDebug("step 5: Verify postback URL in SAML response"); if (!session._disableSamlUrlCheck) { VerifyPostbackUrl(); } else { - s_logger.Debug("The saml url check is disabled. Skipping step 5"); + s_logger.LogDebug("The saml url check is disabled. Skipping step 5"); } - s_logger.Debug("step 6: Send SAML response to Snowflake to login"); + s_logger.LogDebug("step 6: Send SAML response to Snowflake to login"); await LoginAsync(cancellationToken).ConfigureAwait(false); return; } @@ -115,19 +116,19 @@ async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) void IAuthenticator.Authenticate() { - s_logger.Info("Okta Authentication"); + s_logger.LogInformation("Okta Authentication"); - s_logger.Debug("step 1: Get SSO and token URL"); + s_logger.LogDebug("step 1: Get SSO and token URL"); var authenticatorRestRequest = BuildAuthenticatorRestRequest(); var authenticatorResponse = session.restRequester.Post(authenticatorRestRequest); authenticatorResponse.FilterFailedResponse(); Uri ssoUrl = new Uri(authenticatorResponse.data.ssoUrl); Uri tokenUrl = new Uri(authenticatorResponse.data.tokenUrl); - s_logger.Debug("step 2: Verify URLs fetched from step 1"); - s_logger.Debug("Checking SSO Okta URL"); + s_logger.LogDebug("step 2: Verify URLs fetched from step 1"); + s_logger.LogDebug("Checking SSO Okta URL"); VerifyUrls(ssoUrl, _oktaUrl); - s_logger.Debug("Checking token URL"); + s_logger.LogDebug("Checking token URL"); VerifyUrls(tokenUrl, _oktaUrl); int retryCount = 0; @@ -140,27 +141,27 @@ void IAuthenticator.Authenticate() { try { - s_logger.Debug("step 3: Get IdP one-time token"); + s_logger.LogDebug("step 3: Get IdP one-time token"); IdpTokenRestRequest idpTokenRestRequest = BuildIdpTokenRestRequest(tokenUrl); var idpResponse = session.restRequester.Post(idpTokenRestRequest); string onetimeToken = idpResponse.SessionToken ?? idpResponse.CookieToken; - s_logger.Debug("step 4: Get SAML response from SSO"); + s_logger.LogDebug("step 4: Get SAML response from SSO"); var samlRestRequest = BuildSamlRestRequest(ssoUrl, onetimeToken); samlRawResponse = session.restRequester.Get(samlRestRequest); _rawSamlTokenHtmlString = Task.Run(async () => await samlRawResponse.Content.ReadAsStringAsync().ConfigureAwait(false)).Result; - s_logger.Debug("step 5: Verify postback URL in SAML response"); + s_logger.LogDebug("step 5: Verify postback URL in SAML response"); if (!session._disableSamlUrlCheck) { VerifyPostbackUrl(); } else { - s_logger.Debug("The saml url check is disabled. Skipping step 5"); + s_logger.LogDebug("The saml url check is disabled. Skipping step 5"); } - s_logger.Debug("step 6: Send SAML response to Snowflake to login"); + s_logger.LogDebug("step 6: Send SAML response to Snowflake to login"); Login(); return; } @@ -184,12 +185,12 @@ private void HandleAuthenticatorException(Exception ex, HttpResponseMessage saml { if (IsPostbackUrlNotFound(ex)) { - s_logger.Debug("Refreshing token for Okta re-authentication and starting from step 3 again"); + s_logger.LogDebug("Refreshing token for Okta re-authentication and starting from step 3 again"); if (samlRawResponse is null) { var errorNullSamlResponse = "Failure getting SAML response from Okta SSO"; - s_logger.Error(errorNullSamlResponse); + s_logger.LogError(errorNullSamlResponse); throw new SnowflakeDbException(ex, SFError.IDP_SAML_POSTBACK_INVALID); } @@ -199,7 +200,7 @@ private void HandleAuthenticatorException(Exception ex, HttpResponseMessage saml } else { - s_logger.Error("Failed to get the correct SAML response from Okta SSO", ex); + s_logger.LogError("Failed to get the correct SAML response from Okta SSO", ex); throw ex; } } @@ -256,7 +257,7 @@ private void VerifyUrls(Uri tokenOrSsoUrl, Uri sessionUrl) { var e = new SnowflakeDbException( SFError.IDP_SSO_TOKEN_URL_MISMATCH, tokenOrSsoUrl.ToString(), _oktaUrl.ToString()); - s_logger.Error("Different urls", e); + s_logger.LogError("Different urls", e); throw e; } } @@ -275,7 +276,7 @@ private void VerifyPostbackUrl() postBackUrl = new Uri(HttpUtility.HtmlDecode(_rawSamlTokenHtmlString.Substring(startIndex, length))); } catch (Exception e) { - s_logger.Error("Fail to extract SAML from html", e); + s_logger.LogError("Fail to extract SAML from html", e); throw new SnowflakeDbException(e, SFError.IDP_SAML_POSTBACK_NOTFOUND); } @@ -288,7 +289,7 @@ private void VerifyPostbackUrl() SFError.IDP_SAML_POSTBACK_INVALID, postBackUrl.ToString(), sessionScheme + ":\\\\" + sessionHost); - s_logger.Error("Different urls", e); + s_logger.LogError("Different urls", e); throw e; } } @@ -324,7 +325,7 @@ private void ThrowRetryLimitException(int retryCount, int timeoutElapsed, Except } errorMessage += " while trying to authenticate through Okta"; - s_logger.Error(errorMessage); + s_logger.LogError(errorMessage); throw new SnowflakeDbException(lastRetryException, SFError.INTERNAL_ERROR, errorMessage); } } diff --git a/Snowflake.Data/Core/ChunkDownloaderFactory.cs b/Snowflake.Data/Core/ChunkDownloaderFactory.cs index 553e67d2d..cad3f3562 100755 --- a/Snowflake.Data/Core/ChunkDownloaderFactory.cs +++ b/Snowflake.Data/Core/ChunkDownloaderFactory.cs @@ -6,12 +6,13 @@ using System.Threading; using Snowflake.Data.Configuration; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { class ChunkDownloaderFactory { - private static SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static ILogger s_logger = SFLoggerFactory.GetLogger(); public static IChunkDownloader GetDownloader(QueryExecResponseData responseData, SFBaseResultSet resultSet, CancellationToken cancellationToken) @@ -19,7 +20,7 @@ public static IChunkDownloader GetDownloader(QueryExecResponseData responseData, switch (SFConfiguration.Instance().GetChunkDownloaderVersion()) { case 1: - s_logger.Warn("V1 version of ChunkDownloader is deprecated. Using the V3 version."); + s_logger.LogWarning("V1 version of ChunkDownloader is deprecated. Using the V3 version."); return new SFBlockingChunkDownloaderV3(responseData.rowType.Count, responseData.chunks, responseData.qrmk, @@ -28,7 +29,7 @@ public static IChunkDownloader GetDownloader(QueryExecResponseData responseData, resultSet, responseData.queryResultFormat); case 2: - s_logger.Warn("V2 version of ChunkDownloader is deprecated. Using the V3 version."); + s_logger.LogWarning("V2 version of ChunkDownloader is deprecated. Using the V3 version."); return new SFBlockingChunkDownloaderV3(responseData.rowType.Count, responseData.chunks, responseData.qrmk, diff --git a/Snowflake.Data/Core/ChunkParserFactory.cs b/Snowflake.Data/Core/ChunkParserFactory.cs index 87d3a5f33..e5e9d6fb1 100755 --- a/Snowflake.Data/Core/ChunkParserFactory.cs +++ b/Snowflake.Data/Core/ChunkParserFactory.cs @@ -6,12 +6,13 @@ using System.IO; using Snowflake.Data.Configuration; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { class ChunkParserFactory : IChunkParserFactory { - private static SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static ILogger s_logger = SFLoggerFactory.GetLogger(); public static IChunkParserFactory Instance = new ChunkParserFactory(); public IChunkParser GetParser(ResultFormat resultFormat, Stream stream) @@ -22,10 +23,10 @@ public IChunkParser GetParser(ResultFormat resultFormat, Stream stream) switch (SFConfiguration.Instance().GetChunkParserVersion()) { case 1: - s_logger.Warn("V1 version of ChunkParser is deprecated. Using the V3 version."); + s_logger.LogWarning("V1 version of ChunkParser is deprecated. Using the V3 version."); return new ReusableChunkParser(stream); case 2: - s_logger.Warn("V2 version of ChunkParser is deprecated. Using the V3 version."); + s_logger.LogWarning("V2 version of ChunkParser is deprecated. Using the V3 version."); return new ReusableChunkParser(stream); case 3: return new ReusableChunkParser(stream); diff --git a/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs b/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs index ce46332c9..4a2ebeee2 100644 --- a/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs +++ b/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs @@ -1,21 +1,22 @@ using System; using Snowflake.Data.Client; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Converter { public class StructuredTypesReadingHandler { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); public static SnowflakeDbException ToSnowflakeDbException(Exception exception, string context) { if (exception is StructuredTypesReadingException) { - s_logger.Debug("Exception caught when reading structured types", exception); + s_logger.LogDebug("Exception caught when reading structured types", exception); return new SnowflakeDbException(SFError.STRUCTURED_TYPE_READ_DETAILED_ERROR, context, exception.Message); } - s_logger.Debug("Exception caught when reading structured types"); + s_logger.LogDebug("Exception caught when reading structured types"); return new SnowflakeDbException(SFError.STRUCTURED_TYPE_READ_ERROR, context); } } diff --git a/Snowflake.Data/Core/FastParser.cs b/Snowflake.Data/Core/FastParser.cs index bb06f1eaf..3d82668b8 100644 --- a/Snowflake.Data/Core/FastParser.cs +++ b/Snowflake.Data/Core/FastParser.cs @@ -1,19 +1,20 @@ -using System; +using System; using Snowflake.Data.Client; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { public class FastParser { - private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); public static Int64 FastParseInt64(byte[] s, int offset, int len) { if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - Logger.Error("A null buffer was passed to FastParseInt64", ex); + logger.LogError("A null buffer was passed to FastParseInt64", ex); throw ex; } @@ -54,7 +55,7 @@ public static Int32 FastParseInt32(byte[] s, int offset, int len) if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - Logger.Error("A null buffer was passed to FastParseInt32", ex); + logger.LogError("A null buffer was passed to FastParseInt32", ex); throw ex; } @@ -95,7 +96,7 @@ public static decimal FastParseDecimal(byte[] s, int offset, int len) if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - Logger.Error("A null buffer was passed to FastParseDecimal", ex); + logger.LogError("A null buffer was passed to FastParseDecimal", ex); throw ex; } diff --git a/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs b/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs index 411a6eeab..03aa7c20d 100644 --- a/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs +++ b/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs @@ -6,6 +6,7 @@ using System; using Snowflake.Data.Log; using System.Security.Cryptography; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.FileTransfer { @@ -33,7 +34,7 @@ class EncryptionProvider /// /// The logger. /// - private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); /// /// Encrypt data and write to the outStream. @@ -71,7 +72,7 @@ public static StreamPair EncryptStream( { byte[] decodedMasterKey = Convert.FromBase64String(encryptionMaterial.queryStageMasterKey); int masterKeySize = decodedMasterKey.Length; - Logger.Debug($"Master key size : {masterKeySize}"); + logger.LogDebug($"Master key size : {masterKeySize}"); // Generate file key byte[] ivData = new byte[blockSize]; diff --git a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs index b27daa51f..d772e4b2c 100644 --- a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs +++ b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs @@ -14,6 +14,7 @@ using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -60,7 +61,7 @@ class SFFileTransferAgent /// /// The logger. /// - private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); /// /// Auto-detect keyword for source compression type auto detection. @@ -230,7 +231,7 @@ public void execute() } catch (Exception e) { - Logger.Error("Error while transferring file(s): " + e.Message); + logger.LogError("Error while transferring file(s): " + e.Message); if (e is SnowflakeDbException snowflakeException) { if (snowflakeException.QueryId == null) @@ -346,19 +347,19 @@ private void upload() //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - Logger.Debug("Start uploading large files"); + logger.LogDebug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { UploadFilesInSequential(fileMetadata); } - Logger.Debug("End uploading large files"); + logger.LogDebug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - Logger.Debug("Start uploading small files"); + logger.LogDebug("Start uploading small files"); UploadFilesInParallel(SmallFilesMetas, TransferMetadata.parallel); - Logger.Debug("End uploading small files"); + logger.LogDebug("End uploading small files"); } } @@ -372,19 +373,19 @@ private async Task uploadAsync(CancellationToken cancellationToken) //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - Logger.Debug("Start uploading large files"); + logger.LogDebug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { await UploadFilesInSequentialAsync(fileMetadata, cancellationToken).ConfigureAwait(false); } - Logger.Debug("End uploading large files"); + logger.LogDebug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - Logger.Debug("Start uploading small files"); + logger.LogDebug("Start uploading small files"); await UploadFilesInParallelAsync(SmallFilesMetas, TransferMetadata.parallel, cancellationToken).ConfigureAwait(false); - Logger.Debug("End uploading small files"); + logger.LogDebug("End uploading small files"); } } @@ -399,18 +400,18 @@ private void download() //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - Logger.Debug("Start uploading large files"); + logger.LogDebug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { DownloadFilesInSequential(fileMetadata); } - Logger.Debug("End uploading large files"); + logger.LogDebug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - Logger.Debug("Start uploading small files"); + logger.LogDebug("Start uploading small files"); DownloadFilesInParallel(SmallFilesMetas, TransferMetadata.parallel); - Logger.Debug("End uploading small files"); + logger.LogDebug("End uploading small files"); } } @@ -424,18 +425,18 @@ private async Task downloadAsync(CancellationToken cancellationToken) //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - Logger.Debug("Start uploading large files"); + logger.LogDebug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { await DownloadFilesInSequentialAsync(fileMetadata, cancellationToken).ConfigureAwait(false); } - Logger.Debug("End uploading large files"); + logger.LogDebug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - Logger.Debug("Start uploading small files"); + logger.LogDebug("Start uploading small files"); await DownloadFilesInParallelAsync(SmallFilesMetas, TransferMetadata.parallel, cancellationToken).ConfigureAwait(false); - Logger.Debug("End uploading small files"); + logger.LogDebug("End uploading small files"); } } @@ -571,7 +572,7 @@ private void initFileMetadata( // Auto-detect source compression type // Will return NONE if no matching type is found compressionType = SFFileCompressionTypes.GuessCompressionType(file); - Logger.Debug($"File compression detected as {compressionType.Name} for: {file}"); + logger.LogDebug($"File compression detected as {compressionType.Name} for: {file}"); } else { @@ -711,7 +712,7 @@ private int GetFileTransferMaxBytesInMemory() } catch (Exception) { - Logger.Warn("Default for FILE_TRANSFER_MEMORY_THRESHOLD used due to invalid session value."); + logger.LogWarning("Default for FILE_TRANSFER_MEMORY_THRESHOLD used due to invalid session value."); return FileTransferConfiguration.DefaultMaxBytesInMemory; } } @@ -777,12 +778,12 @@ private List expandFileNames(string location) } } - if (Logger.IsDebugEnabled()) + if (logger.IsEnabled(LogLevel.Debug)) { - Logger.Debug("Expand " + location + " into: "); + logger.LogDebug("Expand " + location + " into: "); foreach (var filepath in filePaths) { - Logger.Debug("\t" + filepath ); + logger.LogDebug("\t" + filepath ); } } @@ -896,7 +897,7 @@ private void compressFileWithGzip(SFFileMetadata fileMetadata) } } - Logger.Debug($"Compressed {fileToCompress.Name} to {fileMetadata.realSrcFilePath}"); + logger.LogDebug($"Compressed {fileToCompress.Name} to {fileMetadata.realSrcFilePath}"); FileInfo destInfo = new FileInfo(fileMetadata.realSrcFilePath); fileMetadata.destFileSize = destInfo.Length; } @@ -1230,7 +1231,7 @@ private SFFileMetadata UploadSingleFile( } catch (Exception ex) { - Logger.Debug("Unhandled exception while uploading file.", ex); + logger.LogDebug("Unhandled exception while uploading file.", ex); throw; } finally @@ -1279,7 +1280,7 @@ private async Task UploadSingleFileAsync( } catch (Exception ex) { - Logger.Error("UploadSingleFileAsync encountered an error: " + ex.Message); + logger.LogError("UploadSingleFileAsync encountered an error: " + ex.Message); throw; } finally @@ -1317,7 +1318,7 @@ private SFFileMetadata DownloadSingleFile( } catch (Exception ex) { - Logger.Error("DownloadSingleFile encountered an error: " + ex.Message); + logger.LogError("DownloadSingleFile encountered an error: " + ex.Message); throw; } finally @@ -1355,7 +1356,7 @@ private async Task DownloadSingleFileAsync( } catch (Exception ex) { - Logger.Error("DownloadSingleFileAsync encountered an error: " + ex.Message); + logger.LogError("DownloadSingleFileAsync encountered an error: " + ex.Message); throw; } finally diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs index 14abaad4a..f80fc655f 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs @@ -10,6 +10,7 @@ using Newtonsoft.Json; using Snowflake.Data.Log; using System.Net; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.FileTransfer.StorageClient { @@ -40,7 +41,7 @@ class SFGCSClient : ISFRemoteStorageClient /// /// The logger. /// - private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); /// /// The storage client. @@ -58,18 +59,18 @@ class SFGCSClient : ISFRemoteStorageClient /// The command stage info. public SFGCSClient(PutGetStageInfo stageInfo) { - Logger.Debug("Setting up a new GCS client "); + logger.LogDebug("Setting up a new GCS client "); if (stageInfo.stageCredentials.TryGetValue(GCS_ACCESS_TOKEN, out string accessToken)) { - Logger.Debug("Constructing client using access token"); + logger.LogDebug("Constructing client using access token"); AccessToken = accessToken; GoogleCredential creds = GoogleCredential.FromAccessToken(accessToken, null); StorageClient = Google.Cloud.Storage.V1.StorageClient.Create(creds); } else { - Logger.Info("No access token received from GS, constructing anonymous client with no encryption support"); + logger.LogInformation("No access token received from GS, constructing anonymous client with no encryption support"); StorageClient = Google.Cloud.Storage.V1.StorageClient.CreateUnauthenticated(); } } @@ -443,7 +444,7 @@ private void HandleDownloadResponse(HttpWebResponse response, SFFileMetadata fil /// File Metadata private SFFileMetadata HandleFileHeaderErrForPresignedUrls(WebException ex, SFFileMetadata fileMetadata) { - Logger.Error("Failed to get file header for presigned url: " + ex.Message); + logger.LogError("Failed to get file header for presigned url: " + ex.Message); HttpWebResponse response = (HttpWebResponse)ex.Response; if (response.StatusCode == HttpStatusCode.Unauthorized || @@ -469,7 +470,7 @@ private SFFileMetadata HandleFileHeaderErrForPresignedUrls(WebException ex, SFFi /// File Metadata private SFFileMetadata HandleFileHeaderErrForGeneratedUrls(WebException ex, SFFileMetadata fileMetadata) { - Logger.Error("Failed to get file header for non-presigned url: " + ex.Message); + logger.LogError("Failed to get file header for non-presigned url: " + ex.Message); HttpWebResponse response = (HttpWebResponse)ex.Response; if (response.StatusCode == HttpStatusCode.Unauthorized) @@ -504,7 +505,7 @@ private SFFileMetadata HandleFileHeaderErrForGeneratedUrls(WebException ex, SFFi /// File Metadata private SFFileMetadata HandleUploadFileErr(WebException ex, SFFileMetadata fileMetadata) { - Logger.Error("Failed to upload file: " + ex.Message); + logger.LogError("Failed to upload file: " + ex.Message); fileMetadata.lastError = ex; @@ -534,7 +535,7 @@ private SFFileMetadata HandleUploadFileErr(WebException ex, SFFileMetadata fileM /// File Metadata private SFFileMetadata HandleDownloadFileErr(WebException ex, SFFileMetadata fileMetadata) { - Logger.Error("Failed to download file: " + ex.Message); + logger.LogError("Failed to download file: " + ex.Message); fileMetadata.lastError = ex; diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs index 60d67b5d7..bea6258c8 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs @@ -12,6 +12,7 @@ using System.Net; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.FileTransfer.StorageClient { @@ -71,7 +72,7 @@ internal class S3Metadata /// /// The logger. /// - private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); /// /// The underlying S3 client. @@ -88,7 +89,7 @@ public SFS3Client( int parallel, ProxyCredentials proxyCredentials) { - Logger.Debug("Setting up a new AWS client "); + logger.LogDebug("Setting up a new AWS client "); // Get the key id and secret key from the response stageInfo.stageCredentials.TryGetValue(AWS_KEY_ID, out string awsAccessKeyId); @@ -522,7 +523,7 @@ private GetObjectRequest GetGetObjectRequest(ref AmazonS3Client client, SFFileMe /// The file metadata. private SFFileMetadata HandleFileHeaderErr(Exception ex, SFFileMetadata fileMetadata) { - Logger.Error("Failed to get file header: " + ex.Message); + logger.LogError("Failed to get file header: " + ex.Message); AmazonS3Exception err = (AmazonS3Exception)ex; if (err.ErrorCode == EXPIRED_TOKEN || err.ErrorCode == HttpStatusCode.BadRequest.ToString()) @@ -548,7 +549,7 @@ private SFFileMetadata HandleFileHeaderErr(Exception ex, SFFileMetadata fileMeta /// The file metadata. private SFFileMetadata HandleUploadFileErr(Exception ex, SFFileMetadata fileMetadata) { - Logger.Error("Failed to upload file: " + ex.Message); + logger.LogError("Failed to upload file: " + ex.Message); AmazonS3Exception err = (AmazonS3Exception)ex; if (err.ErrorCode == EXPIRED_TOKEN) @@ -571,7 +572,7 @@ private SFFileMetadata HandleUploadFileErr(Exception ex, SFFileMetadata fileMeta /// The file metadata. private SFFileMetadata HandleDownloadFileErr(Exception ex, SFFileMetadata fileMetadata) { - Logger.Error("Failed to download file: " + ex.Message); + logger.LogError("Failed to download file: " + ex.Message); AmazonS3Exception err = (AmazonS3Exception)ex; if (err.ErrorCode == EXPIRED_TOKEN) diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs index f0ad3f09e..7569f19cb 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs @@ -13,6 +13,7 @@ using System.Threading; using System.Threading.Tasks; using System.Net; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.FileTransfer.StorageClient { @@ -30,7 +31,7 @@ class SFSnowflakeAzureClient : ISFRemoteStorageClient /// /// The logger. /// - private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); /// /// The cloud blob client to use to upload and download data on Azure. @@ -43,7 +44,7 @@ class SFSnowflakeAzureClient : ISFRemoteStorageClient /// The command stage info. public SFSnowflakeAzureClient(PutGetStageInfo stageInfo) { - Logger.Debug("Setting up a new Azure client "); + logger.LogDebug("Setting up a new Azure client "); // Get the Azure SAS token and create the client if (stageInfo.stageCredentials.TryGetValue(AZURE_SAS_TOKEN, out string sasToken)) diff --git a/Snowflake.Data/Core/HttpUtil.cs b/Snowflake.Data/Core/HttpUtil.cs index 72d18bcdd..12fd85251 100755 --- a/Snowflake.Data/Core/HttpUtil.cs +++ b/Snowflake.Data/Core/HttpUtil.cs @@ -15,6 +15,7 @@ using System.Linq; using Snowflake.Data.Core.Authenticator; using static Snowflake.Data.Core.SFRestRequest; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -77,7 +78,7 @@ public sealed class HttpUtil static internal readonly int MAX_BACKOFF = 16; private static readonly int s_baseBackOffTime = 1; private static readonly int s_exponentialFactor = 2; - private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); + private static readonly Microsoft.Extensions.Logging.ILogger logger = SFLoggerFactory.GetLogger(); private static readonly List s_supportedEndpointsForRetryPolicy = new List { @@ -114,7 +115,7 @@ private HttpClient RegisterNewHttpClientIfNecessary(HttpClientConfig config, Del string name = config.ConfKey; if (!_HttpClients.ContainsKey(name)) { - logger.Debug("Http client not registered. Adding."); + logger.LogDebug("Http client not registered. Adding."); var httpClient = new HttpClient( new RetryHandler(SetupCustomHttpHandler(config, customHandler), config.DisableRetry, config.ForceRetryOn404, config.MaxHttpRetries, config.IncludeRetryReason)) @@ -333,7 +334,7 @@ internal Uri Update(int retryReason = 0) } private class RetryHandler : DelegatingHandler { - static private SFLogger logger = SFLoggerFactory.GetLogger(); + static private ILogger logger = SFLoggerFactory.GetLogger(); private bool disableRetry; private bool forceRetryOn404; @@ -367,10 +368,10 @@ protected override async Task SendAsync(HttpRequestMessage TimeSpan httpTimeout = (TimeSpan)requestMessage.Properties[BaseRestRequest.HTTP_REQUEST_TIMEOUT_KEY]; TimeSpan restTimeout = (TimeSpan)requestMessage.Properties[BaseRestRequest.REST_REQUEST_TIMEOUT_KEY]; - if (logger.IsDebugEnabled()) + if (logger.IsEnabled(LogLevel.Debug)) { - logger.Debug("Http request timeout : " + httpTimeout); - logger.Debug("Rest request timeout : " + restTimeout); + logger.LogDebug("Http request timeout : " + httpTimeout); + logger.LogDebug("Rest request timeout : " + restTimeout); } CancellationTokenSource childCts = null; @@ -401,12 +402,12 @@ protected override async Task SendAsync(HttpRequestMessage lastException = e; if (cancellationToken.IsCancellationRequested) { - logger.Debug("SF rest request timeout or explicit cancel called."); + logger.LogDebug("SF rest request timeout or explicit cancel called."); cancellationToken.ThrowIfCancellationRequested(); } else if (childCts != null && childCts.Token.IsCancellationRequested) { - logger.Warn("Http request timeout. Retry the request"); + logger.LogWarning("Http request timeout. Retry the request"); totalRetryTime += (int)httpTimeout.TotalSeconds; } else @@ -415,13 +416,13 @@ protected override async Task SendAsync(HttpRequestMessage if (innermostException is AuthenticationException) { - logger.Error("Non-retryable error encountered: ", e); + logger.LogError("Non-retryable error encountered: ", e); throw; } else { //TODO: Should probably check to see if the error is recoverable or transient. - logger.Warn("Error occurred during request, retrying...", e); + logger.LogWarning("Error occurred during request, retrying...", e); } } } @@ -443,12 +444,12 @@ protected override async Task SendAsync(HttpRequestMessage if (response.IsSuccessStatusCode) { - logger.Debug($"Success Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + logger.LogDebug($"Success Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); return response; } else { - logger.Debug($"Failed Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + logger.LogDebug($"Failed Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); bool isRetryable = isRetryableHTTPCode((int)response.StatusCode, forceRetryOn404); if (!isRetryable || disableRetry) @@ -461,20 +462,20 @@ protected override async Task SendAsync(HttpRequestMessage } else { - logger.Info("Response returned was null."); + logger.LogInformation("Response returned was null."); } retryCount++; if ((maxRetryCount > 0) && (retryCount > maxRetryCount)) { - logger.Debug($"stop retry as maxHttpRetries {maxRetryCount} reached"); + logger.LogDebug($"stop retry as maxHttpRetries {maxRetryCount} reached"); if (response != null) { return response; } var errorMessage = $"http request failed and max retry {maxRetryCount} reached.\n"; errorMessage += $"Last exception encountered: {lastException}"; - logger.Error(errorMessage); + logger.LogError(errorMessage); throw new OperationCanceledException(errorMessage); } @@ -483,7 +484,7 @@ protected override async Task SendAsync(HttpRequestMessage requestMessage.RequestUri = updater.Update(errorReason); - logger.Debug($"Sleep {backOffInSec} seconds and then retry the request, retryCount: {retryCount}"); + logger.LogDebug($"Sleep {backOffInSec} seconds and then retry the request, retryCount: {retryCount}"); await Task.Delay(TimeSpan.FromSeconds(backOffInSec), cancellationToken).ConfigureAwait(false); totalRetryTime += backOffInSec; diff --git a/Snowflake.Data/Core/QueryContextCache.cs b/Snowflake.Data/Core/QueryContextCache.cs index 74d041d2b..5b6e67ec3 100644 --- a/Snowflake.Data/Core/QueryContextCache.cs +++ b/Snowflake.Data/Core/QueryContextCache.cs @@ -1,8 +1,9 @@ -using System; +using System; using System.Collections.Generic; using Newtonsoft.Json; using System.Linq; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -75,7 +76,7 @@ internal class QueryContextCache private Dictionary _priorityMap; // Map for priority and QCC private Dictionary _newPriorityMap; // Intermediate map for priority and QCC for current round of merging private SortedSet _cacheSet; // Order data as per priority - private SFLogger _logger = SFLoggerFactory.GetLogger(); + private ILogger _logger = SFLoggerFactory.GetLogger(); public QueryContextCache(int capacity) { @@ -91,7 +92,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) { if (_idMap.ContainsKey(id)) { - _logger.Debug( + _logger.LogDebug( $"Merge with existing id in cache = {id}, priority = {priority}"); // ID found in the cache QueryContextElement qce = _idMap[id]; @@ -124,7 +125,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) // new id if (_priorityMap.ContainsKey(priority)) { - _logger.Debug( + _logger.LogDebug( $"Merge with existing priority in cache = {id}, priority = {priority}"); // Same priority with different id QueryContextElement qce = _priorityMap[priority]; @@ -136,7 +137,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) { // new priority // Add new element in the cache - _logger.Debug( + _logger.LogDebug( $"Adding new QCC item with either id nor priority found in cache id = {id}, priority = {priority}"); QueryContextElement newQCE = new QueryContextElement(id, readTimestamp, priority, context); AddQCE(newQCE); @@ -147,7 +148,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) /** Sync the newPriorityMap with the priorityMap at the end of current round of merge */ public void SyncPriorityMap() { - _logger.Debug( + _logger.LogDebug( $"syncPriorityMap called priorityMap size = {_priorityMap.Count}, newPrioirtyMap size = {_newPriorityMap.Count}"); foreach (KeyValuePair entry in _newPriorityMap) { @@ -163,7 +164,7 @@ public void SyncPriorityMap() */ public void CheckCacheCapacity() { - _logger.Debug( + _logger.LogDebug( $"checkCacheCapacity() called. cacheSet size {_cacheSet.Count} cache capacity {_capacity}"); if (_cacheSet.Count > _capacity) { @@ -175,18 +176,18 @@ public void CheckCacheCapacity() } } - _logger.Debug( + _logger.LogDebug( $"checkCacheCapacity() returns. cacheSet size {_cacheSet.Count} cache capacity {_capacity}"); } /** Clear the cache. */ public void ClearCache() { - _logger.Debug("clearCache() called"); + _logger.LogDebug("clearCache() called"); _idMap.Clear(); _priorityMap.Clear(); _cacheSet.Clear(); - _logger.Debug($"clearCache() returns. Number of entries in cache now {_cacheSet.Count}"); + _logger.LogDebug($"clearCache() returns. Number of entries in cache now {_cacheSet.Count}"); } public void SetCapacity(int cap) @@ -199,7 +200,7 @@ public void SetCapacity(int cap) if (_capacity == cap) return; - _logger.Debug($"set capacity from {_capacity} to {cap}"); + _logger.LogDebug($"set capacity from {_capacity} to {cap}"); _capacity = cap; CheckCacheCapacity(); LogCacheEntries(); @@ -337,11 +338,11 @@ private void ReplaceQCE(QueryContextElement oldQCE, QueryContextElement newQCE) /** Debugging purpose, log the all entries in the cache. */ private void LogCacheEntries() { - if (_logger.IsDebugEnabled()) + if (_logger.IsEnabled(LogLevel.Debug)) { foreach (QueryContextElement elem in _cacheSet) { - _logger.Debug($"Cache Entry: id: {elem.Id} readTimestamp: {elem.ReadTimestamp} priority: {elem.Priority}"); + _logger.LogDebug($"Cache Entry: id: {elem.Id} readTimestamp: {elem.ReadTimestamp} priority: {elem.Priority}"); } } } diff --git a/Snowflake.Data/Core/QueryResultsAwaiter.cs b/Snowflake.Data/Core/QueryResultsAwaiter.cs index 5ea187fbe..65c2f19de 100644 --- a/Snowflake.Data/Core/QueryResultsAwaiter.cs +++ b/Snowflake.Data/Core/QueryResultsAwaiter.cs @@ -8,6 +8,7 @@ using System; using System.Text.RegularExpressions; using Snowflake.Data.Client; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -36,7 +37,7 @@ internal QueryResultsRetryConfig(int asyncNoDataMaxRetry, int[] asyncRetryPatter internal class QueryResultsAwaiter { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); private static readonly Regex UuidRegex = new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); @@ -64,7 +65,7 @@ internal QueryStatus GetQueryStatus(SnowflakeDbConnection connection, string que else { var errorMessage = $"The given query id {queryId} is not valid uuid"; - s_logger.Error(errorMessage); + s_logger.LogError(errorMessage); throw new Exception(errorMessage); } } @@ -79,7 +80,7 @@ internal async Task GetQueryStatusAsync(SnowflakeDbConnection conne else { var errorMessage = $"The given query id {queryId} is not valid uuid"; - s_logger.Error(errorMessage); + s_logger.LogError(errorMessage); throw new Exception(errorMessage); } } @@ -101,7 +102,7 @@ internal async Task RetryUntilQueryResultIsAvailable(SnowflakeDbConnection conne { if (cancellationToken.IsCancellationRequested) { - s_logger.Debug("Cancellation requested for getting results from query id"); + s_logger.LogDebug("Cancellation requested for getting results from query id"); cancellationToken.ThrowIfCancellationRequested(); } @@ -131,7 +132,7 @@ internal async Task RetryUntilQueryResultIsAvailable(SnowflakeDbConnection conne if (noDataCounter > _queryResultsRetryConfig._asyncNoDataMaxRetry) { var errorMessage = "Max retry for no data is reached"; - s_logger.Error(errorMessage); + s_logger.LogError(errorMessage); throw new Exception(errorMessage); } } diff --git a/Snowflake.Data/Core/RestRequester.cs b/Snowflake.Data/Core/RestRequester.cs index 4c2c7ee39..30fa1e415 100644 --- a/Snowflake.Data/Core/RestRequester.cs +++ b/Snowflake.Data/Core/RestRequester.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Snowflake.Data.Client; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -39,7 +40,7 @@ internal interface IMockRestRequester : IRestRequester internal class RestRequester : IRestRequester { - private static SFLogger logger = SFLoggerFactory.GetLogger(); + private static ILogger logger = SFLoggerFactory.GetLogger(); protected HttpClient _HttpClient; @@ -113,18 +114,18 @@ protected virtual async Task SendAsync(HttpRequestMessage m HttpResponseMessage response = null; try { - logger.Debug($"Executing: {sid} {message.Method} {message.RequestUri} HTTP/{message.Version}"); + logger.LogDebug($"Executing: {sid} {message.Method} {message.RequestUri} HTTP/{message.Version}"); response = await _HttpClient .SendAsync(message, HttpCompletionOption.ResponseHeadersRead, linkedCts.Token) .ConfigureAwait(false); if (!response.IsSuccessStatusCode) { - logger.Error($"Failed Response: {sid} {message.Method} {message.RequestUri} StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + logger.LogError($"Failed Response: {sid} {message.Method} {message.RequestUri} StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); } else { - logger.Debug($"Succeeded Response: {sid} {message.Method} {message.RequestUri}"); + logger.LogDebug($"Succeeded Response: {sid} {message.Method} {message.RequestUri}"); } response.EnsureSuccessStatusCode(); diff --git a/Snowflake.Data/Core/SFBindUploader.cs b/Snowflake.Data/Core/SFBindUploader.cs index 6268c724c..cecfc3b7b 100644 --- a/Snowflake.Data/Core/SFBindUploader.cs +++ b/Snowflake.Data/Core/SFBindUploader.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -35,7 +36,7 @@ class SFBindUploader private string requestId; - private SFLogger logger = SFLoggerFactory.GetLogger(); + private ILogger logger = SFLoggerFactory.GetLogger(); private string stagePath; @@ -297,7 +298,7 @@ private void CreateStage() catch (Exception e) { session.SetArrayBindStageThreshold(0); - logger.Error("Failed to create temporary stage for array binds.", e); + logger.LogError("Failed to create temporary stage for array binds.", e); throw; } } @@ -321,7 +322,7 @@ internal async Task CreateStageAsync(CancellationToken cancellationToken) catch (Exception e) { session.SetArrayBindStageThreshold(0); - logger.Error("Failed to create temporary stage for array binds.", e); + logger.LogError("Failed to create temporary stage for array binds.", e); throw; } } diff --git a/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs b/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs index 282c502b1..c41e15581 100755 --- a/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs +++ b/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs @@ -17,12 +17,13 @@ using System.Diagnostics; using Newtonsoft.Json.Serialization; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { class SFBlockingChunkDownloaderV3 : IChunkDownloader { - static private SFLogger logger = SFLoggerFactory.GetLogger(); + static private ILogger logger = SFLoggerFactory.GetLogger(); private List chunkDatas = new List(); @@ -99,7 +100,7 @@ private int GetPrefetchThreads(SFBaseResultSet resultSet) public async Task GetNextChunkAsync() { - logger.Info($"NextChunkToConsume: {nextChunkToConsumeIndex}, NextChunkToDownload: {nextChunkToDownloadIndex}"); + logger.LogInformation($"NextChunkToConsume: {nextChunkToConsumeIndex}, NextChunkToDownload: {nextChunkToDownloadIndex}"); if (nextChunkToConsumeIndex < chunkInfos.Count) { Task chunk = taskQueues[nextChunkToConsumeIndex % prefetchSlot]; @@ -192,7 +193,7 @@ private async Task DownloadChunkAsync(DownloadContextV3 downloa { if ((maxRetry <= 0) || (retryCount < maxRetry)) { - logger.Debug($"Retry {retryCount}/{maxRetry} of parse stream to chunk error: " + e.Message); + logger.LogDebug($"Retry {retryCount}/{maxRetry} of parse stream to chunk error: " + e.Message); retry = true; // reset the chunk before retry in case there could be garbage // data left from last attempt @@ -209,13 +210,13 @@ private async Task DownloadChunkAsync(DownloadContextV3 downloa else { //parse error - logger.Error("Failed retries of parse stream to chunk error: " + e.Message); + logger.LogError("Failed retries of parse stream to chunk error: " + e.Message); throw new Exception("Parse stream to chunk error: " + e.Message); } } } } while (retry); - logger.Info($"Succeed downloading chunk #{chunk.ChunkIndex}"); + logger.LogInformation($"Succeed downloading chunk #{chunk.ChunkIndex}"); return chunk; } diff --git a/Snowflake.Data/Core/SFMultiStatementsResultSet.cs b/Snowflake.Data/Core/SFMultiStatementsResultSet.cs index 18eb4f650..448787632 100644 --- a/Snowflake.Data/Core/SFMultiStatementsResultSet.cs +++ b/Snowflake.Data/Core/SFMultiStatementsResultSet.cs @@ -8,6 +8,7 @@ using Snowflake.Data.Log; using Snowflake.Data.Client; using System.Collections.Generic; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -15,7 +16,7 @@ class SFMultiStatementsResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => curResultSet.ResultFormat; - private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); private string[] resultIds; diff --git a/Snowflake.Data/Core/SFResultSet.cs b/Snowflake.Data/Core/SFResultSet.cs index a7586f2c3..027a24bf8 100755 --- a/Snowflake.Data/Core/SFResultSet.cs +++ b/Snowflake.Data/Core/SFResultSet.cs @@ -9,6 +9,7 @@ using Snowflake.Data.Client; using System.Collections.Generic; using System.Diagnostics; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -16,7 +17,7 @@ class SFResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => ResultFormat.JSON; - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); private readonly int _totalChunkCount; @@ -51,7 +52,7 @@ public SFResultSet(QueryExecResponseData responseData, SFStatement sfStatement, } catch(System.Exception ex) { - s_logger.Error("Result set error queryId="+responseData.queryId, ex); + s_logger.LogError("Result set error queryId="+responseData.queryId, ex); throw; } } @@ -100,7 +101,7 @@ public SFResultSet(PutGetResponseData responseData, SFStatement sfStatement, Can internal void ResetChunkInfo(BaseResultChunk nextChunk) { - s_logger.Debug($"Received chunk #{nextChunk.ChunkIndex + 1} of {_totalChunkCount}"); + s_logger.LogDebug($"Received chunk #{nextChunk.ChunkIndex + 1} of {_totalChunkCount}"); _currentChunk.RowSet = null; _currentChunk = nextChunk; } @@ -116,7 +117,7 @@ internal override async Task NextAsync() { // GetNextChunk could be blocked if download result is not done yet. // So put this piece of code in a seperate task - s_logger.Debug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_logger.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); BaseResultChunk nextChunk = await _chunkDownloader.GetNextChunkAsync().ConfigureAwait(false); @@ -139,7 +140,7 @@ internal override bool Next() if (_chunkDownloader != null) { - s_logger.Debug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_logger.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); BaseResultChunk nextChunk = Task.Run(async() => await (_chunkDownloader.GetNextChunkAsync()).ConfigureAwait(false)).Result; diff --git a/Snowflake.Data/Core/SFResultSetMetaData.cs b/Snowflake.Data/Core/SFResultSetMetaData.cs index bb5f2e819..b37e0fbb6 100755 --- a/Snowflake.Data/Core/SFResultSetMetaData.cs +++ b/Snowflake.Data/Core/SFResultSetMetaData.cs @@ -7,12 +7,13 @@ using System.Data; using Snowflake.Data.Log; using Snowflake.Data.Client; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { class SFResultSetMetaData { - static private readonly SFLogger logger = SFLoggerFactory.GetLogger(); + static private readonly ILogger logger = SFLoggerFactory.GetLogger(); private int columnCount; @@ -92,7 +93,7 @@ internal int GetColumnIndexByName(string targetColumnName) { if (String.Compare(rowType.name, targetColumnName, false) == 0 ) { - logger.Info($"Found column name {targetColumnName} under index {indexCounter}"); + logger.LogInformation($"Found column name {targetColumnName} under index {indexCounter}"); columnNameToIndexCache[targetColumnName] = indexCounter; return indexCounter; } diff --git a/Snowflake.Data/Core/SFStatement.cs b/Snowflake.Data/Core/SFStatement.cs index e84690d54..49a9a712b 100644 --- a/Snowflake.Data/Core/SFStatement.cs +++ b/Snowflake.Data/Core/SFStatement.cs @@ -11,6 +11,7 @@ using System.Threading; using System.Threading.Tasks; using System.Text; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -97,7 +98,7 @@ internal static bool IsAnError(QueryStatus status) class SFStatement { - static private SFLogger logger = SFLoggerFactory.GetLogger(); + static private ILogger logger = SFLoggerFactory.GetLogger(); internal SFSession SfSession { get; set; } @@ -168,7 +169,7 @@ private void AssignQueryRequestId() if (_requestId != null) { - logger.Info("Another query is running."); + logger.LogInformation("Another query is running."); throw new SnowflakeDbException(SFError.STATEMENT_ALREADY_RUNNING_QUERY); } @@ -340,7 +341,7 @@ private void registerQueryCancellationCallback(int timeout, CancellationToken ex catch (Exception ex) { // Prevent an unhandled exception from being thrown - logger.Error("Unable to cancel query.", ex); + logger.LogError("Unable to cancel query.", ex); } }); } @@ -387,7 +388,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti } catch (Exception e) { - logger.Warn("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. {0}", e); + logger.LogWarning("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. {0}", e); } } @@ -421,7 +422,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti if (SessionExpired(response)) { - logger.Info("Ping pong request failed with session expired, trying to renew the session."); + logger.LogInformation("Ping pong request failed with session expired, trying to renew the session."); await SfSession.renewSessionAsync(cancellationToken).ConfigureAwait(false); } else @@ -435,7 +436,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti } catch { - logger.Error("Query execution failed."); + logger.LogError("Query execution failed."); throw; } finally @@ -481,7 +482,7 @@ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, string tri bindings, describeOnly); - logger.Debug("PUT/GET queryId: " + (response.data != null ? response.data.queryId : "Unknown")); + logger.LogDebug("PUT/GET queryId: " + (response.data != null ? response.data.queryId : "Unknown")); SFFileTransferAgent fileTransferAgent = new SFFileTransferAgent(trimmedSql, SfSession, response.data, CancellationToken.None); @@ -497,13 +498,13 @@ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, string tri } catch (SnowflakeDbException ex) { - logger.Error($"Query execution failed, QueryId: {ex.QueryId??"unavailable"}", ex); + logger.LogError($"Query execution failed, QueryId: {ex.QueryId??"unavailable"}", ex); _lastQueryId = ex.QueryId ?? _lastQueryId; throw; } catch (Exception ex) { - logger.Error("Query execution failed.", ex); + logger.LogError("Query execution failed.", ex); throw new SnowflakeDbException(ex, SFError.INTERNAL_ERROR); } } @@ -536,7 +537,7 @@ private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dicti } catch (Exception e) { - logger.Warn( + logger.LogWarning( "Exception encountered trying to upload binds to stage. Attaching binds in payload instead. {0}", e); } @@ -554,7 +555,7 @@ private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dicti } catch (Exception ex) { - logger.Error("Query execution failed.", ex); + logger.LogError("Query execution failed.", ex); if (ex is SnowflakeDbException snowflakeDbException) { _lastQueryId = snowflakeDbException.QueryId ?? _lastQueryId; @@ -620,11 +621,11 @@ internal void Cancel() if (response.success) { - logger.Info("Query cancellation succeed"); + logger.LogInformation("Query cancellation succeed"); } else { - logger.Warn("Query cancellation failed."); + logger.LogWarning("Query cancellation failed."); } CleanUpCancellationTokenSources(); } @@ -681,7 +682,7 @@ internal T ExecuteHelper( if (SessionExpired(response)) { - logger.Info("Ping pong request failed with session expired, trying to renew the session."); + logger.LogInformation("Ping pong request failed with session expired, trying to renew the session."); SfSession.renewSession(); } else @@ -705,7 +706,7 @@ internal T ExecuteHelper( } catch (Exception ex) { - logger.Error("Query execution failed.", ex); + logger.LogError("Query execution failed.", ex); throw; } finally @@ -768,7 +769,7 @@ internal async Task ExecuteAsyncHelper( if (SessionExpired(response)) { - logger.Info("Ping pong request failed with session expired, trying to renew the session."); + logger.LogInformation("Ping pong request failed with session expired, trying to renew the session."); await SfSession.renewSessionAsync(cancellationToken).ConfigureAwait(false); } else @@ -792,7 +793,7 @@ internal async Task ExecuteAsyncHelper( } catch (Exception ex) { - logger.Error("Query execution failed.", ex); + logger.LogError("Query execution failed.", ex); throw; } finally @@ -869,7 +870,7 @@ internal QueryStatus GetQueryStatus(string queryId) } catch { - logger.Error("Query execution failed."); + logger.LogError("Query execution failed."); throw; } finally @@ -924,7 +925,7 @@ internal async Task GetQueryStatusAsync(string queryId, Cancellatio } catch { - logger.Error("Query execution failed."); + logger.LogError("Query execution failed."); throw; } finally @@ -987,7 +988,7 @@ internal static string TrimSql(string originalSql) var trimmedQuery = builder.ToString(); trimmedQuery = trimmedQuery.Trim(); - logger.Debug("Trimmed query : " + trimmedQuery); + logger.LogDebug("Trimmed query : " + trimmedQuery); return trimmedQuery; } diff --git a/Snowflake.Data/Core/Session/ConnectionPoolManager.cs b/Snowflake.Data/Core/Session/ConnectionPoolManager.cs index 09bfa5821..a6ba12e38 100644 --- a/Snowflake.Data/Core/Session/ConnectionPoolManager.cs +++ b/Snowflake.Data/Core/Session/ConnectionPoolManager.cs @@ -11,12 +11,13 @@ using Snowflake.Data.Client; using Snowflake.Data.Core.Tools; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Session { internal sealed class ConnectionPoolManager : IConnectionManager { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); private static readonly Object s_poolsLock = new Object(); private static readonly Exception s_operationNotAvailable = new Exception("You cannot change connection pool parameters for all the pools. Instead you can change it on a particular pool"); private readonly Dictionary _pools; @@ -31,31 +32,31 @@ internal ConnectionPoolManager() public SFSession GetSession(string connectionString, SecureString password) { - s_logger.Debug($"ConnectionPoolManager::GetSession"); + s_logger.LogDebug($"ConnectionPoolManager::GetSession"); return GetPool(connectionString, password).GetSession(); } public Task GetSessionAsync(string connectionString, SecureString password, CancellationToken cancellationToken) { - s_logger.Debug($"ConnectionPoolManager::GetSessionAsync"); + s_logger.LogDebug($"ConnectionPoolManager::GetSessionAsync"); return GetPool(connectionString, password).GetSessionAsync(cancellationToken); } public bool AddSession(SFSession session) { - s_logger.Debug("ConnectionPoolManager::AddSession"); + s_logger.LogDebug("ConnectionPoolManager::AddSession"); return GetPool(session.ConnectionString, session.Password).AddSession(session, true); } public void ReleaseBusySession(SFSession session) { - s_logger.Debug("ConnectionPoolManager::ReleaseBusySession"); + s_logger.LogDebug("ConnectionPoolManager::ReleaseBusySession"); GetPool(session.ConnectionString, session.Password).ReleaseBusySession(session); } public void ClearAllPools() { - s_logger.Debug("ConnectionPoolManager::ClearAllPools"); + s_logger.LogDebug("ConnectionPoolManager::ClearAllPools"); foreach (var sessionPool in _pools.Values) { sessionPool.DestroyPool(); @@ -70,7 +71,7 @@ public void SetMaxPoolSize(int maxPoolSize) public int GetMaxPoolSize() { - s_logger.Debug("ConnectionPoolManager::GetMaxPoolSize"); + s_logger.LogDebug("ConnectionPoolManager::GetMaxPoolSize"); var values = _pools.Values.Select(it => it.GetMaxPoolSize()).Distinct().ToList(); switch (values.Count) { @@ -90,7 +91,7 @@ public void SetTimeout(long connectionTimeout) public long GetTimeout() { - s_logger.Debug("ConnectionPoolManager::GetTimeout"); + s_logger.LogDebug("ConnectionPoolManager::GetTimeout"); var values = _pools.Values.Select(it => it.GetTimeout()).Distinct().ToList(); switch (values.Count) { @@ -105,7 +106,7 @@ public long GetTimeout() public int GetCurrentPoolSize() { - s_logger.Debug("ConnectionPoolManager::GetCurrentPoolSize"); + s_logger.LogDebug("ConnectionPoolManager::GetCurrentPoolSize"); return _pools.Values.Select(it => it.GetCurrentPoolSize()).Sum(); } @@ -116,13 +117,13 @@ public bool SetPooling(bool poolingEnabled) public bool GetPooling() { - s_logger.Debug("ConnectionPoolManager::GetPooling"); + s_logger.LogDebug("ConnectionPoolManager::GetPooling"); return true; // in new pool pooling is always enabled by default, disabling only by connection string parameter } public SessionPool GetPool(string connectionString, SecureString password) { - s_logger.Debug("ConnectionPoolManager::GetPool with connection string and secure password"); + s_logger.LogDebug("ConnectionPoolManager::GetPool with connection string and secure password"); var poolKey = GetPoolKey(connectionString, password); if (_pools.TryGetValue(poolKey, out var item)) @@ -138,7 +139,7 @@ public SessionPool GetPool(string connectionString, SecureString password) poolCreatedWhileWaitingOnLock.ValidateSecurePassword(password); return poolCreatedWhileWaitingOnLock; } - s_logger.Info($"Creating new pool"); + s_logger.LogInformation($"Creating new pool"); var pool = SessionPool.CreateSessionPool(connectionString, password); _pools.Add(poolKey, pool); return pool; @@ -147,7 +148,7 @@ public SessionPool GetPool(string connectionString, SecureString password) public SessionPool GetPool(string connectionString) { - s_logger.Debug("ConnectionPoolManager::GetPool with connection string"); + s_logger.LogDebug("ConnectionPoolManager::GetPool with connection string"); return GetPool(connectionString, null); } diff --git a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs deleted file mode 100644 index 51a402bf1..000000000 --- a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using System.IO; -using System.Runtime.InteropServices; -using Mono.Unix; -using Mono.Unix.Native; -using Snowflake.Data.Configuration; -using Snowflake.Data.Core.Tools; -using Snowflake.Data.Log; - -namespace Snowflake.Data.Core -{ - internal class EasyLoggingStarter - { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); - - private readonly EasyLoggingConfigProvider _easyLoggingConfigProvider; - - private readonly EasyLoggerManager _easyLoggerManager; - - private readonly UnixOperations _unixOperations; - - private readonly DirectoryOperations _directoryOperations; - - private readonly EnvironmentOperations _environmentOperations; - - private readonly object _lockForExclusiveInit = new object(); - - private EasyLoggingInitTrialParameters _initTrialParameters = null; - - public static readonly EasyLoggingStarter Instance = new EasyLoggingStarter(EasyLoggingConfigProvider.Instance, - EasyLoggerManager.Instance, UnixOperations.Instance, DirectoryOperations.Instance, EnvironmentOperations.Instance); - - internal EasyLoggingStarter( - EasyLoggingConfigProvider easyLoggingConfigProvider, - EasyLoggerManager easyLoggerManager, - UnixOperations unixOperations, - DirectoryOperations directoryOperations, - EnvironmentOperations environmentOperations) - { - _easyLoggingConfigProvider = easyLoggingConfigProvider; - _easyLoggerManager = easyLoggerManager; - _unixOperations = unixOperations; - _directoryOperations = directoryOperations; - _environmentOperations = environmentOperations; - } - - internal EasyLoggingStarter() - { - } - - public virtual void Init(string configFilePathFromConnectionString) - { - lock (_lockForExclusiveInit) - { - if (!AllowedToInitialize(configFilePathFromConnectionString)) - { - return; - } - if (string.IsNullOrEmpty(configFilePathFromConnectionString)) - { - s_logger.Info($"Attempting to enable easy logging without a config file specified from connection string"); - } - else - { - s_logger.Info($"Attempting to enable easy logging using config file specified from connection string: {configFilePathFromConnectionString}"); - } - var config = _easyLoggingConfigProvider.ProvideConfig(configFilePathFromConnectionString); - if (config == null) - { - _initTrialParameters = new EasyLoggingInitTrialParameters(configFilePathFromConnectionString); - return; - } - var logLevel = GetLogLevel(config.CommonProps.LogLevel); - var logPath = GetLogPath(config.CommonProps.LogPath); - s_logger.Info($"LogLevel set to {logLevel}"); - s_logger.Info($"LogPath set to {logPath}"); - _easyLoggerManager.ReconfigureEasyLogging(logLevel, logPath); - _initTrialParameters = new EasyLoggingInitTrialParameters(configFilePathFromConnectionString); - } - } - - internal void Reset(EasyLoggingLogLevel logLevel) - { - lock (_lockForExclusiveInit) - { - _initTrialParameters = null; - _easyLoggerManager.ResetEasyLogging(logLevel); - } - } - - private bool AllowedToInitialize(string configFilePathFromConnectionString) - { - var everTriedToInitialize = _initTrialParameters != null; - var triedToInitializeWithoutConfigFile = everTriedToInitialize && !_initTrialParameters.IsConfigFilePathGiven(); - var isGivenConfigFilePath = !string.IsNullOrEmpty(configFilePathFromConnectionString); - var isAllowedToInitialize = !everTriedToInitialize || (triedToInitializeWithoutConfigFile && isGivenConfigFilePath); - if (!isAllowedToInitialize && _initTrialParameters.HasDifferentConfigPath(configFilePathFromConnectionString)) - { - s_logger.Warn($"Easy logging will not be configured for CLIENT_CONFIG_FILE={configFilePathFromConnectionString} because it was previously configured for a different client config"); - } - - return isAllowedToInitialize; - } - - private EasyLoggingLogLevel GetLogLevel(string logLevel) - { - if (string.IsNullOrEmpty(logLevel)) - { - s_logger.Warn("LogLevel in client config not found. Using default value: OFF"); - return EasyLoggingLogLevel.Off; - } - return EasyLoggingLogLevelExtensions.From(logLevel); - } - - private string GetLogPath(string logPath) - { - var logPathOrDefault = logPath; - if (string.IsNullOrEmpty(logPath)) - { - s_logger.Warn("LogPath in client config not found. Using home directory as a default value"); - logPathOrDefault = HomeDirectoryProvider.HomeDirectory(_environmentOperations); - if (string.IsNullOrEmpty(logPathOrDefault)) - { - throw new Exception("No log path found for easy logging. Home directory is not configured and log path is not provided"); - } - } - var pathWithDotnetSubdirectory = Path.Combine(logPathOrDefault, "dotnet"); - if (!_directoryOperations.Exists(pathWithDotnetSubdirectory)) - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - _directoryOperations.CreateDirectory(pathWithDotnetSubdirectory); - } - else - { - if (!Directory.Exists(logPathOrDefault)) - { - Directory.CreateDirectory(logPathOrDefault); - } - var createDirResult = _unixOperations.CreateDirectoryWithPermissions(pathWithDotnetSubdirectory, - FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR); - if (createDirResult != 0) - { - s_logger.Error($"Failed to create logs directory: {pathWithDotnetSubdirectory}"); - throw new Exception("Failed to create logs directory"); - } - } - } - CheckDirPermissionsOnlyAllowUser(pathWithDotnetSubdirectory); - - return pathWithDotnetSubdirectory; - } - - private void CheckDirPermissionsOnlyAllowUser(string dirPath) - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - return; - - var dirPermissions = _unixOperations.GetDirPermissions(dirPath); - if (dirPermissions != FileAccessPermissions.UserReadWriteExecute) - { - s_logger.Warn($"Access permission for the logs directory is currently " + - $"{UnixFilePermissionsConverter.ConvertFileAccessPermissionsToInt(dirPermissions)} " + - $"and is potentially accessible to users other than the owner of the logs directory"); - } - } - } - - internal class EasyLoggingInitTrialParameters - { - private readonly string _configFilePathFromConnectionString; - - public EasyLoggingInitTrialParameters( - string configFilePathFromConnectionString) - { - _configFilePathFromConnectionString = configFilePathFromConnectionString; - } - - public bool IsConfigFilePathGiven() - { - return _configFilePathFromConnectionString != null; - } - - public bool HasDifferentConfigPath(string configFilePath) - { - return IsConfigFilePathGiven() - && configFilePath != null - && _configFilePathFromConnectionString != configFilePath; - } - } -} diff --git a/Snowflake.Data/Core/Session/SFSession.cs b/Snowflake.Data/Core/Session/SFSession.cs index b6a0ebf79..8e5577481 100755 --- a/Snowflake.Data/Core/Session/SFSession.cs +++ b/Snowflake.Data/Core/Session/SFSession.cs @@ -16,6 +16,7 @@ using System.Text.RegularExpressions; using Snowflake.Data.Core.Session; using Snowflake.Data.Core.Tools; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -23,7 +24,7 @@ public class SFSession { public const int SF_SESSION_EXPIRED_CODE = 390112; - private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetLogger(); private static readonly Regex APPLICATION_REGEX = new Regex(@"^[A-Za-z]([A-Za-z0-9.\-_]){1,50}$"); @@ -67,8 +68,6 @@ public class SFSession private int arrayBindStageThreshold = 0; internal int masterValidityInSeconds = 0; - private readonly EasyLoggingStarter _easyLoggingStarter = EasyLoggingStarter.Instance; - private long _startTime = 0; internal string ConnectionString { get; } internal SecureString Password { get; } @@ -114,9 +113,9 @@ internal void ProcessLoginResponse(LoginResponse authnResponse) UpdateSessionParameterMap(authnResponse.data.nameValueParameter); if (_disableQueryContextCache) { - logger.Debug("Query context cache disabled."); + logger.LogDebug("Query context cache disabled."); } - logger.Debug($"Session opened: {sessionId}"); + logger.LogDebug($"Session opened: {sessionId}"); _startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } else @@ -127,7 +126,7 @@ internal void ProcessLoginResponse(LoginResponse authnResponse) authnResponse.message, ""); - logger.Error("Authentication failed", e); + logger.LogError("Authentication failed", e); throw e; } } @@ -158,16 +157,8 @@ internal Uri BuildLoginUrl() /// A string in the form of "key1=value1;key2=value2" internal SFSession( String connectionString, - SecureString password) : this(connectionString, password, EasyLoggingStarter.Instance) - { - } - - internal SFSession( - String connectionString, - SecureString password, - EasyLoggingStarter easyLoggingStarter) + SecureString password) { - _easyLoggingStarter = easyLoggingStarter; ConnectionString = connectionString; Password = password; properties = SFSessionProperties.ParseConnectionString(ConnectionString, Password); @@ -184,8 +175,6 @@ internal SFSession( _HttpClient = HttpUtil.Instance.GetHttpClient(httpClientConfig); restRequester = new RestRequester(_HttpClient); _poolConfig = extractedProperties.BuildConnectionPoolConfig(); - properties.TryGetValue(SFSessionProperty.CLIENT_CONFIG_FILE, out var easyLoggingConfigFile); - _easyLoggingStarter.Init(easyLoggingConfigFile); properties.TryGetValue(SFSessionProperty.QUERY_TAG, out _queryTag); _maxRetryCount = extractedProperties.maxHttpRetries; _maxRetryTimeout = extractedProperties.retryTimeout; @@ -193,12 +182,12 @@ internal SFSession( } catch (SnowflakeDbException e) { - logger.Error("Unable to initialize session ", e); + logger.LogError("Unable to initialize session ", e); throw; } catch (Exception e) { - logger.Error("Unable to initialize session ", e); + logger.LogError("Unable to initialize session ", e); throw new SnowflakeDbException(e, SnowflakeDbException.CONNECTION_FAILURE_SSTATE, SFError.INVALID_CONNECTION_STRING, @@ -251,7 +240,7 @@ internal Uri BuildUri(string path, Dictionary queryParams = null internal virtual void Open() { - logger.Debug("Open Session"); + logger.LogDebug("Open Session"); if (authenticator == null) { @@ -263,7 +252,7 @@ internal virtual void Open() internal virtual async Task OpenAsync(CancellationToken cancellationToken) { - logger.Debug("Open Session Async"); + logger.LogDebug("Open Session Async"); if (authenticator == null) { @@ -277,7 +266,7 @@ internal void close() { // Nothing to do if the session is not open if (!IsEstablished()) return; - logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + logger.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); PostCloseSession(closeSessionRequest, restRequester); @@ -288,7 +277,7 @@ internal void CloseNonBlocking() { // Nothing to do if the session is not open if (!IsEstablished()) return; - logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + logger.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); Task.Run(() => PostCloseSession(closeSessionRequest, restRequester)); @@ -299,19 +288,19 @@ internal async Task CloseAsync(CancellationToken cancellationToken) { // Nothing to do if the session is not open if (!IsEstablished()) return; - logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + logger.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); - logger.Debug($"Closing session async"); + logger.LogDebug($"Closing session async"); var response = await restRequester.PostAsync(closeSessionRequest, cancellationToken).ConfigureAwait(false); if (!response.success) { - logger.Error($"Failed to close session {sessionId}, error ignored. Code: {response.code} Message: {response.message}"); + logger.LogError($"Failed to close session {sessionId}, error ignored. Code: {response.code} Message: {response.message}"); } - logger.Debug($"Session closed: {sessionId}"); + logger.LogDebug($"Session closed: {sessionId}"); sessionToken = null; } @@ -319,18 +308,18 @@ private static void PostCloseSession(SFRestRequest closeSessionRequest, IRestReq { try { - logger.Debug($"Closing session"); + logger.LogDebug($"Closing session"); var response = restRequester.Post(closeSessionRequest); if (!response.success) { - logger.Error($"Failed to close session: {closeSessionRequest.sid}, error ignored. Code: {response.code} Message: {response.message}"); + logger.LogError($"Failed to close session: {closeSessionRequest.sid}, error ignored. Code: {response.code} Message: {response.message}"); } - logger.Debug($"Session closed: {closeSessionRequest.sid}"); + logger.LogDebug($"Session closed: {closeSessionRequest.sid}"); } catch (Exception) { - logger.Error($"Failed to close session: {closeSessionRequest.sid}, because of exception."); + logger.LogError($"Failed to close session: {closeSessionRequest.sid}, because of exception."); throw; } } @@ -354,13 +343,13 @@ private SFRestRequest PrepareCloseSessionRequest() internal void renewSession() { - logger.Info("Renew the session."); + logger.LogInformation("Renew the session."); var response = restRequester.Post(getRenewSessionRequest()); if (!response.success) { SnowflakeDbException e = new SnowflakeDbException("", response.code, response.message, sessionId); - logger.Error($"Renew session (ID: {sessionId}) failed", e); + logger.LogError($"Renew session (ID: {sessionId}) failed", e); throw e; } else @@ -372,7 +361,7 @@ internal void renewSession() internal async Task renewSessionAsync(CancellationToken cancellationToken) { - logger.Info("Renew the session."); + logger.LogInformation("Renew the session."); var response = await restRequester.PostAsync( getRenewSessionRequest(), @@ -382,7 +371,7 @@ await restRequester.PostAsync( { SnowflakeDbException e = new SnowflakeDbException("", response.code, response.message, sessionId); - logger.Error($"Renew session (ID: {sessionId}) failed", e); + logger.LogError($"Renew session (ID: {sessionId}) failed", e); throw e; } else @@ -430,7 +419,7 @@ internal SFRestRequest BuildTimeoutRestRequest(Uri uri, Object body) internal void UpdateSessionParameterMap(List parameterList) { - logger.Debug("Update parameter map"); + logger.LogDebug("Update parameter map"); // with HTAP parameter removal parameters might not returned // query response if (parameterList is null) @@ -578,7 +567,7 @@ public void SetArrayBindStageThreshold(int arrayBindStageThreshold) internal void heartbeat() { - logger.Debug("heartbeat"); + logger.LogDebug("heartbeat"); bool retry = false; if (IsEstablished()) @@ -599,16 +588,16 @@ internal void heartbeat() }; var response = restRequester.Post(heartBeatSessionRequest); - logger.Debug("heartbeat response=" + response); + logger.LogDebug("heartbeat response=" + response); if (response.success) { - logger.Debug("SFSession::heartbeat success, session token did not expire."); + logger.LogDebug("SFSession::heartbeat success, session token did not expire."); } else { if (response.code == SF_SESSION_EXPIRED_CODE) { - logger.Debug($"SFSession ::heartbeat Session ID: {sessionId} session token expired and retry heartbeat"); + logger.LogDebug($"SFSession ::heartbeat Session ID: {sessionId} session token expired and retry heartbeat"); try { renewSession(); @@ -621,12 +610,12 @@ internal void heartbeat() // the heart beat, it's possible that the session get // closed when sending renew request and caused exception // thrown from renewSession(), simply ignore that - logger.Error($"renew session (ID: {sessionId}) failed.", ex); + logger.LogError($"renew session (ID: {sessionId}) failed.", ex); } } else { - logger.Error($"heartbeat failed for session ID: {sessionId}."); + logger.LogError($"heartbeat failed for session ID: {sessionId}."); } } retry = false; diff --git a/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs b/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs index 2d818f8c8..a398507e2 100644 --- a/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs +++ b/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs @@ -5,6 +5,7 @@ using Snowflake.Data.Core.Session; using Snowflake.Data.Core.Tools; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -21,7 +22,7 @@ internal class SFSessionHttpClientProperties public const bool DefaultPoolingEnabled = true; public const int DefaultMaxHttpRetries = 7; public static readonly TimeSpan DefaultRetryTimeout = TimeSpan.FromSeconds(300); - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); internal bool validateDefaultParameters; internal bool clientSessionKeepAlive; @@ -68,11 +69,11 @@ private void DisablePoolingIfNotExplicitlyEnabled(SFSessionProperties properties if (!properties.IsPoolingEnabledValueProvided && _poolingEnabled) { _poolingEnabled = false; - s_logger.Info($"Disabling connection pooling for {authenticationDescription} authentication"); + s_logger.LogInformation($"Disabling connection pooling for {authenticationDescription} authentication"); } else if (properties.IsPoolingEnabledValueProvided && _poolingEnabled) { - s_logger.Warn($"Connection pooling is enabled for {authenticationDescription} authentication which is not recommended"); + s_logger.LogWarning($"Connection pooling is enabled for {authenticationDescription} authentication which is not recommended"); } } @@ -101,16 +102,16 @@ private void ValidateConnectionTimeout() { if (TimeoutHelper.IsZeroLength(connectionTimeout)) { - s_logger.Warn("Connection timeout provided is 0. Timeout will be infinite"); + s_logger.LogWarning("Connection timeout provided is 0. Timeout will be infinite"); connectionTimeout = TimeoutHelper.Infinity(); } else if (TimeoutHelper.IsInfinite(connectionTimeout)) { - s_logger.Warn("Connection timeout provided is negative. Timeout will be infinite."); + s_logger.LogWarning("Connection timeout provided is negative. Timeout will be infinite."); } if (!TimeoutHelper.IsInfinite(connectionTimeout) && connectionTimeout < DefaultRetryTimeout) { - s_logger.Warn($"Connection timeout provided is less than recommended minimum value of {DefaultRetryTimeout}"); + s_logger.LogWarning($"Connection timeout provided is less than recommended minimum value of {DefaultRetryTimeout}"); } } @@ -118,17 +119,17 @@ private void ValidateRetryTimeout() { if (retryTimeout.TotalMilliseconds > 0 && retryTimeout < DefaultRetryTimeout) { - s_logger.Warn($"Max retry timeout provided is less than the allowed minimum value of {DefaultRetryTimeout}"); + s_logger.LogWarning($"Max retry timeout provided is less than the allowed minimum value of {DefaultRetryTimeout}"); retryTimeout = DefaultRetryTimeout; } else if (TimeoutHelper.IsZeroLength(retryTimeout)) { - s_logger.Warn($"Max retry timeout provided is 0. Timeout will be infinite"); + s_logger.LogWarning($"Max retry timeout provided is 0. Timeout will be infinite"); retryTimeout = TimeoutHelper.Infinity(); } else if (TimeoutHelper.IsInfinite(retryTimeout)) { - s_logger.Warn($"Max retry timeout provided is negative. Timeout will be infinite"); + s_logger.LogWarning($"Max retry timeout provided is negative. Timeout will be infinite"); } } @@ -136,7 +137,7 @@ private void ShortenConnectionTimeoutByRetryTimeout() { if (!TimeoutHelper.IsInfinite(retryTimeout) && retryTimeout < connectionTimeout) { - s_logger.Warn($"Connection timeout greater than retry timeout. Setting connection time same as retry timeout"); + s_logger.LogWarning($"Connection timeout greater than retry timeout. Setting connection time same as retry timeout"); connectionTimeout = retryTimeout; } } @@ -145,13 +146,13 @@ private void ValidateHttpRetries() { if (maxHttpRetries > 0 && maxHttpRetries < DefaultMaxHttpRetries) { - s_logger.Warn($"Max retry count provided is less than the allowed minimum value of {DefaultMaxHttpRetries}"); + s_logger.LogWarning($"Max retry count provided is less than the allowed minimum value of {DefaultMaxHttpRetries}"); maxHttpRetries = DefaultMaxHttpRetries; } else if (maxHttpRetries == 0) { - s_logger.Warn($"Max retry count provided is 0. Retry count will be infinite"); + s_logger.LogWarning($"Max retry count provided is 0. Retry count will be infinite"); } } @@ -171,7 +172,7 @@ private void ValidateWaitingForSessionIdleTimeout() } if (TimeoutHelper.IsZeroLength(_waitingForSessionIdleTimeout)) { - s_logger.Warn("Waiting for idle session timeout is 0. There will be no waiting for idle session"); + s_logger.LogWarning("Waiting for idle session timeout is 0. There will be no waiting for idle session"); } } diff --git a/Snowflake.Data/Core/Session/SFSessionProperty.cs b/Snowflake.Data/Core/Session/SFSessionProperty.cs index 07896ae14..e35f1d3d6 100644 --- a/Snowflake.Data/Core/Session/SFSessionProperty.cs +++ b/Snowflake.Data/Core/Session/SFSessionProperty.cs @@ -14,6 +14,7 @@ using System.Text; using System.Text.RegularExpressions; using Snowflake.Data.Core.Tools; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -126,7 +127,7 @@ class SFSessionPropertyAttr : Attribute class SFSessionProperties : Dictionary { - private static SFLogger logger = SFLoggerFactory.GetLogger(); + private static ILogger logger = SFLoggerFactory.GetLogger(); internal string ConnectionStringWithoutSecrets { get; set; } @@ -171,7 +172,7 @@ public override bool Equals(object obj) } catch (InvalidCastException) { - logger.Warn("Invalid casting to SFSessionProperties"); + logger.LogWarning("Invalid casting to SFSessionProperties"); return false; } } @@ -183,7 +184,7 @@ public override int GetHashCode() internal static SFSessionProperties ParseConnectionString(string connectionString, SecureString password) { - logger.Info("Start parsing connection string."); + logger.LogInformation("Start parsing connection string."); var builder = new DbConnectionStringBuilder(); try { @@ -191,7 +192,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin } catch (ArgumentException e) { - logger.Warn("Invalid connectionString", e); + logger.LogWarning("Invalid connectionString", e); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_STRING, e.Message); @@ -215,7 +216,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin } catch (ArgumentException) { - logger.Debug($"Property {keys[i]} not found ignored."); + logger.LogDebug($"Property {keys[i]} not found ignored."); } } @@ -231,7 +232,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin catch (Exception e) { // The useProxy setting is not a valid boolean value - logger.Error("Unable to connect", e); + logger.LogError("Unable to connect", e); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_STRING, e.Message); @@ -273,15 +274,15 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin if (!allowUnderscoresInHost && compliantAccountName.Contains('_')) { compliantAccountName = compliantAccountName.Replace('_', '-'); - logger.Info($"Replacing _ with - in the account name. Old: {properties[SFSessionProperty.ACCOUNT]}, new: {compliantAccountName}."); + logger.LogInformation($"Replacing _ with - in the account name. Old: {properties[SFSessionProperty.ACCOUNT]}, new: {compliantAccountName}."); } var hostName = $"{compliantAccountName}.snowflakecomputing.com"; // Remove in case it's here but empty properties.Remove(SFSessionProperty.HOST); properties.Add(SFSessionProperty.HOST, hostName); - logger.Info($"Compose host name: {hostName}"); + logger.LogInformation($"Compose host name: {hostName}"); } - logger.Info(ResolveConnectionAreaMessage(properties[SFSessionProperty.HOST])); + logger.LogInformation(ResolveConnectionAreaMessage(properties[SFSessionProperty.HOST])); // Trim the account name to remove the region and cloud platform if any were provided // because the login request data does not expect region and cloud information to be @@ -312,7 +313,7 @@ private static void ValidateAuthenticator(SFSessionProperties properties) if (!knownAuthenticators.Contains(authenticator) && !(authenticator.Contains(OktaAuthenticator.AUTH_NAME) && authenticator.StartsWith("https://"))) { var error = $"Unknown authenticator: {authenticator}"; - logger.Error(error); + logger.LogError(error); throw new SnowflakeDbException(SFError.UNKNOWN_AUTHENTICATOR, authenticator); } } @@ -405,7 +406,7 @@ private static void ValidateAccountDomain(SFSessionProperties properties) return; if (IsAccountRegexMatched(account)) return; - logger.Error($"Invalid account {account}"); + logger.LogError($"Invalid account {account}"); throw new SnowflakeDbException( new Exception("Invalid account"), SFError.INVALID_CONNECTION_PARAMETER_VALUE, @@ -427,14 +428,14 @@ private static void CheckSessionProperties(SFSessionProperties properties) !properties.ContainsKey(sessionProperty)) { SnowflakeDbException e = new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY, sessionProperty); - logger.Error("Missing connection property", e); + logger.LogError("Missing connection property", e); throw e; } if (IsRequired(sessionProperty, properties) && string.IsNullOrEmpty(properties[sessionProperty])) { SnowflakeDbException e = new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY, sessionProperty); - logger.Error("Empty connection property", e); + logger.LogError("Empty connection property", e); throw e; } @@ -442,7 +443,7 @@ private static void CheckSessionProperties(SFSessionProperties properties) string defaultVal = sessionProperty.GetAttribute().defaultValue; if (defaultVal != null && !properties.ContainsKey(sessionProperty)) { - logger.Debug($"Session property {sessionProperty} set to default value: {defaultVal}"); + logger.LogDebug($"Session property {sessionProperty} set to default value: {defaultVal}"); properties.Add(sessionProperty, defaultVal); } } @@ -463,13 +464,13 @@ private static void ValidateFileTransferMaxBytesInMemoryProperty(SFSessionProper } catch (Exception e) { - logger.Error($"Value for parameter {propertyName} could not be parsed"); + logger.LogError($"Value for parameter {propertyName} could not be parsed"); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_PARAMETER_VALUE, maxBytesInMemoryString, propertyName); } if (maxBytesInMemory <= 0) { - logger.Error($"Value for parameter {propertyName} should be greater than 0"); + logger.LogError($"Value for parameter {propertyName} should be greater than 0"); throw new SnowflakeDbException( new Exception($"Value for parameter {propertyName} should be greater than 0"), SFError.INVALID_CONNECTION_PARAMETER_VALUE, maxBytesInMemoryString, propertyName); @@ -529,7 +530,7 @@ private static bool ParseAllowUnderscoresInHost(SFSessionProperties properties) } catch (Exception e) { - logger.Warn("Unable to parse property 'allowUnderscoresInHost'", e); + logger.LogWarning("Unable to parse property 'allowUnderscoresInHost'", e); } return allowUnderscoresInHost; diff --git a/Snowflake.Data/Core/Session/SessionPool.cs b/Snowflake.Data/Core/Session/SessionPool.cs index de66c2240..885b263ce 100644 --- a/Snowflake.Data/Core/Session/SessionPool.cs +++ b/Snowflake.Data/Core/Session/SessionPool.cs @@ -11,12 +11,13 @@ using Snowflake.Data.Client; using Snowflake.Data.Core.Tools; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Session { sealed class SessionPool : IDisposable { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); private readonly object _sessionPoolLock = new object(); private static ISessionFactory s_sessionFactory = new SessionFactory(); @@ -63,9 +64,9 @@ private SessionPool(string connectionString, SecureString password, ConnectionPo internal static SessionPool CreateSessionPool(string connectionString, SecureString password) { - s_logger.Debug("Creating a connection pool"); + s_logger.LogDebug("Creating a connection pool"); var extracted = ExtractConfig(connectionString, password); - s_logger.Debug("Creating a connection pool identified by: " + extracted.Item2); + s_logger.LogDebug("Creating a connection pool identified by: " + extracted.Item2); return new SessionPool(connectionString, password, extracted.Item1, extracted.Item2); } @@ -88,7 +89,7 @@ internal static ISessionFactory SessionFactory private void CleanExpiredSessions() { - s_logger.Debug("SessionPool::CleanExpiredSessions" + PoolIdentification()); + s_logger.LogDebug("SessionPool::CleanExpiredSessions" + PoolIdentification()); lock (_sessionPoolLock) { var timeNow = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); @@ -115,7 +116,7 @@ internal static Tuple ExtractConfig(string connect } catch (Exception exception) { - s_logger.Error("Failed to extract pool configuration", exception); + s_logger.LogError("Failed to extract pool configuration", exception); throw; } } @@ -125,7 +126,7 @@ internal void ValidateSecurePassword(SecureString password) if (!ExtractPassword(Password).Equals(ExtractPassword(password))) { var errorMessage = "Could not get a pool because of password mismatch"; - s_logger.Error(errorMessage + PoolIdentification()); + s_logger.LogError(errorMessage + PoolIdentification()); throw new Exception(errorMessage); } } @@ -135,7 +136,7 @@ private string ExtractPassword(SecureString password) => internal SFSession GetSession(string connStr, SecureString password) { - s_logger.Debug("SessionPool::GetSession" + PoolIdentification()); + s_logger.LogDebug("SessionPool::GetSession" + PoolIdentification()); if (!GetPooling()) return NewNonPoolingSession(connStr, password); var sessionOrCreateTokens = GetIdleSession(connStr); @@ -150,7 +151,7 @@ internal SFSession GetSession(string connStr, SecureString password) internal async Task GetSessionAsync(string connStr, SecureString password, CancellationToken cancellationToken) { - s_logger.Debug("SessionPool::GetSessionAsync" + PoolIdentification()); + s_logger.LogDebug("SessionPool::GetSessionAsync" + PoolIdentification()); if (!GetPooling()) return await NewNonPoolingSessionAsync(connStr, password, cancellationToken).ConfigureAwait(false); var sessionOrCreateTokens = GetIdleSession(connStr); @@ -181,7 +182,7 @@ private void WarnAboutOverridenConfig() { if (IsConfigOverridden() && GetPooling() && IsMultiplePoolsVersion()) { - s_logger.Warn("Providing a connection from a pool for which technical configuration has been overriden by the user"); + s_logger.LogWarning("Providing a connection from a pool for which technical configuration has been overriden by the user"); } } @@ -199,22 +200,22 @@ internal void SetSessionPoolEventHandler(ISessionPoolEventHandler sessionPoolEve private SessionOrCreationTokens GetIdleSession(string connStr) { - s_logger.Debug("SessionPool::GetIdleSession" + PoolIdentification()); + s_logger.LogDebug("SessionPool::GetIdleSession" + PoolIdentification()); lock (_sessionPoolLock) { if (_waitingForIdleSessionQueue.IsAnyoneWaiting()) { - s_logger.Debug("SessionPool::GetIdleSession - someone is already waiting for a session, request is going to be queued" + PoolIdentification()); + s_logger.LogDebug("SessionPool::GetIdleSession - someone is already waiting for a session, request is going to be queued" + PoolIdentification()); } else { var session = ExtractIdleSession(connStr); if (session != null) { - s_logger.Debug("SessionPool::GetIdleSession - no thread was waiting for a session, an idle session was retrieved from the pool" + PoolIdentification()); + s_logger.LogDebug("SessionPool::GetIdleSession - no thread was waiting for a session, an idle session was retrieved from the pool" + PoolIdentification()); return new SessionOrCreationTokens(session); } - s_logger.Debug("SessionPool::GetIdleSession - no thread was waiting for a session, but could not find any idle session available in the pool" + PoolIdentification()); + s_logger.LogDebug("SessionPool::GetIdleSession - no thread was waiting for a session, but could not find any idle session available in the pool" + PoolIdentification()); var sessionsCount = AllowedNumberOfNewSessionCreations(1); if (sessionsCount > 0) { @@ -244,7 +245,7 @@ private int AllowedNumberOfNewSessionCreations(int atLeastCount) if (!IsMultiplePoolsVersion()) { if (atLeastCount > 0) - s_logger.Debug($"SessionPool - creating of new sessions is not limited"); + s_logger.LogDebug($"SessionPool - creating of new sessions is not limited"); return atLeastCount; // we are either in old pool or there is no pooling } var currentSize = GetCurrentPoolSize(); @@ -253,10 +254,10 @@ private int AllowedNumberOfNewSessionCreations(int atLeastCount) var maxSessionsToCreate = _poolConfig.MaxPoolSize - currentSize; var sessionsNeeded = Math.Max(_poolConfig.MinPoolSize - currentSize, atLeastCount); var sessionsToCreate = Math.Min(sessionsNeeded, maxSessionsToCreate); - s_logger.Debug($"SessionPool - allowed to create {sessionsToCreate} sessions, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); + s_logger.LogDebug($"SessionPool - allowed to create {sessionsToCreate} sessions, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); return sessionsToCreate; } - s_logger.Debug($"SessionPool - not allowed to create a session, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); + s_logger.LogDebug($"SessionPool - not allowed to create a session, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); return 0; } @@ -266,7 +267,7 @@ private SFSession WaitForSession(string connStr) { if (TimeoutHelper.IsInfinite(_poolConfig.WaitingForIdleSessionTimeout)) throw new Exception("WaitingForIdleSessionTimeout cannot be infinite"); - s_logger.Info($"SessionPool::WaitForSession for {(long) _poolConfig.WaitingForIdleSessionTimeout.TotalMilliseconds} ms timeout" + PoolIdentification()); + s_logger.LogInformation($"SessionPool::WaitForSession for {(long) _poolConfig.WaitingForIdleSessionTimeout.TotalMilliseconds} ms timeout" + PoolIdentification()); _sessionPoolEventHandler.OnWaitingForSessionStarted(this); var beforeWaitingTimeMillis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); long nowTimeMillis = beforeWaitingTimeMillis; @@ -277,25 +278,25 @@ private SFSession WaitForSession(string connStr) var successful = _waitingForIdleSessionQueue.Wait((int) timeoutLeftMillis, CancellationToken.None); if (successful) { - s_logger.Debug($"SessionPool::WaitForSession - woken with a session granted" + PoolIdentification()); + s_logger.LogDebug($"SessionPool::WaitForSession - woken with a session granted" + PoolIdentification()); _sessionPoolEventHandler.OnWaitingForSessionSuccessful(this); lock (_sessionPoolLock) { var session = ExtractIdleSession(connStr); if (session != null) { - s_logger.Debug("SessionPool::WaitForSession - provided an idle session" + PoolIdentification()); + s_logger.LogDebug("SessionPool::WaitForSession - provided an idle session" + PoolIdentification()); return session; } } } else { - s_logger.Debug("SessionPool::WaitForSession - woken without a session granted" + PoolIdentification()); + s_logger.LogDebug("SessionPool::WaitForSession - woken without a session granted" + PoolIdentification()); } nowTimeMillis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } - s_logger.Info("SessionPool::WaitForSession - could not find any idle session available withing a given timeout" + PoolIdentification()); + s_logger.LogInformation("SessionPool::WaitForSession - could not find any idle session available withing a given timeout" + PoolIdentification()); throw WaitingFailedException(); } @@ -317,7 +318,7 @@ private SFSession ExtractIdleSession(string connStr) } else { - s_logger.Debug($"reuse pooled session with sid {session.sessionId}" + PoolIdentification()); + s_logger.LogDebug($"reuse pooled session with sid {session.sessionId}" + PoolIdentification()); _busySessionsCounter.Increase(); return session; } @@ -331,19 +332,19 @@ private SFSession NewNonPoolingSession(String connectionString, SecureString pas private SFSession NewSession(String connectionString, SecureString password, SessionCreationToken sessionCreationToken) { - s_logger.Debug("SessionPool::NewSession" + PoolIdentification()); + s_logger.LogDebug("SessionPool::NewSession" + PoolIdentification()); try { var session = s_sessionFactory.NewSession(connectionString, password); session.Open(); - s_logger.Debug("SessionPool::NewSession - opened" + PoolIdentification()); + s_logger.LogDebug("SessionPool::NewSession - opened" + PoolIdentification()); if (GetPooling() && !_underDestruction) { lock (_sessionPoolLock) { _sessionCreationTokenCounter.RemoveToken(sessionCreationToken); _busySessionsCounter.Increase(); - s_logger.Debug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); + s_logger.LogDebug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); } } _sessionPoolEventHandler.OnNewSessionCreated(this); @@ -358,7 +359,7 @@ private SFSession NewSession(String connectionString, SecureString password, Ses { lock (_sessionPoolLock) { - s_logger.Debug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); + s_logger.LogDebug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); } } if (e is SnowflakeDbException) @@ -379,7 +380,7 @@ private Task NewNonPoolingSessionAsync( private Task NewSessionAsync(String connectionString, SecureString password, SessionCreationToken sessionCreationToken, CancellationToken cancellationToken) { - s_logger.Debug("SessionPool::NewSessionAsync" + PoolIdentification()); + s_logger.LogDebug("SessionPool::NewSessionAsync" + PoolIdentification()); var session = s_sessionFactory.NewSession(connectionString, password); return session .OpenAsync(cancellationToken) @@ -392,7 +393,7 @@ private Task NewSessionAsync(String connectionString, SecureString pa { lock (_sessionPoolLock) { - s_logger.Debug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); + s_logger.LogDebug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); } } } @@ -414,7 +415,7 @@ private Task NewSessionAsync(String connectionString, SecureString pa { _sessionCreationTokenCounter.RemoveToken(sessionCreationToken); _busySessionsCounter.Increase(); - s_logger.Debug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); + s_logger.LogDebug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); } } @@ -427,19 +428,19 @@ private Task NewSessionAsync(String connectionString, SecureString pa internal void ReleaseBusySession(SFSession session) { - s_logger.Debug("SessionPool::ReleaseBusySession" + PoolIdentification()); + s_logger.LogDebug("SessionPool::ReleaseBusySession" + PoolIdentification()); SessionPoolState poolState; lock (_sessionPoolLock) { _busySessionsCounter.Decrease(); poolState = GetCurrentState(); } - s_logger.Debug($"After releasing a busy session from the pool {poolState}" + PoolIdentification()); + s_logger.LogDebug($"After releasing a busy session from the pool {poolState}" + PoolIdentification()); } internal bool AddSession(SFSession session, bool ensureMinPoolSize) { - s_logger.Debug("SessionPool::AddSession" + PoolIdentification()); + s_logger.LogDebug("SessionPool::AddSession" + PoolIdentification()); if (!GetPooling() || _underDestruction) return false; @@ -448,7 +449,7 @@ internal bool AddSession(SFSession session, bool ensureMinPoolSize) session.SessionPropertiesChanged && _poolConfig.ChangedSession == ChangedSessionBehavior.Destroy) { - s_logger.Debug($"Session returning to pool was changed. Destroying the session: {session.sessionId}."); + s_logger.LogDebug($"Session returning to pool was changed. Destroying the session: {session.sessionId}."); session.SetPooling(false); } @@ -481,7 +482,7 @@ private Tuple> ReturnSessionToPool(SFSession se ? RegisterSessionCreationsWhenReturningSessionToPool() : SessionOrCreationTokens.s_emptySessionCreationTokenList; var poolState = GetCurrentState(); - s_logger.Debug($"Could not return session to pool {poolState}" + PoolIdentification()); + s_logger.LogDebug($"Could not return session to pool {poolState}" + PoolIdentification()); return Tuple.Create(false, sessionCreationTokens); } } @@ -496,13 +497,13 @@ private Tuple> ReturnSessionToPool(SFSession se ? RegisterSessionCreationsWhenReturningSessionToPool() : SessionOrCreationTokens.s_emptySessionCreationTokenList; var poolState = GetCurrentState(); - s_logger.Debug($"Could not return session to pool {poolState}" + PoolIdentification()); + s_logger.LogDebug($"Could not return session to pool {poolState}" + PoolIdentification()); return Tuple.Create(false, sessionCreationTokens); } var poolStateBeforeReturningToPool = GetCurrentState(); if (poolStateBeforeReturningToPool.Count() >= _poolConfig.MaxPoolSize) { - s_logger.Warn($"Pool is full - unable to add session with sid {session.sessionId} {poolStateBeforeReturningToPool}"); + s_logger.LogWarning($"Pool is full - unable to add session with sid {session.sessionId} {poolStateBeforeReturningToPool}"); return Tuple.Create(false, SessionOrCreationTokens.s_emptySessionCreationTokenList); } _idleSessions.Add(session); @@ -511,14 +512,14 @@ private Tuple> ReturnSessionToPool(SFSession se ? RegisterSessionCreationsWhenReturningSessionToPool() : SessionOrCreationTokens.s_emptySessionCreationTokenList; var poolStateAfterReturningToPool = GetCurrentState(); - s_logger.Debug($"returned session with sid {session.sessionId} to pool {poolStateAfterReturningToPool}" + PoolIdentification()); + s_logger.LogDebug($"returned session with sid {session.sessionId} to pool {poolStateAfterReturningToPool}" + PoolIdentification()); return Tuple.Create(true, sessionCreationTokensAfterReturningToPool); } } internal void DestroyPool() { - s_logger.Debug("SessionPool::DestroyPool" + PoolIdentification()); + s_logger.LogDebug("SessionPool::DestroyPool" + PoolIdentification()); lock (_sessionPoolLock) { _underDestruction = true; @@ -531,7 +532,7 @@ internal void DestroyPool() internal void DestroyPoolAsync() { - s_logger.Debug("SessionPool::DestroyPoolAsync" + PoolIdentification()); + s_logger.LogDebug("SessionPool::DestroyPoolAsync" + PoolIdentification()); lock (_sessionPoolLock) { _underDestruction = true; @@ -544,7 +545,7 @@ internal void DestroyPoolAsync() internal void ClearSessions() { - s_logger.Debug($"SessionPool::ClearSessions" + PoolIdentification()); + s_logger.LogDebug($"SessionPool::ClearSessions" + PoolIdentification()); lock (_sessionPoolLock) { _busySessionsCounter.Reset(); @@ -555,7 +556,7 @@ internal void ClearSessions() internal void ClearIdleSessions() { - s_logger.Debug("SessionPool::ClearIdleSessions" + PoolIdentification()); + s_logger.LogDebug("SessionPool::ClearIdleSessions" + PoolIdentification()); lock (_sessionPoolLock) { foreach (SFSession session in _idleSessions) @@ -568,7 +569,7 @@ internal void ClearIdleSessions() internal async void ClearIdleSessionsAsync() { - s_logger.Debug("SessionPool::ClearIdleSessionsAsync" + PoolIdentification()); + s_logger.LogDebug("SessionPool::ClearIdleSessionsAsync" + PoolIdentification()); IEnumerable idleSessionsCopy; lock (_sessionPoolLock) { @@ -583,7 +584,7 @@ internal async void ClearIdleSessionsAsync() public void SetMaxPoolSize(int size) { - s_logger.Debug($"SessionPool::SetMaxPoolSize({size})" + PoolIdentification()); + s_logger.LogDebug($"SessionPool::SetMaxPoolSize({size})" + PoolIdentification()); _poolConfig.MaxPoolSize = size; _configOverriden = true; } @@ -614,7 +615,7 @@ public long GetConnectionTimeout() public void SetTimeout(long seconds) { - s_logger.Debug($"SessionPool::SetTimeout({seconds})" + PoolIdentification()); + s_logger.LogDebug($"SessionPool::SetTimeout({seconds})" + PoolIdentification()); var timeout = seconds < 0 ? TimeoutHelper.Infinity() : TimeSpan.FromSeconds(seconds); _poolConfig.ExpirationTimeout = timeout; _configOverriden = true; @@ -643,7 +644,7 @@ public SessionPoolState GetCurrentState() public bool SetPooling(bool isEnable) { - s_logger.Info($"SessionPool::SetPooling({isEnable})" + PoolIdentification()); + s_logger.LogInformation($"SessionPool::SetPooling({isEnable})" + PoolIdentification()); if (_poolConfig.PoolingEnabled == isEnable) return false; _poolConfig.PoolingEnabled = isEnable; diff --git a/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs b/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs index f9092c7f9..11492787e 100644 --- a/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs +++ b/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs @@ -3,12 +3,13 @@ using System.Text.RegularExpressions; using Snowflake.Data.Core.Tools; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Session { internal class SessionPropertiesWithDefaultValuesExtractor { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); private static readonly Regex s_timeoutFormatRegex = new Regex(@"^(-)?[0-9]{1,10}[mM]?[sS]?$"); private readonly SFSessionProperties _propertiesDictionary; @@ -71,7 +72,7 @@ public T ExtractPropertyWithDefaultValue( var valueString = _propertiesDictionary[property]; if (string.IsNullOrEmpty(valueString)) { - s_logger.Warn($"Parameter {property} not defined. Using a default value: {defaultValue}"); + s_logger.LogWarning($"Parameter {property} not defined. Using a default value: {defaultValue}"); return defaultValue; } if (!preExtractValidation(valueString)) @@ -87,10 +88,10 @@ public T ExtractPropertyWithDefaultValue( { if (_failOnWrongValue) { - s_logger.Error($"Invalid value of parameter {property}. Error: {e}"); + s_logger.LogError($"Invalid value of parameter {property}. Error: {e}"); throw new Exception($"Invalid value of parameter {property}", e); } - s_logger.Warn($"Invalid value of parameter {property}. Using a default a default value: {defaultValue}"); + s_logger.LogWarning($"Invalid value of parameter {property}. Using a default a default value: {defaultValue}"); return defaultValue; } if (!postExtractValidation(value)) @@ -107,10 +108,10 @@ private TResult handleFailedValidation( { if (_failOnWrongValue) { - s_logger.Error($"Invalid value of parameter {property}: {value}"); + s_logger.LogError($"Invalid value of parameter {property}: {value}"); throw new Exception($"Invalid value of parameter {property}"); } - s_logger.Warn($"Invalid value of parameter {property}. Using a default value: {defaultValue}"); + s_logger.LogWarning($"Invalid value of parameter {property}. Using a default value: {defaultValue}"); return defaultValue; } diff --git a/Snowflake.Data/Core/Tools/Diagnostics.cs b/Snowflake.Data/Core/Tools/Diagnostics.cs index dc0b19593..2552d6994 100644 --- a/Snowflake.Data/Core/Tools/Diagnostics.cs +++ b/Snowflake.Data/Core/Tools/Diagnostics.cs @@ -5,15 +5,16 @@ using System.Runtime.InteropServices; using System.Text; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Tools { internal class Diagnostics { private const int PadRight = -25; - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); - public static void LogDiagnostics() => s_logger.Info(GetDiagnosticInfo()); + public static void LogDiagnostics() => s_logger.LogInformation(GetDiagnosticInfo()); private static string GetDiagnosticInfo() { diff --git a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs index 1f1959986..daee66d65 100644 --- a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs +++ b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs @@ -5,13 +5,14 @@ using System; using System.IO; using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Tools { internal class EnvironmentOperations { public static readonly EnvironmentOperations Instance = new EnvironmentOperations(); - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); public virtual string GetEnvironmentVariable(string variable) { @@ -29,7 +30,7 @@ public virtual string GetExecutionDirectory() var directoryName = string.IsNullOrEmpty(executablePath) ? null : Path.GetDirectoryName(executablePath); if (string.IsNullOrEmpty(directoryName)) { - s_logger.Warn("Unable to determine execution directory"); + s_logger.LogWarning("Unable to determine execution directory"); return null; } return directoryName; diff --git a/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs b/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs index a39a0987c..a273363b4 100644 --- a/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs +++ b/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs @@ -1,15 +1,16 @@ -/* +/* * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. */ using Snowflake.Data.Log; using System; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Tools { internal class HomeDirectoryProvider { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); public static string HomeDirectory(EnvironmentOperations _environmentOperations) { try @@ -23,7 +24,7 @@ public static string HomeDirectory(EnvironmentOperations _environmentOperations) } catch (Exception e) { - s_logger.Error($"Error while trying to retrieve the home directory: {e}"); + s_logger.LogError($"Error while trying to retrieve the home directory: {e}"); return null; } } diff --git a/Snowflake.Data/Logger/EasyLoggerManager.cs b/Snowflake.Data/Logger/EasyLoggerManager.cs deleted file mode 100644 index ca7800f0e..000000000 --- a/Snowflake.Data/Logger/EasyLoggerManager.cs +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using System.IO; -using System.Linq; -using log4net; -using log4net.Appender; -using log4net.Layout; -using Snowflake.Data.Configuration; - -namespace Snowflake.Data.Log -{ - internal class EasyLoggerManager - { - public static readonly EasyLoggerManager Instance = new EasyLoggerManager(); - - private readonly object _lockForExclusiveConfigure = new object(); - - private const string AppenderPrefix = "SFEasyLogging"; - - private readonly EasyLoggingLevelMapper _levelMapper = EasyLoggingLevelMapper.Instance; - - public virtual void ReconfigureEasyLogging(EasyLoggingLogLevel easyLoggingLogLevel, string logsPath) - { - var log4netLevel = _levelMapper.ToLog4NetLevel(easyLoggingLogLevel); - lock (_lockForExclusiveConfigure) - { - var repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); - var rootLogger = (log4net.Repository.Hierarchy.Logger)repository.GetLogger("Snowflake.Data"); - rootLogger.Level = log4netLevel; - var appender = string.Equals(logsPath, "STDOUT", StringComparison.OrdinalIgnoreCase) - ? AddConsoleAppender(rootLogger) - : AddRollingFileAppender(rootLogger, logsPath); - RemoveOtherEasyLoggingAppenders(rootLogger, appender); - repository.RaiseConfigurationChanged(EventArgs.Empty); - } - } - - internal void ResetEasyLogging(EasyLoggingLogLevel easyLoggingLogLevel) - { - var log4netLevel = _levelMapper.ToLog4NetLevel(easyLoggingLogLevel); - lock (_lockForExclusiveConfigure) - { - var repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); - var rootLogger = (log4net.Repository.Hierarchy.Logger)repository.GetLogger("Snowflake.Data"); - rootLogger.Level = log4netLevel; - RemoveOtherEasyLoggingAppenders(rootLogger, null); - repository.RaiseConfigurationChanged(EventArgs.Empty); - } - } - - internal static bool HasEasyLoggingAppender() - { - var repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); - var rootLogger = (log4net.Repository.Hierarchy.Logger)repository.GetLogger("Snowflake.Data"); - return rootLogger.Appenders.ToArray().Any(IsEasyLoggingAppender); - } - - private static void RemoveOtherEasyLoggingAppenders(log4net.Repository.Hierarchy.Logger logger, IAppender appender) - { - var existingAppenders = logger.Appenders.ToArray(); - foreach (var existingAppender in existingAppenders) - { - if (IsEasyLoggingAppender(existingAppender) && existingAppender != appender) - { - logger.RemoveAppender(existingAppender); - } - } - } - - private static IAppender AddRollingFileAppender(log4net.Repository.Hierarchy.Logger logger, - string directoryPath) - { - var patternLayout = PatternLayout(); - var randomFileName = $"snowflake_dotnet_{Path.GetRandomFileName()}"; - var logFileName = randomFileName.Substring(0, randomFileName.Length - 4) + ".log"; - var appender = new RollingFileAppender - { - Layout = patternLayout, - AppendToFile = true, - File = Path.Combine(directoryPath, logFileName), - Name = $"{AppenderPrefix}RollingFileAppender", - StaticLogFileName = true, - RollingStyle = RollingFileAppender.RollingMode.Size, - MaximumFileSize = "1GB", - MaxSizeRollBackups = 2, - PreserveLogFileNameExtension = true, - LockingModel = new FileAppender.MinimalLock() - }; - appender.ActivateOptions(); - logger.AddAppender(appender); - return appender; - } - - private static bool IsEasyLoggingAppender(IAppender appender) - { - if (appender.GetType() == typeof(ConsoleAppender)) - { - var consoleAppender = (ConsoleAppender)appender; - return consoleAppender.Name != null && consoleAppender.Name.StartsWith(AppenderPrefix); - } - - if (appender.GetType() == typeof(RollingFileAppender)) - { - var rollingFileAppender = (RollingFileAppender)appender; - return rollingFileAppender.Name != null && rollingFileAppender.Name.StartsWith(AppenderPrefix); - } - - return false; - } - - private static IAppender AddConsoleAppender(log4net.Repository.Hierarchy.Logger logger) - { - var patternLayout = PatternLayout(); - var appender = new ConsoleAppender() - { - Layout = patternLayout, - Name = $"{AppenderPrefix}ConsoleAppender" - }; - appender.ActivateOptions(); - logger.AddAppender(appender); - return appender; - } - - private static PatternLayout PatternLayout() - { - var patternLayout = new PatternLayout - { - ConversionPattern = "[%date] [%t] [%-5level] [%logger] %message%newline" - }; - patternLayout.ActivateOptions(); - return patternLayout; - } - } -} diff --git a/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs b/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs deleted file mode 100644 index 609265e30..000000000 --- a/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using log4net.Core; -using Snowflake.Data.Configuration; - -namespace Snowflake.Data.Log -{ - internal class EasyLoggingLevelMapper - { - public static readonly EasyLoggingLevelMapper Instance = new EasyLoggingLevelMapper(); - - public Level ToLog4NetLevel(EasyLoggingLogLevel level) - { - switch (level) - { - case EasyLoggingLogLevel.Off: return Level.Off; - case EasyLoggingLogLevel.Error: return Level.Error; - case EasyLoggingLogLevel.Warn: return Level.Warn; - case EasyLoggingLogLevel.Info: return Level.Info; - case EasyLoggingLogLevel.Debug: return Level.Debug; - case EasyLoggingLogLevel.Trace: return Level.Trace; - default: throw new Exception("Unknown log level"); - } - } - } -} \ No newline at end of file diff --git a/Snowflake.Data/Logger/Log4netImpl.cs b/Snowflake.Data/Logger/Log4netImpl.cs deleted file mode 100755 index 4a9ec00d6..000000000 --- a/Snowflake.Data/Logger/Log4netImpl.cs +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. - */ - -using log4net; -using System; - -namespace Snowflake.Data.Log -{ - // Default implementation for SFLogger - - class Log4NetImpl : SFLogger - { - private readonly ILog logger; - - public Log4NetImpl(ILog logger) - { - this.logger = logger; - } - - public bool IsDebugEnabled() - { - return logger.IsDebugEnabled; - } - - public bool IsInfoEnabled() - { - return logger.IsInfoEnabled; - } - - public bool IsWarnEnabled() - { - return logger.IsWarnEnabled; - } - - public bool IsErrorEnabled() - { - return logger.IsErrorEnabled; - } - - public bool IsFatalEnabled() - { - return logger.IsFatalEnabled; - } - - public void Debug(string msg, Exception ex = null) - { - msg = SecretDetector.MaskSecrets(msg).maskedText; - logger.Debug(msg, ex); - } - - public void Info(string msg, Exception ex = null) - { - msg = SecretDetector.MaskSecrets(msg).maskedText; - logger.Info(msg, ex); - } - - public void Warn(string msg, Exception ex = null) - { - msg = SecretDetector.MaskSecrets(msg).maskedText; - logger.Warn(msg, ex); - } - - - public void Error(string msg, Exception ex = null) - { - msg = SecretDetector.MaskSecrets(msg).maskedText; - logger.Error(msg, ex); - } - - public void Fatal(string msg, Exception ex = null) - { - msg = SecretDetector.MaskSecrets(msg).maskedText; - logger.Fatal(msg, ex); - } - } - -} diff --git a/Snowflake.Data/Logger/SFLogger.cs b/Snowflake.Data/Logger/SFLogger.cs deleted file mode 100755 index 28a8a5b3c..000000000 --- a/Snowflake.Data/Logger/SFLogger.cs +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Snowflake.Data.Log -{ - interface SFLogger - { - bool IsDebugEnabled(); - - bool IsInfoEnabled(); - - bool IsWarnEnabled(); - - bool IsErrorEnabled(); - - bool IsFatalEnabled(); - - void Debug(string msg, Exception ex = null); - - void Info(string msg, Exception ex = null); - - void Warn(string msg, Exception ex = null); - - void Error(string msg, Exception ex = null); - - void Fatal(string msg, Exception ex = null); - } - - enum LoggingEvent - { - DEBUG, INFO, WARN, ERROR, FATAL - } - -} \ No newline at end of file diff --git a/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs b/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs index 2508c4309..0f6e49f5f 100644 --- a/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs +++ b/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs @@ -1,62 +1,28 @@ /* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ - - using System; + +using Microsoft.Extensions.Logging; +using System; namespace Snowflake.Data.Log { // Empty implementation of SFLogger // Used when SFLoggerFactory.disableLogger() is called. - class SFLoggerEmptyImpl : SFLogger + class SFLoggerEmptyImpl : ILogger { - public bool IsDebugEnabled() - { - return false; - } - - public bool IsInfoEnabled() + IDisposable ILogger.BeginScope(TState state) { - return false; + throw new NotImplementedException(); } - public bool IsWarnEnabled() + bool ILogger.IsEnabled(LogLevel logLevel) { return false; } - public bool IsErrorEnabled() - { - return false; - } - - public bool IsFatalEnabled() - { - return false; - } - - public void Debug(string msg, Exception ex) - { - return; - } - - public void Info(string msg, Exception ex) - { - return; - } - - public void Warn(string msg, Exception ex) - { - return; - } - - public void Error(string msg, Exception ex) - { - return; - } - - public void Fatal(string msg, Exception ex) + void ILogger.Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { return; } diff --git a/Snowflake.Data/Logger/SFLoggerFactory.cs b/Snowflake.Data/Logger/SFLoggerFactory.cs index e38440167..7b06454cf 100755 --- a/Snowflake.Data/Logger/SFLoggerFactory.cs +++ b/Snowflake.Data/Logger/SFLoggerFactory.cs @@ -2,50 +2,55 @@ * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ -using log4net; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Log { - class SFLoggerFactory + public class SFLoggerFactory { - private static bool isLoggerEnabled = true; + private static bool isLoggerEnabled = false; - private static SFLogger logger = null; + private static ILogger logger = null; private SFLoggerFactory() { } - public static void disableLogger() + public static void DisableLogger() { isLoggerEnabled = false; } - public static void enableLogger() + public static void EnableLogger() { isLoggerEnabled = true; } - public static void useDefaultLogger() + public static void UseDefaultLogger() { logger = null; } - public static void Instance(SFLogger customLogger) + public static void SetCustomLogger(ILogger customLogger) { logger = customLogger; } - public static SFLogger GetLogger() + internal static ILogger GetLogger() { // If true, return the default/specified logger if (isLoggerEnabled) { - // If no logger specified, use the default logger: log4net + // If no logger specified, use the default logger: Microsoft's console logger if (logger == null) { - ILog loggerL = LogManager.GetLogger(typeof(T)); - return new Log4NetImpl(loggerL); + ILoggerFactory factory = LoggerFactory.Create( + builder => builder + .AddConsole() + .SetMinimumLevel(LogLevel.Trace) + ); + + return factory.CreateLogger(); } return logger; } @@ -56,5 +61,4 @@ public static SFLogger GetLogger() } } } - } diff --git a/Snowflake.Data/Snowflake.Data.csproj b/Snowflake.Data/Snowflake.Data.csproj index 35599c903..a9b97ba88 100644 --- a/Snowflake.Data/Snowflake.Data.csproj +++ b/Snowflake.Data/Snowflake.Data.csproj @@ -22,10 +22,12 @@ + + - + From f0484f602abafc8b100c60f95bc34cef2db338fa Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 8 Nov 2024 16:24:12 -0800 Subject: [PATCH 02/35] SNOW-834781: Refactor/add tests --- .../ConnectionMultiplePoolsAsyncIT.cs | 3 +- .../ConnectionPoolCommonIT.cs | 7 +- .../IntegrationTests/EasyLoggingIT.cs | 124 -------- .../IntegrationTests/SFBindTestIT.cs | 11 +- .../IntegrationTests/SFConnectionIT.cs | 19 +- .../Mock/MockSnowflakeDbConnection.cs | 11 +- Snowflake.Data.Tests/SFBaseTest.cs | 22 +- .../Snowflake.Data.Tests.csproj | 21 ++ Snowflake.Data.Tests/TestLog4Net.config | 20 ++ Snowflake.Data.Tests/TestNLog.config | 23 ++ Snowflake.Data.Tests/TestSerilog.config | 15 + .../EasyLoggingConfigFinderTest.cs | 259 ----------------- .../EasyLoggingConfigParserTest.cs | 132 --------- .../EasyLoggingConfigProviderTest.cs | 58 ---- .../Configuration/EasyLoggingLogLevelTest.cs | 38 --- .../UnitTests/Logger/EasyLoggerManagerTest.cs | 150 ---------- .../Logger/EasyLoggingStarterTest.cs | 274 ------------------ .../UnitTests/Logger/SFLoggerTest.cs | 241 ++++++++++----- .../UnitTests/SFSessionTest.cs | 20 -- .../Util/ConnectingThreads.cs | 23 +- .../Util/DbConnectionExtensions.cs | 7 +- Snowflake.Data.Tests/log4net.config | 20 ++ 22 files changed, 321 insertions(+), 1177 deletions(-) delete mode 100644 Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs create mode 100644 Snowflake.Data.Tests/TestLog4Net.config create mode 100644 Snowflake.Data.Tests/TestNLog.config create mode 100644 Snowflake.Data.Tests/TestSerilog.config delete mode 100644 Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigFinderTest.cs delete mode 100644 Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigParserTest.cs delete mode 100644 Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigProviderTest.cs delete mode 100644 Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingLogLevelTest.cs delete mode 100644 Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs delete mode 100644 Snowflake.Data.Tests/UnitTests/Logger/EasyLoggingStarterTest.cs create mode 100644 Snowflake.Data.Tests/log4net.config diff --git a/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs b/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs index e263cb9d3..0d61e5933 100644 --- a/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs @@ -1,6 +1,7 @@ using System.Data.Common; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; using Snowflake.Data.Client; @@ -17,7 +18,7 @@ namespace Snowflake.Data.Tests.IntegrationTests public class ConnectionMultiplePoolsAsyncIT: SFBaseTestAsync { private readonly PoolConfig _previousPoolConfig = new PoolConfig(); - private readonly SFLogger logger = SFLoggerFactory.GetLogger(); + private readonly ILogger logger = SFLoggerFactory.GetLogger(); [SetUp] public new void BeforeTest() diff --git a/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs b/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs index 9bf78ffbe..db7fd0c20 100644 --- a/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs @@ -11,6 +11,7 @@ using Snowflake.Data.Core.Session; using Snowflake.Data.Log; using Snowflake.Data.Tests.Util; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.IntegrationTests { @@ -20,7 +21,7 @@ namespace Snowflake.Data.Tests.IntegrationTests class ConnectionPoolCommonIT : SFBaseTest { private readonly ConnectionPoolType _connectionPoolTypeUnderTest; - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); private readonly PoolConfig _previousPoolConfig; public ConnectionPoolCommonIT(ConnectionPoolType connectionPoolTypeUnderTest) @@ -38,8 +39,8 @@ public ConnectionPoolCommonIT(ConnectionPoolType connectionPoolTypeUnderTest) { SnowflakeDbConnectionPool.SetPooling(true); } - s_logger.Debug($"---------------- BeforeTest ---------------------"); - s_logger.Debug($"Testing Pool Type: {SnowflakeDbConnectionPool.GetConnectionPoolVersion()}"); + s_logger.LogDebug($"---------------- BeforeTest ---------------------"); + s_logger.LogDebug($"Testing Pool Type: {SnowflakeDbConnectionPool.GetConnectionPoolVersion()}"); } [TearDown] diff --git a/Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs b/Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs deleted file mode 100644 index fd2e79409..000000000 --- a/Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System.Data; -using System.IO; -using System.Runtime.InteropServices; -using Mono.Unix.Native; -using NUnit.Framework; -using Snowflake.Data.Client; -using Snowflake.Data.Configuration; -using Snowflake.Data.Core; -using Snowflake.Data.Log; -using static Snowflake.Data.Tests.UnitTests.Configuration.EasyLoggingConfigGenerator; - -namespace Snowflake.Data.Tests.IntegrationTests -{ - [TestFixture, NonParallelizable] - public class EasyLoggingIT: SFBaseTest - { - private static readonly string s_workingDirectory = Path.Combine(Path.GetTempPath(), "easy_logging_test_configs_", Path.GetRandomFileName()); - - [OneTimeSetUp] - public static void BeforeAll() - { - if (!Directory.Exists(s_workingDirectory)) - { - Directory.CreateDirectory(s_workingDirectory); - } - } - - [OneTimeTearDown] - public static void AfterAll() - { - Directory.Delete(s_workingDirectory, true); - } - - [TearDown] - public static void AfterEach() - { - EasyLoggingStarter.Instance.Reset(EasyLoggingLogLevel.Warn); - } - - [Test] - public void TestEnableEasyLogging() - { - // arrange - var configFilePath = CreateConfigTempFile(s_workingDirectory, Config("WARN", s_workingDirectory)); - using (IDbConnection conn = new SnowflakeDbConnection()) - { - conn.ConnectionString = ConnectionString + $"CLIENT_CONFIG_FILE={configFilePath}"; - - // act - conn.Open(); - - // assert - Assert.IsTrue(EasyLoggerManager.HasEasyLoggingAppender()); - } - } - - [Test] - public void TestFailToEnableEasyLoggingForWrongConfiguration() - { - // arrange - var configFilePath = CreateConfigTempFile(s_workingDirectory, "random config content"); - using (IDbConnection conn = new SnowflakeDbConnection()) - { - conn.ConnectionString = ConnectionString + $"CLIENT_CONFIG_FILE={configFilePath}"; - - // act - var thrown = Assert.Throws(() => conn.Open()); - - // assert - Assert.That(thrown.Message, Does.Contain("Connection string is invalid: Unable to initialize session")); - Assert.IsFalse(EasyLoggerManager.HasEasyLoggingAppender()); - } - } - - [Test] - public void TestFailToEnableEasyLoggingWhenConfigHasWrongPermissions() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Assert.Ignore("skip test on Windows"); - } - - // arrange - var configFilePath = CreateConfigTempFile(s_workingDirectory, Config("WARN", s_workingDirectory)); - Syscall.chmod(configFilePath, FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IWGRP); - using (IDbConnection conn = new SnowflakeDbConnection()) - { - conn.ConnectionString = ConnectionString + $"CLIENT_CONFIG_FILE={configFilePath}"; - - // act - var thrown = Assert.Throws(() => conn.Open()); - - // assert - Assert.That(thrown.Message, Does.Contain("Connection string is invalid: Unable to initialize session")); - Assert.IsFalse(EasyLoggerManager.HasEasyLoggingAppender()); - } - } - - [Test] - public void TestFailToEnableEasyLoggingWhenLogDirectoryNotAccessible() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Assert.Ignore("skip test on Windows"); - } - - // arrange - var configFilePath = CreateConfigTempFile(s_workingDirectory, Config("WARN", "/")); - using (IDbConnection conn = new SnowflakeDbConnection()) - { - conn.ConnectionString = ConnectionString + $"CLIENT_CONFIG_FILE={configFilePath}"; - - // act - var thrown = Assert.Throws(() => conn.Open()); - - // assert - Assert.That(thrown.Message, Does.Contain("Connection string is invalid: Unable to initialize session")); - Assert.That(thrown.InnerException.Message, Does.Contain("Failed to create logs directory")); - Assert.IsFalse(EasyLoggerManager.HasEasyLoggingAppender()); - } - - } - } -} diff --git a/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs index 1683700cb..fce90502b 100755 --- a/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs @@ -15,6 +15,7 @@ using System.Globalization; using System.Collections.Generic; using Snowflake.Data.Tests.Util; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.IntegrationTests { @@ -22,7 +23,7 @@ namespace Snowflake.Data.Tests.IntegrationTests [TestFixture] class SFBindTestIT : SFBaseTest { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); [Test] public void TestArrayBind() @@ -896,7 +897,7 @@ public void TestDateTimeBinding(ResultFormat resultFormat, SFTableType tableType var bindingThreshold = 65280; // when exceeded enforces bindings via file on stage var smallBatchRowCount = 2; var bigBatchRowCount = bindingThreshold / 2; - s_logger.Info(testCase); + s_logger.LogInformation(testCase); using (IDbConnection conn = new SnowflakeDbConnection(ConnectionString)) { @@ -925,7 +926,7 @@ public void TestDateTimeBinding(ResultFormat resultFormat, SFTableType tableType var row = 0; using (var select = conn.CreateCommand($"select id, ts from {TableName} order by id")) { - s_logger.Debug(select.CommandText); + s_logger.LogDebug(select.CommandText); var reader = select.ExecuteReader(); while (reader.Read()) { @@ -956,7 +957,7 @@ private void InsertSingleRecord(IDbConnection conn, string sqlInsert, DbType bin } // Act - s_logger.Info(sqlInsert); + s_logger.LogInformation(sqlInsert); var rowsAffected = insert.ExecuteNonQuery(); // Assert @@ -982,7 +983,7 @@ private void InsertMultipleRecords(IDbConnection conn, string sqlInsert, DbType } // Act - s_logger.Debug(sqlInsert); + s_logger.LogDebug(sqlInsert); var rowsAffected = insert.ExecuteNonQuery(); // Assert diff --git a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs index 6f3c87291..68b96d0c6 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs @@ -21,11 +21,12 @@ namespace Snowflake.Data.Tests.IntegrationTests using Snowflake.Data.Tests.Mock; using System.Runtime.InteropServices; using System.Net.Http; + using Microsoft.Extensions.Logging; [TestFixture] class SFConnectionIT : SFBaseTest { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); [Test] public void TestBasicConnection() @@ -83,14 +84,14 @@ public void TestApplicationName() try { conn.Open(); - s_logger.Debug("{appName}"); + s_logger.LogDebug("{appName}"); Assert.Fail(); } catch (SnowflakeDbException e) { // Expected - s_logger.Debug("Failed opening connection ", e); + s_logger.LogDebug("Failed opening connection ", e); AssertIsConnectionFailure(e); } @@ -127,7 +128,7 @@ public void TestIncorrectUserOrPasswordBasicConnection() catch (SnowflakeDbException e) { // Expected - s_logger.Debug("Failed opening connection ", e); + s_logger.LogDebug("Failed opening connection ", e); AssertIsConnectionFailure(e); } @@ -142,7 +143,7 @@ public void TestConnectionIsNotMarkedAsOpenWhenWasNotCorrectlyOpenedBefore(bool { for (int i = 0; i < 2; ++i) { - s_logger.Debug($"Running try #{i}"); + s_logger.LogDebug($"Running try #{i}"); SnowflakeDbConnection snowflakeConnection = null; try { @@ -168,7 +169,7 @@ public void TestConnectionIsNotMarkedAsOpenWhenWasNotCorrectlyOpenedWithUsingCla { for (int i = 0; i < 2; ++i) { - s_logger.Debug($"Running try #{i}"); + s_logger.LogDebug($"Running try #{i}"); SnowflakeDbConnection snowflakeConnection = null; try { @@ -1559,7 +1560,7 @@ public void TestInvalidProxySettingFromConnectionString() catch (SnowflakeDbException e) { // Expected - s_logger.Debug("Failed opening connection ", e); + s_logger.LogDebug("Failed opening connection ", e); Assert.AreEqual(270001, e.ErrorCode); //Internal error AssertIsConnectionFailure(e); } @@ -1868,7 +1869,7 @@ public void TestKeepAlive() [TestFixture] class SFConnectionITAsync : SFBaseTestAsync { - private static SFLogger logger = SFLoggerFactory.GetLogger(); + private static ILogger logger = SFLoggerFactory.GetLogger(); [Test] @@ -1898,7 +1899,7 @@ public void TestCancelLoginBeforeTimeout() // Cancel the connection because it will never succeed since there is no // connection_timeout defined - logger.Debug("connectionCancelToken.Cancel "); + logger.LogDebug("connectionCancelToken.Cancel "); connectionCancelToken.Cancel(); try diff --git a/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs b/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs index c6d8f0698..0c3d59e1a 100644 --- a/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs +++ b/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs @@ -9,12 +9,13 @@ using System.Data; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.Mock { class MockSnowflakeDbConnection : SnowflakeDbConnection { - private SFLogger logger = SFLoggerFactory.GetLogger(); + private ILogger logger = SFLoggerFactory.GetLogger(); private IMockRestRequester _restRequester; @@ -31,7 +32,7 @@ public MockSnowflakeDbConnection() public override void Open() { - logger.Debug("Open Connection."); + logger.LogDebug("Open Connection."); SetMockSession(); try { @@ -41,7 +42,7 @@ public override void Open() { // Otherwise when Dispose() is called, the close request would timeout. _connectionState = System.Data.ConnectionState.Closed; - logger.Error("Unable to connect", e); + logger.LogError("Unable to connect", e); throw; } OnSessionEstablished(); @@ -61,14 +62,14 @@ public override Task OpenAsync(CancellationToken cancellationToken) // Exception from SfSession.OpenAsync Exception sfSessionEx = previousTask.Exception; _connectionState = ConnectionState.Closed; - logger.Error("Unable to connect", sfSessionEx); + logger.LogError("Unable to connect", sfSessionEx); throw //sfSessionEx.InnerException; new SnowflakeDbException(sfSessionEx, SFError.INTERNAL_ERROR, "Unable to connect"); } if (previousTask.IsCanceled) { _connectionState = ConnectionState.Closed; - logger.Debug("Connection canceled"); + logger.LogDebug("Connection canceled"); } else { diff --git a/Snowflake.Data.Tests/SFBaseTest.cs b/Snowflake.Data.Tests/SFBaseTest.cs index 1e8e13018..390fbf789 100755 --- a/Snowflake.Data.Tests/SFBaseTest.cs +++ b/Snowflake.Data.Tests/SFBaseTest.cs @@ -14,6 +14,7 @@ using Snowflake.Data.Client; using Snowflake.Data.Log; using Snowflake.Data.Tests.Util; +using Microsoft.Extensions.Logging; [assembly:LevelOfParallelism(10)] @@ -57,7 +58,7 @@ public static void TearDownContext() #endif public class SFBaseTestAsync { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); private const string ConnectionStringWithoutAuthFmt = "scheme={0};host={1};port={2};" + "account={3};role={4};db={5};schema={6};warehouse={7}"; @@ -118,7 +119,7 @@ protected void CreateOrReplaceTable(IDbConnection conn, string tableName, string var columnsStr = string.Join(", ", columns); var cmd = conn.CreateCommand(); cmd.CommandText = $"CREATE OR REPLACE {tableType} TABLE {tableName}({columnsStr}) {additionalQueryStr}"; - s_logger.Debug(cmd.CommandText); + s_logger.LogDebug(cmd.CommandText); cmd.ExecuteNonQuery(); _tablesToRemove.Add(tableName); @@ -186,14 +187,19 @@ public static void RecordTestPerformance(string name, TimeSpan time) public void Setup() { #if NETFRAMEWORK - log4net.GlobalContext.Properties["framework"] = "net471"; - log4net.Config.XmlConfigurator.Configure(); - + Environment.SetEnvironmentVariable("net_test_framework", "net471"); #else - log4net.GlobalContext.Properties["framework"] = "net6.0"; - var logRepository = log4net.LogManager.GetRepository(Assembly.GetEntryAssembly()); - log4net.Config.XmlConfigurator.Configure(logRepository, new FileInfo("App.config")); + Environment.SetEnvironmentVariable("net_test_framework", "net6.0"); #endif + ILoggerFactory factory = LoggerFactory.Create( + builder => builder + .AddLog4Net() + .SetMinimumLevel(LogLevel.Debug)); + + var logger = factory.CreateLogger("SFBaseTest"); + SFLoggerFactory.SetCustomLogger(logger); + SFLoggerFactory.EnableLogger(); + var cloud = Environment.GetEnvironmentVariable("snowflake_cloud_env"); Assert.IsTrue(cloud == null || cloud == "AWS" || cloud == "AZURE" || cloud == "GCP", "{0} is not supported. Specify AWS, AZURE or GCP as cloud environment", cloud); diff --git a/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj b/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj index cc895154e..1d08fb783 100644 --- a/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj +++ b/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj @@ -13,10 +13,16 @@ + + + + + + @@ -35,6 +41,21 @@ + + + Always + + + Always + + + Always + + + Always + + + full True diff --git a/Snowflake.Data.Tests/TestLog4Net.config b/Snowflake.Data.Tests/TestLog4Net.config new file mode 100644 index 000000000..784355885 --- /dev/null +++ b/Snowflake.Data.Tests/TestLog4Net.config @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Snowflake.Data.Tests/TestNLog.config b/Snowflake.Data.Tests/TestNLog.config new file mode 100644 index 000000000..85c376043 --- /dev/null +++ b/Snowflake.Data.Tests/TestNLog.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + diff --git a/Snowflake.Data.Tests/TestSerilog.config b/Snowflake.Data.Tests/TestSerilog.config new file mode 100644 index 000000000..65bf5c82c --- /dev/null +++ b/Snowflake.Data.Tests/TestSerilog.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigFinderTest.cs b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigFinderTest.cs deleted file mode 100644 index b23fbbf0e..000000000 --- a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigFinderTest.cs +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using System.IO; -using System.Runtime.InteropServices; -using Mono.Unix; -using Moq; -using NUnit.Framework; -using Snowflake.Data.Configuration; -using Snowflake.Data.Core.Tools; - -namespace Snowflake.Data.Tests.UnitTests.Configuration -{ - [TestFixture] - public class EasyLoggingConfigFinderTest - { - private const string InputConfigFilePath = "input_config.json"; - private const string EnvironmentalConfigFilePath = "environmental_config.json"; - private const string HomeDirectory = "/home/user"; - private const string DriverDirectory = "."; - private static readonly string s_driverConfigFilePath = Path.Combine(DriverDirectory, EasyLoggingConfigFinder.ClientConfigFileName); - private static readonly string s_homeConfigFilePath = Path.Combine(HomeDirectory, EasyLoggingConfigFinder.ClientConfigFileName); - - [ThreadStatic] - private static Mock t_fileOperations; - - [ThreadStatic] - private static Mock t_unixOperations; - - [ThreadStatic] - private static Mock t_environmentOperations; - - [ThreadStatic] - private static EasyLoggingConfigFinder t_finder; - - [SetUp] - public void Setup() - { - t_fileOperations = new Mock(); - t_unixOperations = new Mock(); - t_environmentOperations = new Mock(); - t_finder = new EasyLoggingConfigFinder(t_fileOperations.Object, t_unixOperations.Object, t_environmentOperations.Object); - MockHomeDirectory(); - MockExecutionDirectory(); - } - - [Test] - public void TestThatTakesFilePathFromTheInput() - { - // arrange - MockFileFromEnvironmentalVariable(); - MockFileOnDriverPath(); - MockFileOnHomePath(); - - // act - var filePath = t_finder.FindConfigFilePath(InputConfigFilePath); - - // assert - Assert.AreEqual(InputConfigFilePath, filePath); - t_fileOperations.VerifyNoOtherCalls(); - t_environmentOperations.VerifyNoOtherCalls(); - } - - [Test] - public void TestThatTakesFilePathFromEnvironmentVariableIfInputNotPresent( - [Values(null, "")] string inputFilePath) - { - // arrange - MockFileFromEnvironmentalVariable(); - MockFileOnDriverPath(); - MockFileOnHomePath(); - - // act - var filePath = t_finder.FindConfigFilePath(inputFilePath); - - // assert - Assert.AreEqual(EnvironmentalConfigFilePath, filePath); - } - - [Test] - public void TestThatTakesFilePathFromDriverLocationWhenNoInputParameterNorEnvironmentVariable() - { - // arrange - MockFileOnDriverPath(); - MockFileOnHomePath(); - - // act - var filePath = t_finder.FindConfigFilePath(null); - - // assert - Assert.AreEqual(s_driverConfigFilePath, filePath); - } - - [Test] - public void TestThatTakesFilePathFromHomeLocationWhenNoInputParamEnvironmentVarNorDriverLocation() - { - // arrange - MockFileOnHomePath(); - - // act - var filePath = t_finder.FindConfigFilePath(null); - - // assert - Assert.AreEqual(s_homeConfigFilePath, filePath); - } - - [Test] - public void TestThatTakesFilePathFromHomeDirectoryWhenNoOtherWaysPossible() - { - // arrange - MockFileOnHomePath(); - - // act - var filePath = t_finder.FindConfigFilePath(null); - - // assert - Assert.AreEqual(s_homeConfigFilePath, filePath); - } - - [Test] - public void TestThatConfigFileIsNotUsedIfOthersCanModifyTheConfigFile() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Assert.Ignore("skip test on Windows"); - } - - // arrange - MockFileOnHomePath(); - MockHasFlagReturnsTrue(); - - // act - var thrown = Assert.Throws(() => t_finder.FindConfigFilePath(null)); - - // assert - Assert.IsNotNull(thrown); - Assert.AreEqual(thrown.Message, $"Error due to other users having permission to modify the config file: {s_homeConfigFilePath}"); - } - - [Test] - public void TestThatReturnsNullIfNoWayOfGettingTheFile() - { - // act - var filePath = t_finder.FindConfigFilePath(null); - - // assert - Assert.IsNull(filePath); - } - - [Test] - public void TestThatDoesNotFailWhenSearchForOneOfDirectoriesFails() - { - // arrange - MockHomeDirectoryFails(); - - // act - var filePath = t_finder.FindConfigFilePath(null); - - // assert - Assert.IsNull(filePath); - t_environmentOperations.Verify(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile), Times.Once); - } - - [Test] - public void TestThatDoesNotFailWhenHomeDirectoryReturnsNull() - { - // arrange - MockHomeDirectoryReturnsNull(); - - // act - var filePath = t_finder.FindConfigFilePath(null); - - // assert - Assert.IsNull(filePath); - t_environmentOperations.Verify(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile), Times.Once); - } - - [Test] - public void TestThatDoesNotFailWhenHomeDirectoryDoesNotExist() - { - // arrange - MockFileOnHomePath(); - MockFileOnHomePathDoesNotExist(); - - // act - var filePath = t_finder.FindConfigFilePath(null); - - // assert - Assert.IsNull(filePath); - t_environmentOperations.Verify(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile), Times.Once); - } - - private static void MockHasFlagReturnsTrue() - { - t_unixOperations - .Setup(f => f.CheckFileHasAnyOfPermissions(s_homeConfigFilePath, - It.Is(p => p.Equals(FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite)))) - .Returns(true); - } - - private static void MockHomeDirectory() - { - t_environmentOperations - .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) - .Returns(HomeDirectory); - } - - private static void MockHomeDirectoryFails() - { - t_environmentOperations - .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) - .Throws(() => new Exception("No home directory")); - } - - private static void MockExecutionDirectory() - { - t_environmentOperations - .Setup(e => e.GetExecutionDirectory()) - .Returns(DriverDirectory); - } - - private static void MockFileOnHomePathDoesNotExist() - { - t_fileOperations - .Setup(f => f.Exists(s_homeConfigFilePath)) - .Returns(false); - } - - private static void MockHomeDirectoryReturnsNull() - { - t_environmentOperations - .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) - .Returns((string) null); - } - - private static void MockFileFromEnvironmentalVariable() - { - t_environmentOperations - .Setup(e => e.GetEnvironmentVariable(EasyLoggingConfigFinder.ClientConfigEnvironmentName)) - .Returns(EnvironmentalConfigFilePath); - } - - private static void MockFileOnDriverPath() - { - t_fileOperations - .Setup(f => f.Exists(s_driverConfigFilePath)) - .Returns(true); - } - - private static void MockFileOnHomePath() - { - t_fileOperations - .Setup(f => f.Exists(s_homeConfigFilePath)) - .Returns(true); - } - } -} diff --git a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigParserTest.cs b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigParserTest.cs deleted file mode 100644 index 847d57c51..000000000 --- a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigParserTest.cs +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using System.Collections.Generic; -using System.IO; -using NUnit.Framework; -using Snowflake.Data.Configuration; -using static Snowflake.Data.Tests.UnitTests.Configuration.EasyLoggingConfigGenerator; - -namespace Snowflake.Data.Tests.UnitTests.Configuration -{ - [TestFixture, NonParallelizable] - public class EasyLoggingConfigParserTest - { - private const string NotExistingFilePath = "../../../Resources/EasyLogging/not_existing_config.json"; - private const string LogLevel = "info"; - private const string LogPath = "./test-logs/log_file.log"; - private static readonly string s_workingDirectory = Path.Combine(Path.GetTempPath(), "easy_logging_test_configs_", Path.GetRandomFileName()); - - [OneTimeSetUp] - public static void BeforeAll() - { - if (!Directory.Exists(s_workingDirectory)) - { - Directory.CreateDirectory(s_workingDirectory); - } - } - - [OneTimeTearDown] - public static void AfterAll() - { - Directory.Delete(s_workingDirectory, true); - } - - [Test] - public void TestThatParsesConfigFile() - { - // arrange - var parser = new EasyLoggingConfigParser(); - var configFilePath = CreateConfigTempFile(s_workingDirectory, Config(LogLevel, LogPath)); - - // act - var config = parser.Parse(configFilePath); - - // assert - Assert.IsNotNull(config); - Assert.IsNotNull(config.CommonProps); - Assert.AreEqual(LogLevel, config.CommonProps.LogLevel); - Assert.AreEqual(LogPath, config.CommonProps.LogPath); - } - - [Test, TestCaseSource(nameof(ConfigFilesWithoutValues))] - public void TestThatParsesConfigFileWithNullValues(string filePath) - { - // arrange - var parser = new EasyLoggingConfigParser(); - - // act - var config = parser.Parse(filePath); - - // assert - Assert.IsNotNull(config); - Assert.IsNotNull(config.CommonProps); - Assert.IsNull(config.CommonProps.LogLevel); - Assert.IsNull(config.CommonProps.LogPath); - } - - [Test] - [TestCase(null)] - [TestCase("")] - public void TestThatReturnsNullWhenNothingToParse(string noFilePath) - { - // arrange - var parser = new EasyLoggingConfigParser(); - - // act - var config = parser.Parse(noFilePath); - - // assert - Assert.IsNull(config); - } - - [Test] - public void TestThatFailsWhenTheFileDoesNotExist() - { - // arrange - var parser = new EasyLoggingConfigParser(); - - // act - var thrown = Assert.Throws(() => parser.Parse(NotExistingFilePath)); - - // assert - Assert.IsNotNull(thrown); - Assert.AreEqual("Finding easy logging configuration failed", thrown.Message); - } - - [Test, TestCaseSource(nameof(WrongConfigFiles))] - public void TestThatFailsIfMissingOrInvalidRequiredFields(string filePath) - { - // arrange - var parser = new EasyLoggingConfigParser(); - - // act - var thrown = Assert.Throws(() => parser.Parse(filePath)); - // assert - Assert.IsNotNull(thrown); - Assert.IsTrue(thrown.Message == "Parsing easy logging configuration failed"); - } - - public static IEnumerable ConfigFilesWithoutValues() - { - BeforeAll(); - return new[] - { - CreateConfigTempFile(s_workingDirectory, EmptyCommonConfig), - CreateConfigTempFile(s_workingDirectory, Config(null, null)) - }; - } - - public static IEnumerable WrongConfigFiles() - { - BeforeAll(); - return new[] - { - CreateConfigTempFile(s_workingDirectory, EmptyConfig), - CreateConfigTempFile(s_workingDirectory, Config("unknown", LogPath)), - }; - } - } -} diff --git a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigProviderTest.cs b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigProviderTest.cs deleted file mode 100644 index f61d51503..000000000 --- a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigProviderTest.cs +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using Moq; -using NUnit.Framework; -using Snowflake.Data.Configuration; - -namespace Snowflake.Data.Tests.UnitTests.Configuration -{ - [TestFixture] - public class EasyLoggingConfigProviderTest - { - private const string FilePathFromConnectionString = "/Users/dotnet/config.json"; - private const string FilePathToUse = "/home/config.json"; - - [Test] - public void TestThatProvidesConfiguration() - { - // arrange - var configFinder = new Mock(); - var configParser = new Mock(); - var configProvider = new EasyLoggingConfigProvider(configFinder.Object, configParser.Object); - var config = new ClientConfig(); - configFinder - .Setup(finder => finder.FindConfigFilePath(FilePathFromConnectionString)) - .Returns(FilePathToUse); - configParser - .Setup(parser => parser.Parse(FilePathToUse)) - .Returns(config); - - // act - var result = configProvider.ProvideConfig(FilePathFromConnectionString); - - // assert - Assert.AreSame(config, result); - } - - [Test] - public void TestThatReturnsNullWhenNoConfigurationFound() - { - // arrange - var configFinder = new Mock(); - var configParser = new Mock(); - var configProvider = new EasyLoggingConfigProvider(configFinder.Object, configParser.Object); - configFinder - .Setup(finder => finder.FindConfigFilePath(FilePathFromConnectionString)) - .Returns((string) null); - - // act - var result = configProvider.ProvideConfig(FilePathFromConnectionString); - - // assert - Assert.IsNull(result); - configParser.Verify(parser => parser.Parse(It.IsAny()), Times.Never); - } - } -} diff --git a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingLogLevelTest.cs b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingLogLevelTest.cs deleted file mode 100644 index d61cfaeec..000000000 --- a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingLogLevelTest.cs +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using NUnit.Framework; -using Snowflake.Data.Configuration; - -namespace Snowflake.Data.Tests.UnitTests.Configuration -{ - [TestFixture] - class EasyLoggingLogLevelTest - { - [Test] - [TestCase("OFF", EasyLoggingLogLevel.Off)] - [TestCase("off", EasyLoggingLogLevel.Off)] - [TestCase("iNfO", EasyLoggingLogLevel.Info)] - public void TestThatGetsLogLevelValueIgnoringLetterCase(string loglevelString, EasyLoggingLogLevel expectedLogLevel) - { - // act - var logLevel = EasyLoggingLogLevelExtensions.From(loglevelString); - - // assert - Assert.AreEqual(expectedLogLevel, logLevel); - } - - [Test] - public void TestThatFailsToParseLogLevelFromUnknownValue() - { - // act - var thrown = Assert.Throws(() => EasyLoggingLogLevelExtensions.From("unknown")); - - // assert - Assert.IsNotNull(thrown); - Assert.AreEqual("Requested value 'unknown' was not found.", thrown.Message); - } - } -} diff --git a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs deleted file mode 100644 index 4dfba8c83..000000000 --- a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using NUnit.Framework; -using Snowflake.Data.Configuration; -using Snowflake.Data.Core; -using Snowflake.Data.Log; - -namespace Snowflake.Data.Tests.UnitTests.Logger -{ - [TestFixture, NonParallelizable] - public class EasyLoggerManagerTest - { - - private const string InfoMessage = "Easy logging Info message"; - private const string DebugMessage = "Easy logging Debug message"; - private const string WarnMessage = "Easy logging Warn message"; - private const string ErrorMessage = "Easy logging Error message"; - private const string FatalMessage = "Easy logging Fatal message"; - private static readonly string s_logsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - - [ThreadStatic] - private static string t_directoryLogPath; - - [OneTimeTearDown] - public static void CleanUp() - { - RemoveEasyLoggingLogFiles(); - } - - [SetUp] - public void BeforeEach() - { - t_directoryLogPath = RandomLogsDirectoryPath(); - } - - [TearDown] - public void AfterEach() - { - EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, t_directoryLogPath); - } - - [Test] - public void TestThatChangesLogLevel() - { - // arrange - var logger = SFLoggerFactory.GetLogger(); - EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, t_directoryLogPath); - - // assert - Assert.IsFalse(logger.IsDebugEnabled()); - Assert.IsFalse(logger.IsInfoEnabled()); - Assert.IsTrue(logger.IsWarnEnabled()); - Assert.IsTrue(logger.IsErrorEnabled()); - Assert.IsTrue(logger.IsFatalEnabled()); - - // act - EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Debug, t_directoryLogPath); - - // assert - Assert.IsTrue(logger.IsDebugEnabled()); - Assert.IsTrue(logger.IsInfoEnabled()); - Assert.IsTrue(logger.IsWarnEnabled()); - Assert.IsTrue(logger.IsErrorEnabled()); - Assert.IsTrue(logger.IsFatalEnabled()); - } - - [Test] - public void TestThatLogsToProperFileWithProperLogLevelOnly() - { - // arrange - var logger = SFLoggerFactory.GetLogger(); - EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Info, t_directoryLogPath); - - // act - logger.Debug(DebugMessage); - logger.Info(InfoMessage); - logger.Warn(WarnMessage); - logger.Error(ErrorMessage); - logger.Fatal(FatalMessage); - - // assert - var logLines = File.ReadLines(FindLogFilePath(t_directoryLogPath)); - Assert.That(logLines, Has.Exactly(0).Matches(s => s.Contains(DebugMessage))); - Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(InfoMessage))); - Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(WarnMessage))); - Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(ErrorMessage))); - Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(FatalMessage))); - } - - [Test] - public void TestThatOnlyUnknownFieldsAreLogged() - { - // arrange - string expectedFakeLogField = "fake_log_field"; - string ConfigWithUnknownFields = $@"{{ - ""common"": {{ - ""LOG_LEVEL"": ""warn"", - ""lOg_PaTh"": ""path"", - ""{expectedFakeLogField}_1"": ""abc"", - ""{expectedFakeLogField}_2"": ""123"" - }} - }}"; - var configFilePath = Guid.NewGuid().ToString() + ".json"; - using (var writer = File.CreateText(configFilePath)) - { - writer.Write(ConfigWithUnknownFields); - } - EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, t_directoryLogPath); - var parser = new EasyLoggingConfigParser(); - - // act - parser.Parse(configFilePath); - - // assert - var logLines = File.ReadLines(FindLogFilePath(t_directoryLogPath)); - Assert.That(logLines, Has.Exactly(2).Matches(s => s.Contains($"Unknown field from config: {expectedFakeLogField}"))); - - // cleanup - File.Delete(configFilePath); - } - - private static string RandomLogsDirectoryPath() - { - var randomName = Path.GetRandomFileName(); - return Path.Combine(s_logsDirectory, $"easy_logging_logs_{randomName}", "dotnet"); - } - - private static string FindLogFilePath(string directoryLogPath) - { - Assert.IsTrue(Directory.Exists(directoryLogPath)); - var files = Directory.GetFiles(directoryLogPath); - Assert.AreEqual(1, files.Length); - return files.First(); - } - - private static void RemoveEasyLoggingLogFiles() - { - Directory.GetFiles(s_logsDirectory) - .Where(filePath => filePath.StartsWith(Path.Combine(s_logsDirectory, "easy_logging_logs"))) - .AsParallel() - .ForAll(filePath => File.Delete(filePath)); - } - } -} diff --git a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggingStarterTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggingStarterTest.cs deleted file mode 100644 index 8b1c6ebfe..000000000 --- a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggingStarterTest.cs +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using System.IO; -using System.Runtime.InteropServices; -using Mono.Unix; -using Mono.Unix.Native; -using Moq; -using NUnit.Framework; -using Snowflake.Data.Configuration; -using Snowflake.Data.Core; -using Snowflake.Data.Core.Tools; -using Snowflake.Data.Log; - -namespace Snowflake.Data.Tests.UnitTests.Session -{ - [TestFixture] - public class EasyLoggingStarterTest - { - private static readonly string HomeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - private static readonly string LogPath = Path.Combine(HomeDirectory, "some-logs-path/some-folder"); - private const string ConfigPath = "/some-path/config.json"; - private const string AnotherConfigPath = "/another/path"; - private static readonly string s_expectedLogPath = Path.Combine(LogPath, "dotnet"); - - private static readonly ClientConfig s_configWithErrorLevel = new ClientConfig - { - CommonProps = new ClientConfigCommonProps - { - LogLevel = "Error", - LogPath = LogPath - } - }; - - private static readonly ClientConfig s_configWithInfoLevel = new ClientConfig - { - CommonProps = new ClientConfigCommonProps - { - LogLevel = "Info", - LogPath = LogPath - } - }; - - private static readonly ClientConfig s_configWithNoLogPath = new ClientConfig - { - CommonProps = new ClientConfigCommonProps - { - LogLevel = "Info" - } - }; - - [ThreadStatic] - private static Mock t_easyLoggingProvider; - - [ThreadStatic] - private static Mock t_easyLoggerManager; - - [ThreadStatic] - private static Mock t_unixOperations; - - [ThreadStatic] - private static Mock t_directoryOperations; - - [ThreadStatic] - private static Mock t_environmentOperations; - - [ThreadStatic] - private static EasyLoggingStarter t_easyLoggerStarter; - - [SetUp] - public void BeforeEach() - { - t_easyLoggingProvider = new Mock(); - t_easyLoggerManager = new Mock(); - t_unixOperations = new Mock(); - t_directoryOperations = new Mock(); - t_environmentOperations = new Mock(); - t_easyLoggerStarter = new EasyLoggingStarter( - t_easyLoggingProvider.Object, - t_easyLoggerManager.Object, - t_unixOperations.Object, - t_directoryOperations.Object, - t_environmentOperations.Object); - } - - [Test] - public void TestThatThrowsErrorWhenLogPathAndHomeDirectoryIsNotSet() - { - // arrange - t_easyLoggingProvider - .Setup(provider => provider.ProvideConfig(ConfigPath)) - .Returns(s_configWithNoLogPath); - t_environmentOperations - .Setup(env => env.GetFolderPath(Environment.SpecialFolder.UserProfile)) - .Returns(""); - - // act - var thrown = Assert.Throws(() => t_easyLoggerStarter.Init(ConfigPath)); - - // assert - Assert.IsNotNull(thrown); - Assert.AreEqual(thrown.Message, "No log path found for easy logging. Home directory is not configured and log path is not provided"); - } - - [Test] - public void TestThatThrowsErrorWhenLogPathIsNotSetAndHomeDirectoryThrowsAnException() - { - // arrange - var ex = new Exception("No home directory"); - t_easyLoggingProvider - .Setup(provider => provider.ProvideConfig(ConfigPath)) - .Returns(s_configWithNoLogPath); - t_environmentOperations - .Setup(env => env.GetFolderPath(Environment.SpecialFolder.UserProfile)) - .Throws(() => ex); - - // act - var thrown = Assert.Throws(() => t_easyLoggerStarter.Init(ConfigPath)); - - // assert - Assert.IsNotNull(thrown); - Assert.AreEqual(thrown.Message, "No log path found for easy logging. Home directory is not configured and log path is not provided"); - } - - [Test] - public void TestThatDoesNotFailWhenLogDirectoryPermissionIsNot700() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Assert.Ignore("skip test on Windows"); - } - - // arrange - t_easyLoggingProvider - .Setup(provider => provider.ProvideConfig(ConfigPath)) - .Returns(s_configWithInfoLevel); - t_directoryOperations - .Setup(dir => dir.Exists(s_expectedLogPath)) - .Returns(true); - t_unixOperations - .Setup(unix => unix.GetDirPermissions(s_expectedLogPath)) - .Returns(FileAccessPermissions.AllPermissions); - - // act - t_easyLoggerStarter.Init(ConfigPath); - - // assert - t_unixOperations.Verify(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, - FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR), Times.Never); - } - - [Test] - public void TestFailIfDirectoryCreationFails() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Assert.Ignore("skip test on Windows"); - } - - // arrange - t_easyLoggingProvider - .Setup(provider => provider.ProvideConfig(ConfigPath)) - .Returns(s_configWithErrorLevel); - t_unixOperations - .Setup(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR)) - .Returns((int)Errno.EPERM); - - // act - var thrown = Assert.Throws(() => t_easyLoggerStarter.Init(ConfigPath)); - - // assert - Assert.That(thrown.Message, Does.Contain("Failed to create logs directory")); - } - - [Test] - public void TestThatConfiguresEasyLoggingOnlyOnceWhenInitializedWithConfigPath() - { - // arrange - t_easyLoggingProvider - .Setup(provider => provider.ProvideConfig(ConfigPath)) - .Returns(s_configWithErrorLevel); - t_easyLoggingProvider - .Setup(provider => provider.ProvideConfig(null)) - .Returns(s_configWithInfoLevel); - t_easyLoggingProvider - .Setup(provider => provider.ProvideConfig(AnotherConfigPath)) - .Returns(s_configWithInfoLevel); - - // act - t_easyLoggerStarter.Init(ConfigPath); - - // assert - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - t_directoryOperations.Verify(d => d.CreateDirectory(s_expectedLogPath), Times.Once); - } - else - { - t_unixOperations.Verify(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, - FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR), Times.Once); - } - t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Error, s_expectedLogPath), Times.Once); - - // act - t_easyLoggerStarter.Init(null); - t_easyLoggerStarter.Init(ConfigPath); - t_easyLoggerStarter.Init(AnotherConfigPath); - - // assert - t_easyLoggerManager.VerifyNoOtherCalls(); - } - - [Test] - public void TestThatConfiguresEasyLoggingOnlyOnceForInitializationsWithoutConfigPath() - { - // arrange - t_easyLoggingProvider - .Setup(provider => provider.ProvideConfig(null)) - .Returns(s_configWithErrorLevel); - - // act - t_easyLoggerStarter.Init(null); - t_easyLoggerStarter.Init(null); - - // assert - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - t_directoryOperations.Verify(d => d.CreateDirectory(s_expectedLogPath), Times.Once); - } - else - { - t_unixOperations.Verify(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, - FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR), Times.Once); - } - t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Error, s_expectedLogPath), Times.Once); - } - - [Test] - public void TestThatReconfiguresEasyLoggingWithConfigPathIfNotGivenForTheFirstTime() - { - // arrange - t_easyLoggingProvider - .Setup(provider => provider.ProvideConfig(null)) - .Returns(s_configWithErrorLevel); - t_easyLoggingProvider - .Setup(provider => provider.ProvideConfig(ConfigPath)) - .Returns(s_configWithInfoLevel); - - // act - t_easyLoggerStarter.Init(null); - - // assert - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - t_directoryOperations.Verify(d => d.CreateDirectory(s_expectedLogPath), Times.Once); - } - else - { - t_unixOperations.Verify(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, - FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR), Times.Once); - } - t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Error, s_expectedLogPath), Times.Once); - - // act - t_easyLoggerStarter.Init(ConfigPath); - - // assert - t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Info, s_expectedLogPath), Times.Once); - t_easyLoggerManager.VerifyNoOtherCalls(); - } - } -} diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs index 710a8d645..26d2010d8 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs @@ -2,112 +2,199 @@ * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. */ -using Snowflake.Data.Configuration; +using NUnit.Framework; +using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; +using ILogger = Microsoft.Extensions.Logging.ILogger; +using NLog.Extensions.Logging; +using Serilog; +using Serilog.Extensions.Logging; +using System.IO; namespace Snowflake.Data.Tests.UnitTests { - using NUnit.Framework; - using Snowflake.Data.Log; - [TestFixture, NonParallelizable] class SFLoggerTest { - SFLogger _logger; + private const string InfoMessage = "Info message"; + private const string DebugMessage = "Debug message"; + private const string WarnMessage = "Warn message"; + private const string ErrorMessage = "Error message"; + private const string CriticalMessage = "critical message"; - [OneTimeSetUp] - public static void BeforeTest() + public abstract class SFBaseLoggerTest { - // Log level defaults to Warn on net6.0 builds in github actions - // Set the root level to Debug - EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Debug, "STDOUT"); - } + protected ILogger _logger; + protected string _logFile; - [OneTimeTearDown] - public static void AfterAll() - { - EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, "STDOUT"); - } - - [TearDown] public void AfterTest() - { - // Return to default setting - SFLoggerFactory.useDefaultLogger(); - SFLoggerFactory.enableLogger(); - } + [OneTimeSetUp] + public void BeforeTest() + { + SFLoggerFactory.EnableLogger(); + } - [Test] - public void TestUsingDefaultLogger() - { - SFLoggerFactory.useDefaultLogger(); - _logger = SFLoggerFactory.GetLogger(); - Assert.IsInstanceOf(_logger); - } + [OneTimeTearDown] + public void AfterTest() + { + // Return to default setting + SFLoggerFactory.UseDefaultLogger(); + SFLoggerFactory.DisableLogger(); + if (_logFile != null) + { + File.Delete(_logFile); + _logFile = null; + } + } - [Test] - public void TestSettingCustomLogger() - { - SFLoggerFactory.Instance(new SFLoggerEmptyImpl()); - _logger = SFLoggerFactory.GetLogger(); - Assert.IsInstanceOf(_logger); - } + [Test] + public void TestUsingDefaultLogger() + { + var originalLogger = SFLoggerFactory.GetLogger(); + SFLoggerFactory.UseDefaultLogger(); + _logger = SFLoggerFactory.GetLogger(); + Assert.IsInstanceOf(_logger); + SFLoggerFactory.SetCustomLogger(originalLogger); + } - [Test] - public void TestIsDebugEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); + [Test] + public void TestSettingCustomLogger() + { + var originalLogger = SFLoggerFactory.GetLogger(); + SFLoggerFactory.SetCustomLogger(new SFLoggerEmptyImpl()); + _logger = SFLoggerFactory.GetLogger(); + Assert.IsInstanceOf(_logger); + SFLoggerFactory.SetCustomLogger(originalLogger); + } - Assert.AreEqual(isEnabled, _logger.IsDebugEnabled()); - } + [Test] + public void TestIsDebugEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Debug)); + } - [Test] - public void TestIsInfoEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); + [Test] + public void TestIsInfoEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Information)); + } - Assert.AreEqual(isEnabled, _logger.IsInfoEnabled()); - } + [Test] + public void TestIsWarnEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Warning)); + } - [Test] - public void TestIsWarnEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); + [Test] + public void TestIsErrorEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Error)); + } - Assert.AreEqual(isEnabled, _logger.IsWarnEnabled()); - } + [Test] + public void TestIsFatalEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Critical)); + } - [Test] - public void TestIsErrorEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); + private ILogger GetLogger(bool isEnabled) + { + if (isEnabled) + { + SFLoggerFactory.EnableLogger(); + } + else + { + SFLoggerFactory.DisableLogger(); + } + + return SFLoggerFactory.GetLogger(); + } - Assert.AreEqual(isEnabled, _logger.IsErrorEnabled()); + [Test] + public void TestThatLogsToProperFileWithProperLogLevelOnly() + { + _logger = SFLoggerFactory.GetLogger(); + + // act + _logger.LogDebug(DebugMessage); + _logger.LogInformation(InfoMessage); + _logger.LogWarning(WarnMessage); + _logger.LogError(ErrorMessage); + _logger.LogCritical(CriticalMessage); + + // assert + using (FileStream logFileStream = new FileStream(_logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + using (StreamReader logFileReader = new StreamReader(logFileStream)) + { + string logLines = logFileReader.ReadToEnd(); + Assert.IsTrue(logLines.Contains(DebugMessage)); + Assert.IsTrue(logLines.Contains(InfoMessage)); + Assert.IsTrue(logLines.Contains(WarnMessage)); + Assert.IsTrue(logLines.Contains(ErrorMessage)); + Assert.IsTrue(logLines.Contains(CriticalMessage)); + } + } + } } - [Test] - public void TestIsFatalEnabled( - [Values(false, true)] bool isEnabled) + [TestFixture] + public class Log4NetTest : SFBaseLoggerTest { - _logger = GetLogger(isEnabled); - - Assert.AreEqual(isEnabled, _logger.IsFatalEnabled()); + [OneTimeSetUp] + public void SetUp() + { + var factory = LoggerFactory.Create( + builder => builder + .AddLog4Net("TestLog4Net.config") + .SetMinimumLevel(LogLevel.Trace)); + + var log4netLogger = factory.CreateLogger("Log4NetTest"); + SFLoggerFactory.SetCustomLogger(log4netLogger); + _logFile = "test_log4net.log"; + } } - private SFLogger GetLogger(bool isEnabled) + [TestFixture] + public class SerilogTest : SFBaseLoggerTest { - if (isEnabled) + [OneTimeSetUp] + public void SetUp() { - SFLoggerFactory.enableLogger(); + var loggerSerilog = new LoggerConfiguration() + .ReadFrom.Xml("TestSerilog.Config") + .CreateLogger(); + var serilogLogger = new SerilogLoggerFactory(loggerSerilog).CreateLogger("SerilogTest"); + SFLoggerFactory.SetCustomLogger(serilogLogger); + _logFile = "test_serilog.log"; } - else + } + + [TestFixture] + public class NlogTest : SFBaseLoggerTest + { + [OneTimeSetUp] + public void SetUp() { - SFLoggerFactory.disableLogger(); + var factory = LoggerFactory.Create( + builder => builder + .AddNLog("TestNLog.config") + .SetMinimumLevel(LogLevel.Trace)); + + var nlogLogger = factory.CreateLogger("NlogTest"); + SFLoggerFactory.SetCustomLogger(nlogLogger); + _logFile = "test_nlog.log"; } - - return SFLoggerFactory.GetLogger(); } } } diff --git a/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs b/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs index 262122b2d..c7e3942c9 100644 --- a/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs +++ b/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs @@ -85,26 +85,6 @@ public void TestSkipUpdateSessionPropertiesWhenPropertiesMissing() Assert.AreEqual(roleName, sfSession.role); } - [Test] - [TestCase(null)] - [TestCase("/some-path/config.json")] - [TestCase("C:\\some-path\\config.json")] - public void TestThatConfiguresEasyLogging(string configPath) - { - // arrange - var easyLoggingStarter = new Moq.Mock(); - var simpleConnectionString = "account=test;user=test;password=test;"; - var connectionString = configPath == null - ? simpleConnectionString - : $"{simpleConnectionString}client_config_file={configPath};"; - - // act - new SFSession(connectionString, null, easyLoggingStarter.Object); - - // assert - easyLoggingStarter.Verify(starter => starter.Init(configPath)); - } - [TestCase(null, "accountDefault", "accountDefault", false)] [TestCase("initial", "initial", "initial", false)] [TestCase("initial", null, "initial", false)] diff --git a/Snowflake.Data.Tests/Util/ConnectingThreads.cs b/Snowflake.Data.Tests/Util/ConnectingThreads.cs index beba4720c..de5b6e462 100644 --- a/Snowflake.Data.Tests/Util/ConnectingThreads.cs +++ b/Snowflake.Data.Tests/Util/ConnectingThreads.cs @@ -7,6 +7,7 @@ using Snowflake.Data.Core.Session; using Snowflake.Data.Log; using Snowflake.Data.Tests.Util; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.IntegrationTests { @@ -55,12 +56,12 @@ public ConnectingThreads JoinAll() public void Enqueue(ThreadEvent threadEvent) => _events.Enqueue(threadEvent); - public static SFLogger Logger() => SFLoggerFactory.GetLogger(); // we have to choose a class from Snowflake.Data package otherwise it will be visible in GH build output + public static ILogger Logger() => SFLoggerFactory.GetLogger(); // we have to choose a class from Snowflake.Data package otherwise it will be visible in GH build output } class ConnectingThread { - private static readonly SFLogger s_logger = ConnectingThreads.Logger(); + private static readonly ILogger s_logger = ConnectingThreads.Logger(); private string _name; @@ -103,21 +104,21 @@ private void Execute() { var connection = new SnowflakeDbConnection(); connection.ConnectionString = _connectionString; - s_logger.Debug($"Execution started, will sleep for {_waitBeforeConnectMillis} ms"); + s_logger.LogDebug($"Execution started, will sleep for {_waitBeforeConnectMillis} ms"); Sleep(_waitBeforeConnectMillis); var watch = new StopWatch(); watch.Start(); var connected = false; try { - s_logger.Debug("Opening the connection"); + s_logger.LogDebug("Opening the connection"); connection.Open(); connected = true; } catch (Exception exception) { watch.Stop(); - s_logger.Error($"Execution failed because of the error: {exception}"); + s_logger.LogError($"Execution failed because of the error: {exception}"); _events.Enqueue(ThreadEvent.EventConnectingFailed(_name, exception, watch.ElapsedMilliseconds)); } if (connected) @@ -128,7 +129,7 @@ private void Execute() Sleep(_waitAfterConnectMillis); if (_closeOnExit) { - s_logger.Debug($"Closing the connection"); + s_logger.LogDebug($"Closing the connection"); connection.Close(); } } @@ -184,7 +185,7 @@ public static ThreadEvent EventWaitingForSessionStarted(string threadName) => class SessionPoolThreadEventHandler: SessionPoolEventHandler { - private static readonly SFLogger s_logger = ConnectingThreads.Logger(); + private static readonly ILogger s_logger = ConnectingThreads.Logger(); private readonly ConnectingThreads _connectingThreads; public SessionPoolThreadEventHandler(ConnectingThreads connectingThreads) @@ -197,24 +198,24 @@ public override void OnWaitingForSessionStarted(SessionPool sessionPool) var threadName = Thread.CurrentThread.Name; var realThreadName = threadName.StartsWith(ConnectingThread.NamePrefix) ? threadName.Substring(ConnectingThread.NamePrefix.Length) : threadName; - s_logger.Warn($"Thread is going to wait for an available session. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); + s_logger.LogWarning($"Thread is going to wait for an available session. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); var waitingStartedEvent = ThreadEvent.EventWaitingForSessionStarted(realThreadName); _connectingThreads.Enqueue(waitingStartedEvent); } public override void OnWaitingForSessionStarted(SessionPool sessionPool, long millisLeft) { - s_logger.Warn($"Thread is going to wait with milliseconds timeout of {millisLeft}. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); + s_logger.LogWarning($"Thread is going to wait with milliseconds timeout of {millisLeft}. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); } public override void OnWaitingForSessionSuccessful(SessionPool sessionPool) { - s_logger.Warn($"Thread has been woken with a session granted. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); + s_logger.LogWarning($"Thread has been woken with a session granted. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); } public override void OnSessionProvided(SessionPool sessionPool) { - s_logger.Warn($"Thread has got a session. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); + s_logger.LogWarning($"Thread has got a session. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); } } } diff --git a/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs b/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs index e8efc371d..8f91c11bf 100644 --- a/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs +++ b/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs @@ -3,26 +3,27 @@ using Snowflake.Data.Client; using Snowflake.Data.Log; using Snowflake.Data.Tests.IcebergTests; +using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.Util { public static class DbConnectionExtensions { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); internal static IDbCommand CreateCommand(this IDbConnection connection, string commandText) { var command = connection.CreateCommand(); command.Connection = connection; command.CommandText = commandText; - s_logger.Debug(commandText); + s_logger.LogDebug(commandText); return command; } internal static int ExecuteNonQuery(this IDbConnection connection, string commandText) { var rowsAffected = connection.CreateCommand(commandText).ExecuteNonQuery(); - s_logger.Debug($"Affected row(s): {rowsAffected}"); + s_logger.LogDebug($"Affected row(s): {rowsAffected}"); return rowsAffected; } diff --git a/Snowflake.Data.Tests/log4net.config b/Snowflake.Data.Tests/log4net.config new file mode 100644 index 000000000..0dffc1970 --- /dev/null +++ b/Snowflake.Data.Tests/log4net.config @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + From 0ab8c66ed24ed6d0198a4909b4d29dd062ca4581 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Tue, 12 Nov 2024 15:22:56 -0800 Subject: [PATCH 03/35] Set config from code --- Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs index 26d2010d8..0cd9ce014 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs @@ -172,7 +172,8 @@ public class SerilogTest : SFBaseLoggerTest public void SetUp() { var loggerSerilog = new LoggerConfiguration() - .ReadFrom.Xml("TestSerilog.Config") + .MinimumLevel.Verbose() + .WriteTo.File("test_serilog.log") .CreateLogger(); var serilogLogger = new SerilogLoggerFactory(loggerSerilog).CreateLogger("SerilogTest"); SFLoggerFactory.SetCustomLogger(serilogLogger); From 15090b4aa644e6bc01ddb824f97a3705f73ceb67 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Wed, 13 Nov 2024 17:04:39 -0800 Subject: [PATCH 04/35] Use constant file names for tests --- Snowflake.Data.Tests/SFBaseTest.cs | 4 ++-- Snowflake.Data.Tests/TestLog4Net.config | 2 +- Snowflake.Data.Tests/TestNLog.config | 2 +- .../UnitTests/Logger/SFLoggerTest.cs | 16 ++++++++++++---- Snowflake.Data.Tests/log4net.config | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Snowflake.Data.Tests/SFBaseTest.cs b/Snowflake.Data.Tests/SFBaseTest.cs index 5b3f8d45f..e791de352 100755 --- a/Snowflake.Data.Tests/SFBaseTest.cs +++ b/Snowflake.Data.Tests/SFBaseTest.cs @@ -187,9 +187,9 @@ public static void RecordTestPerformance(string name, TimeSpan time) public void Setup() { #if NETFRAMEWORK - Environment.SetEnvironmentVariable("net_test_framework", "net471"); + Environment.SetEnvironmentVariable("NET_TEST_FRAMEWORK", "net471"); #else - Environment.SetEnvironmentVariable("net_test_framework", "net6.0"); + Environment.SetEnvironmentVariable("NET_TEST_FRAMEWORK", "net6.0"); #endif ILoggerFactory factory = LoggerFactory.Create( builder => builder diff --git a/Snowflake.Data.Tests/TestLog4Net.config b/Snowflake.Data.Tests/TestLog4Net.config index 784355885..72de5b815 100644 --- a/Snowflake.Data.Tests/TestLog4Net.config +++ b/Snowflake.Data.Tests/TestLog4Net.config @@ -1,7 +1,7 @@ - + diff --git a/Snowflake.Data.Tests/TestNLog.config b/Snowflake.Data.Tests/TestNLog.config index 85c376043..6dd1b6ce8 100644 --- a/Snowflake.Data.Tests/TestNLog.config +++ b/Snowflake.Data.Tests/TestNLog.config @@ -10,7 +10,7 @@ diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs index 0cd9ce014..37fd8a503 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs @@ -10,6 +10,7 @@ using Serilog; using Serilog.Extensions.Logging; using System.IO; +using System; namespace Snowflake.Data.Tests.UnitTests { @@ -22,6 +23,10 @@ class SFLoggerTest private const string ErrorMessage = "Error message"; private const string CriticalMessage = "critical message"; + private const string Log4NetFileName = "test_log4net.log"; + private const string SerilogFileName = "test_serilog.log"; + private const string NlogFileName = "test_nlog.log"; + public abstract class SFBaseLoggerTest { protected ILogger _logger; @@ -154,6 +159,7 @@ public class Log4NetTest : SFBaseLoggerTest [OneTimeSetUp] public void SetUp() { + Environment.SetEnvironmentVariable("TEST_LOG4NET_FILE_NAME", Log4NetFileName); var factory = LoggerFactory.Create( builder => builder .AddLog4Net("TestLog4Net.config") @@ -161,7 +167,7 @@ public void SetUp() var log4netLogger = factory.CreateLogger("Log4NetTest"); SFLoggerFactory.SetCustomLogger(log4netLogger); - _logFile = "test_log4net.log"; + _logFile = Log4NetFileName; } } @@ -173,11 +179,12 @@ public void SetUp() { var loggerSerilog = new LoggerConfiguration() .MinimumLevel.Verbose() - .WriteTo.File("test_serilog.log") + .WriteTo.File(SerilogFileName) .CreateLogger(); + var serilogLogger = new SerilogLoggerFactory(loggerSerilog).CreateLogger("SerilogTest"); SFLoggerFactory.SetCustomLogger(serilogLogger); - _logFile = "test_serilog.log"; + _logFile = SerilogFileName; } } @@ -187,6 +194,7 @@ public class NlogTest : SFBaseLoggerTest [OneTimeSetUp] public void SetUp() { + Environment.SetEnvironmentVariable("TEST_NLOG_FILE_NAME", NlogFileName); var factory = LoggerFactory.Create( builder => builder .AddNLog("TestNLog.config") @@ -194,7 +202,7 @@ public void SetUp() var nlogLogger = factory.CreateLogger("NlogTest"); SFLoggerFactory.SetCustomLogger(nlogLogger); - _logFile = "test_nlog.log"; + _logFile = NlogFileName; } } } diff --git a/Snowflake.Data.Tests/log4net.config b/Snowflake.Data.Tests/log4net.config index 0dffc1970..e461d54b5 100644 --- a/Snowflake.Data.Tests/log4net.config +++ b/Snowflake.Data.Tests/log4net.config @@ -1,7 +1,7 @@ - + From 1b80c55e217b803825be497bf7fd1d3bb34f41e7 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Mon, 18 Nov 2024 14:00:33 -0800 Subject: [PATCH 05/35] Remove unused method --- Snowflake.Data/Core/Tools/EnvironmentOperations.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs index daee66d65..291fddd9a 100644 --- a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs +++ b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs @@ -23,17 +23,5 @@ public virtual string GetFolderPath(Environment.SpecialFolder folder) { return Environment.GetFolderPath(folder); } - - public virtual string GetExecutionDirectory() - { - var executablePath = Environment.GetCommandLineArgs()[0]; - var directoryName = string.IsNullOrEmpty(executablePath) ? null : Path.GetDirectoryName(executablePath); - if (string.IsNullOrEmpty(directoryName)) - { - s_logger.LogWarning("Unable to determine execution directory"); - return null; - } - return directoryName; - } } } From 00d0e39fd4dd8b4a1b8129f864340922c772a8e3 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Tue, 19 Nov 2024 15:07:44 -0800 Subject: [PATCH 06/35] Add tests for home directory tool --- .../Tools/HomeDirectoryProviderTest.cs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 Snowflake.Data.Tests/UnitTests/Tools/HomeDirectoryProviderTest.cs diff --git a/Snowflake.Data.Tests/UnitTests/Tools/HomeDirectoryProviderTest.cs b/Snowflake.Data.Tests/UnitTests/Tools/HomeDirectoryProviderTest.cs new file mode 100644 index 000000000..488d78f33 --- /dev/null +++ b/Snowflake.Data.Tests/UnitTests/Tools/HomeDirectoryProviderTest.cs @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using Moq; +using NUnit.Framework; +using Snowflake.Data.Core.Tools; + +namespace Snowflake.Data.Tests.Tools +{ + [TestFixture] + public class HomeDirectoryProviderTest + { + private const string HomeDirectory = "/home/user"; + + [ThreadStatic] + private static Mock t_environmentOperations; + + [SetUp] + public void Setup() + { + t_environmentOperations = new Mock(); + } + + [Test] + public void TestThatReturnsHomeDirectorySuccessfully() + { + // arrange + MockHomeDirectory(); + + // act + var actualHomeDirectory = HomeDirectoryProvider.HomeDirectory(t_environmentOperations.Object); + + // assert + Assert.AreEqual(HomeDirectory, actualHomeDirectory); + } + + [Test] + public void TestThatDoesNotFailWhenHomeDirectoryReturnsNull() + { + // arrange + MockHomeDirectoryReturnsNull(); + + // act + var actualHomeDirectory = HomeDirectoryProvider.HomeDirectory(t_environmentOperations.Object); + + // assert + Assert.IsNull(actualHomeDirectory); + t_environmentOperations.Verify(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile), Times.Once); + } + + [Test] + public void TestThatDoesNotFailWhenHomeDirectoryThrowsError() + { + // arrange + MockHomeDirectoryFails(); + + // act + var actualHomeDirectory = HomeDirectoryProvider.HomeDirectory(t_environmentOperations.Object); + + // assert + Assert.IsNull(actualHomeDirectory); + t_environmentOperations.Verify(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile), Times.Once); + } + + private static void MockHomeDirectory() + { + t_environmentOperations + .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) + .Returns(HomeDirectory); + } + + private static void MockHomeDirectoryReturnsNull() + { + t_environmentOperations + .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) + .Returns((string)null); + } + + private static void MockHomeDirectoryFails() + { + t_environmentOperations + .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) + .Throws(() => new Exception("No home directory")); + } + } +} From 1036d5677b7ae57754be3e40f33bf04da8aeda77 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Thu, 21 Nov 2024 11:23:07 -0800 Subject: [PATCH 07/35] Re-add Easy Logging --- .../IntegrationTests/EasyLoggingIT.cs | 124 +++++++++ Snowflake.Data.Tests/SFBaseTest.cs | 10 +- .../EasyLoggingConfigFinderTest.cs | 259 ++++++++++++++++++ .../EasyLoggingConfigParserTest.cs | 132 +++++++++ .../EasyLoggingConfigProviderTest.cs | 58 ++++ .../Configuration/EasyLoggingLogLevelTest.cs | 38 +++ .../UnitTests/Logger/EasyLoggerManagerTest.cs | 150 ++++++++++ .../UnitTests/SFSessionTest.cs | 20 ++ .../Tools/HomeDirectoryProviderTest.cs | 88 ------ .../Configuration/EasyLoggingConfigFinder.cs | 118 ++++++++ .../Configuration/EasyLoggingConfigParser.cs | 85 ++++++ .../EasyLoggingConfigProvider.cs | 31 +++ .../Configuration/EasyLoggingLogLevel.cs | 26 ++ .../Core/Session/EasyLoggingStarter.cs | 195 +++++++++++++ Snowflake.Data/Core/Session/SFSession.cs | 16 +- .../Core/Tools/EnvironmentOperations.cs | 12 + Snowflake.Data/Logger/EasyLoggerManager.cs | 137 +++++++++ .../Logger/EasyLoggingLevelMapper.cs | 29 ++ Snowflake.Data/Logger/Log4netImpl.cs | 78 ++++++ Snowflake.Data/Logger/SFLogger.cs | 39 +++ .../Logger/SFLoggerEmptySimpleImpl.cs | 65 +++++ Snowflake.Data/Logger/SFLoggerFactory.cs | 18 +- Snowflake.Data/Snowflake.Data.csproj | 3 +- 23 files changed, 1636 insertions(+), 95 deletions(-) create mode 100644 Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs create mode 100644 Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigFinderTest.cs create mode 100644 Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigParserTest.cs create mode 100644 Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigProviderTest.cs create mode 100644 Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingLogLevelTest.cs create mode 100644 Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs delete mode 100644 Snowflake.Data.Tests/UnitTests/Tools/HomeDirectoryProviderTest.cs create mode 100644 Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs create mode 100644 Snowflake.Data/Configuration/EasyLoggingConfigParser.cs create mode 100644 Snowflake.Data/Configuration/EasyLoggingConfigProvider.cs create mode 100644 Snowflake.Data/Configuration/EasyLoggingLogLevel.cs create mode 100644 Snowflake.Data/Core/Session/EasyLoggingStarter.cs create mode 100644 Snowflake.Data/Logger/EasyLoggerManager.cs create mode 100644 Snowflake.Data/Logger/EasyLoggingLevelMapper.cs create mode 100644 Snowflake.Data/Logger/Log4netImpl.cs create mode 100644 Snowflake.Data/Logger/SFLogger.cs create mode 100644 Snowflake.Data/Logger/SFLoggerEmptySimpleImpl.cs diff --git a/Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs b/Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs new file mode 100644 index 000000000..fd2e79409 --- /dev/null +++ b/Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs @@ -0,0 +1,124 @@ +using System.Data; +using System.IO; +using System.Runtime.InteropServices; +using Mono.Unix.Native; +using NUnit.Framework; +using Snowflake.Data.Client; +using Snowflake.Data.Configuration; +using Snowflake.Data.Core; +using Snowflake.Data.Log; +using static Snowflake.Data.Tests.UnitTests.Configuration.EasyLoggingConfigGenerator; + +namespace Snowflake.Data.Tests.IntegrationTests +{ + [TestFixture, NonParallelizable] + public class EasyLoggingIT: SFBaseTest + { + private static readonly string s_workingDirectory = Path.Combine(Path.GetTempPath(), "easy_logging_test_configs_", Path.GetRandomFileName()); + + [OneTimeSetUp] + public static void BeforeAll() + { + if (!Directory.Exists(s_workingDirectory)) + { + Directory.CreateDirectory(s_workingDirectory); + } + } + + [OneTimeTearDown] + public static void AfterAll() + { + Directory.Delete(s_workingDirectory, true); + } + + [TearDown] + public static void AfterEach() + { + EasyLoggingStarter.Instance.Reset(EasyLoggingLogLevel.Warn); + } + + [Test] + public void TestEnableEasyLogging() + { + // arrange + var configFilePath = CreateConfigTempFile(s_workingDirectory, Config("WARN", s_workingDirectory)); + using (IDbConnection conn = new SnowflakeDbConnection()) + { + conn.ConnectionString = ConnectionString + $"CLIENT_CONFIG_FILE={configFilePath}"; + + // act + conn.Open(); + + // assert + Assert.IsTrue(EasyLoggerManager.HasEasyLoggingAppender()); + } + } + + [Test] + public void TestFailToEnableEasyLoggingForWrongConfiguration() + { + // arrange + var configFilePath = CreateConfigTempFile(s_workingDirectory, "random config content"); + using (IDbConnection conn = new SnowflakeDbConnection()) + { + conn.ConnectionString = ConnectionString + $"CLIENT_CONFIG_FILE={configFilePath}"; + + // act + var thrown = Assert.Throws(() => conn.Open()); + + // assert + Assert.That(thrown.Message, Does.Contain("Connection string is invalid: Unable to initialize session")); + Assert.IsFalse(EasyLoggerManager.HasEasyLoggingAppender()); + } + } + + [Test] + public void TestFailToEnableEasyLoggingWhenConfigHasWrongPermissions() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Assert.Ignore("skip test on Windows"); + } + + // arrange + var configFilePath = CreateConfigTempFile(s_workingDirectory, Config("WARN", s_workingDirectory)); + Syscall.chmod(configFilePath, FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IWGRP); + using (IDbConnection conn = new SnowflakeDbConnection()) + { + conn.ConnectionString = ConnectionString + $"CLIENT_CONFIG_FILE={configFilePath}"; + + // act + var thrown = Assert.Throws(() => conn.Open()); + + // assert + Assert.That(thrown.Message, Does.Contain("Connection string is invalid: Unable to initialize session")); + Assert.IsFalse(EasyLoggerManager.HasEasyLoggingAppender()); + } + } + + [Test] + public void TestFailToEnableEasyLoggingWhenLogDirectoryNotAccessible() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Assert.Ignore("skip test on Windows"); + } + + // arrange + var configFilePath = CreateConfigTempFile(s_workingDirectory, Config("WARN", "/")); + using (IDbConnection conn = new SnowflakeDbConnection()) + { + conn.ConnectionString = ConnectionString + $"CLIENT_CONFIG_FILE={configFilePath}"; + + // act + var thrown = Assert.Throws(() => conn.Open()); + + // assert + Assert.That(thrown.Message, Does.Contain("Connection string is invalid: Unable to initialize session")); + Assert.That(thrown.InnerException.Message, Does.Contain("Failed to create logs directory")); + Assert.IsFalse(EasyLoggerManager.HasEasyLoggingAppender()); + } + + } + } +} diff --git a/Snowflake.Data.Tests/SFBaseTest.cs b/Snowflake.Data.Tests/SFBaseTest.cs index e791de352..6153b337e 100755 --- a/Snowflake.Data.Tests/SFBaseTest.cs +++ b/Snowflake.Data.Tests/SFBaseTest.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved. */ @@ -187,9 +187,13 @@ public static void RecordTestPerformance(string name, TimeSpan time) public void Setup() { #if NETFRAMEWORK - Environment.SetEnvironmentVariable("NET_TEST_FRAMEWORK", "net471"); + log4net.GlobalContext.Properties["framework"] = "net471"; + log4net.Config.XmlConfigurator.Configure(); + #else - Environment.SetEnvironmentVariable("NET_TEST_FRAMEWORK", "net6.0"); + log4net.GlobalContext.Properties["framework"] = "net6.0"; + var logRepository = log4net.LogManager.GetRepository(Assembly.GetEntryAssembly()); + log4net.Config.XmlConfigurator.Configure(logRepository, new FileInfo("App.config")); #endif ILoggerFactory factory = LoggerFactory.Create( builder => builder diff --git a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigFinderTest.cs b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigFinderTest.cs new file mode 100644 index 000000000..4b9e36d47 --- /dev/null +++ b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigFinderTest.cs @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using Mono.Unix; +using Moq; +using NUnit.Framework; +using Snowflake.Data.Configuration; +using Snowflake.Data.Core.Tools; + +namespace Snowflake.Data.Tests.UnitTests.Configuration +{ + [TestFixture] + public class EasyLoggingConfigFinderTest + { + private const string InputConfigFilePath = "input_config.json"; + private const string EnvironmentalConfigFilePath = "environmental_config.json"; + private const string HomeDirectory = "/home/user"; + private const string DriverDirectory = "."; + private static readonly string s_driverConfigFilePath = Path.Combine(DriverDirectory, EasyLoggingConfigFinder.ClientConfigFileName); + private static readonly string s_homeConfigFilePath = Path.Combine(HomeDirectory, EasyLoggingConfigFinder.ClientConfigFileName); + + [ThreadStatic] + private static Mock t_fileOperations; + + [ThreadStatic] + private static Mock t_unixOperations; + + [ThreadStatic] + private static Mock t_environmentOperations; + + [ThreadStatic] + private static EasyLoggingConfigFinder t_finder; + + [SetUp] + public void Setup() + { + t_fileOperations = new Mock(); + t_unixOperations = new Mock(); + t_environmentOperations = new Mock(); + t_finder = new EasyLoggingConfigFinder(t_fileOperations.Object, t_unixOperations.Object, t_environmentOperations.Object); + MockHomeDirectory(); + MockExecutionDirectory(); + } + + [Test] + public void TestThatTakesFilePathFromTheInput() + { + // arrange + MockFileFromEnvironmentalVariable(); + MockFileOnDriverPath(); + MockFileOnHomePath(); + + // act + var filePath = t_finder.FindConfigFilePath(InputConfigFilePath); + + // assert + Assert.AreEqual(InputConfigFilePath, filePath); + t_fileOperations.VerifyNoOtherCalls(); + t_environmentOperations.VerifyNoOtherCalls(); + } + + [Test] + public void TestThatTakesFilePathFromEnvironmentVariableIfInputNotPresent( + [Values(null, "")] string inputFilePath) + { + // arrange + MockFileFromEnvironmentalVariable(); + MockFileOnDriverPath(); + MockFileOnHomePath(); + + // act + var filePath = t_finder.FindConfigFilePath(inputFilePath); + + // assert + Assert.AreEqual(EnvironmentalConfigFilePath, filePath); + } + + [Test] + public void TestThatTakesFilePathFromDriverLocationWhenNoInputParameterNorEnvironmentVariable() + { + // arrange + MockFileOnDriverPath(); + MockFileOnHomePath(); + + // act + var filePath = t_finder.FindConfigFilePath(null); + + // assert + Assert.AreEqual(s_driverConfigFilePath, filePath); + } + + [Test] + public void TestThatTakesFilePathFromHomeLocationWhenNoInputParamEnvironmentVarNorDriverLocation() + { + // arrange + MockFileOnHomePath(); + + // act + var filePath = t_finder.FindConfigFilePath(null); + + // assert + Assert.AreEqual(s_homeConfigFilePath, filePath); + } + + [Test] + public void TestThatTakesFilePathFromHomeDirectoryWhenNoOtherWaysPossible() + { + // arrange + MockFileOnHomePath(); + + // act + var filePath = t_finder.FindConfigFilePath(null); + + // assert + Assert.AreEqual(s_homeConfigFilePath, filePath); + } + + [Test] + public void TestThatConfigFileIsNotUsedIfOthersCanModifyTheConfigFile() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Assert.Ignore("skip test on Windows"); + } + + // arrange + MockFileOnHomePath(); + MockHasFlagReturnsTrue(); + + // act + var thrown = Assert.Throws(() => t_finder.FindConfigFilePath(null)); + + // assert + Assert.IsNotNull(thrown); + Assert.AreEqual(thrown.Message, $"Error due to other users having permission to modify the config file: {s_homeConfigFilePath}"); + } + + [Test] + public void TestThatReturnsNullIfNoWayOfGettingTheFile() + { + // act + var filePath = t_finder.FindConfigFilePath(null); + + // assert + Assert.IsNull(filePath); + } + + [Test] + public void TestThatDoesNotFailWhenSearchForOneOfDirectoriesFails() + { + // arrange + MockHomeDirectoryFails(); + + // act + var filePath = t_finder.FindConfigFilePath(null); + + // assert + Assert.IsNull(filePath); + t_environmentOperations.Verify(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile), Times.Once); + } + + [Test] + public void TestThatDoesNotFailWhenHomeDirectoryReturnsNull() + { + // arrange + MockHomeDirectoryReturnsNull(); + + // act + var filePath = t_finder.FindConfigFilePath(null); + + // assert + Assert.IsNull(filePath); + t_environmentOperations.Verify(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile), Times.Once); + } + + [Test] + public void TestThatDoesNotFailWhenHomeDirectoryDoesNotExist() + { + // arrange + MockFileOnHomePath(); + MockFileOnHomePathDoesNotExist(); + + // act + var filePath = t_finder.FindConfigFilePath(null); + + // assert + Assert.IsNull(filePath); + t_environmentOperations.Verify(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile), Times.Once); + } + + private static void MockHasFlagReturnsTrue() + { + t_unixOperations + .Setup(f => f.CheckFileHasAnyOfPermissions(s_homeConfigFilePath, + It.Is(p => p.Equals(FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite)))) + .Returns(true); + } + + private static void MockHomeDirectory() + { + t_environmentOperations + .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) + .Returns(HomeDirectory); + } + + private static void MockHomeDirectoryFails() + { + t_environmentOperations + .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) + .Throws(() => new Exception("No home directory")); + } + + private static void MockExecutionDirectory() + { + t_environmentOperations + .Setup(e => e.GetExecutionDirectory()) + .Returns(DriverDirectory); + } + + private static void MockFileOnHomePathDoesNotExist() + { + t_fileOperations + .Setup(f => f.Exists(s_homeConfigFilePath)) + .Returns(false); + } + + private static void MockHomeDirectoryReturnsNull() + { + t_environmentOperations + .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) + .Returns((string) null); + } + + private static void MockFileFromEnvironmentalVariable() + { + t_environmentOperations + .Setup(e => e.GetEnvironmentVariable(EasyLoggingConfigFinder.ClientConfigEnvironmentName)) + .Returns(EnvironmentalConfigFilePath); + } + + private static void MockFileOnDriverPath() + { + t_fileOperations + .Setup(f => f.Exists(s_driverConfigFilePath)) + .Returns(true); + } + + private static void MockFileOnHomePath() + { + t_fileOperations + .Setup(f => f.Exists(s_homeConfigFilePath)) + .Returns(true); + } + } +} diff --git a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigParserTest.cs b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigParserTest.cs new file mode 100644 index 000000000..60a3ab272 --- /dev/null +++ b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigParserTest.cs @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using NUnit.Framework; +using Snowflake.Data.Configuration; +using static Snowflake.Data.Tests.UnitTests.Configuration.EasyLoggingConfigGenerator; + +namespace Snowflake.Data.Tests.UnitTests.Configuration +{ + [TestFixture, NonParallelizable] + public class EasyLoggingConfigParserTest + { + private const string NotExistingFilePath = "../../../Resources/EasyLogging/not_existing_config.json"; + private const string LogLevel = "info"; + private const string LogPath = "./test-logs/log_file.log"; + private static readonly string s_workingDirectory = Path.Combine(Path.GetTempPath(), "easy_logging_test_configs_", Path.GetRandomFileName()); + + [OneTimeSetUp] + public static void BeforeAll() + { + if (!Directory.Exists(s_workingDirectory)) + { + Directory.CreateDirectory(s_workingDirectory); + } + } + + [OneTimeTearDown] + public static void AfterAll() + { + Directory.Delete(s_workingDirectory, true); + } + + [Test] + public void TestThatParsesConfigFile() + { + // arrange + var parser = new EasyLoggingConfigParser(); + var configFilePath = CreateConfigTempFile(s_workingDirectory, Config(LogLevel, LogPath)); + + // act + var config = parser.Parse(configFilePath); + + // assert + Assert.IsNotNull(config); + Assert.IsNotNull(config.CommonProps); + Assert.AreEqual(LogLevel, config.CommonProps.LogLevel); + Assert.AreEqual(LogPath, config.CommonProps.LogPath); + } + + [Test, TestCaseSource(nameof(ConfigFilesWithoutValues))] + public void TestThatParsesConfigFileWithNullValues(string filePath) + { + // arrange + var parser = new EasyLoggingConfigParser(); + + // act + var config = parser.Parse(filePath); + + // assert + Assert.IsNotNull(config); + Assert.IsNotNull(config.CommonProps); + Assert.IsNull(config.CommonProps.LogLevel); + Assert.IsNull(config.CommonProps.LogPath); + } + + [Test] + [TestCase(null)] + [TestCase("")] + public void TestThatReturnsNullWhenNothingToParse(string noFilePath) + { + // arrange + var parser = new EasyLoggingConfigParser(); + + // act + var config = parser.Parse(noFilePath); + + // assert + Assert.IsNull(config); + } + + [Test] + public void TestThatFailsWhenTheFileDoesNotExist() + { + // arrange + var parser = new EasyLoggingConfigParser(); + + // act + var thrown = Assert.Throws(() => parser.Parse(NotExistingFilePath)); + + // assert + Assert.IsNotNull(thrown); + Assert.AreEqual("Finding easy logging configuration failed", thrown.Message); + } + + [Test, TestCaseSource(nameof(WrongConfigFiles))] + public void TestThatFailsIfMissingOrInvalidRequiredFields(string filePath) + { + // arrange + var parser = new EasyLoggingConfigParser(); + + // act + var thrown = Assert.Throws(() => parser.Parse(filePath)); + // assert + Assert.IsNotNull(thrown); + Assert.IsTrue(thrown.Message == "Parsing easy logging configuration failed"); + } + + public static IEnumerable ConfigFilesWithoutValues() + { + BeforeAll(); + return new[] + { + CreateConfigTempFile(s_workingDirectory, EmptyCommonConfig), + CreateConfigTempFile(s_workingDirectory, Config(null, null)) + }; + } + + public static IEnumerable WrongConfigFiles() + { + BeforeAll(); + return new[] + { + CreateConfigTempFile(s_workingDirectory, EmptyConfig), + CreateConfigTempFile(s_workingDirectory, Config("unknown", LogPath)), + }; + } + } +} diff --git a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigProviderTest.cs b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigProviderTest.cs new file mode 100644 index 000000000..6e971ff9e --- /dev/null +++ b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingConfigProviderTest.cs @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using Moq; +using NUnit.Framework; +using Snowflake.Data.Configuration; + +namespace Snowflake.Data.Tests.UnitTests.Configuration +{ + [TestFixture] + public class EasyLoggingConfigProviderTest + { + private const string FilePathFromConnectionString = "/Users/dotnet/config.json"; + private const string FilePathToUse = "/home/config.json"; + + [Test] + public void TestThatProvidesConfiguration() + { + // arrange + var configFinder = new Mock(); + var configParser = new Mock(); + var configProvider = new EasyLoggingConfigProvider(configFinder.Object, configParser.Object); + var config = new ClientConfig(); + configFinder + .Setup(finder => finder.FindConfigFilePath(FilePathFromConnectionString)) + .Returns(FilePathToUse); + configParser + .Setup(parser => parser.Parse(FilePathToUse)) + .Returns(config); + + // act + var result = configProvider.ProvideConfig(FilePathFromConnectionString); + + // assert + Assert.AreSame(config, result); + } + + [Test] + public void TestThatReturnsNullWhenNoConfigurationFound() + { + // arrange + var configFinder = new Mock(); + var configParser = new Mock(); + var configProvider = new EasyLoggingConfigProvider(configFinder.Object, configParser.Object); + configFinder + .Setup(finder => finder.FindConfigFilePath(FilePathFromConnectionString)) + .Returns((string)null); + + // act + var result = configProvider.ProvideConfig(FilePathFromConnectionString); + + // assert + Assert.IsNull(result); + configParser.Verify(parser => parser.Parse(It.IsAny()), Times.Never); + } + } +} diff --git a/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingLogLevelTest.cs b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingLogLevelTest.cs new file mode 100644 index 000000000..7b6e827db --- /dev/null +++ b/Snowflake.Data.Tests/UnitTests/Configuration/EasyLoggingLogLevelTest.cs @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using NUnit.Framework; +using Snowflake.Data.Configuration; + +namespace Snowflake.Data.Tests.UnitTests.Configuration +{ + [TestFixture] + class EasyLoggingLogLevelTest + { + [Test] + [TestCase("OFF", EasyLoggingLogLevel.Off)] + [TestCase("off", EasyLoggingLogLevel.Off)] + [TestCase("iNfO", EasyLoggingLogLevel.Info)] + public void TestThatGetsLogLevelValueIgnoringLetterCase(string loglevelString, EasyLoggingLogLevel expectedLogLevel) + { + // act + var logLevel = EasyLoggingLogLevelExtensions.From(loglevelString); + + // assert + Assert.AreEqual(expectedLogLevel, logLevel); + } + + [Test] + public void TestThatFailsToParseLogLevelFromUnknownValue() + { + // act + var thrown = Assert.Throws(() => EasyLoggingLogLevelExtensions.From("unknown")); + + // assert + Assert.IsNotNull(thrown); + Assert.AreEqual("Requested value 'unknown' was not found.", thrown.Message); + } + } +} diff --git a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs new file mode 100644 index 000000000..599f1ce5a --- /dev/null +++ b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using NUnit.Framework; +using Snowflake.Data.Configuration; +using Snowflake.Data.Core; +using Snowflake.Data.Log; + +namespace Snowflake.Data.Tests.UnitTests.Logger +{ + [TestFixture, NonParallelizable] + public class EasyLoggerManagerTest + { + + private const string InfoMessage = "Easy logging Info message"; + private const string DebugMessage = "Easy logging Debug message"; + private const string WarnMessage = "Easy logging Warn message"; + private const string ErrorMessage = "Easy logging Error message"; + private const string FatalMessage = "Easy logging Fatal message"; + private static readonly string s_logsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + + [ThreadStatic] + private static string t_directoryLogPath; + + [OneTimeTearDown] + public static void CleanUp() + { + RemoveEasyLoggingLogFiles(); + } + + [SetUp] + public void BeforeEach() + { + t_directoryLogPath = RandomLogsDirectoryPath(); + } + + [TearDown] + public void AfterEach() + { + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, t_directoryLogPath); + } + + [Test] + public void TestThatChangesLogLevel() + { + // arrange + var logger = SFLoggerFactory.GetSimpleLogger(); + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, t_directoryLogPath); + + // assert + Assert.IsFalse(logger.IsDebugEnabled()); + Assert.IsFalse(logger.IsInfoEnabled()); + Assert.IsTrue(logger.IsWarnEnabled()); + Assert.IsTrue(logger.IsErrorEnabled()); + Assert.IsTrue(logger.IsFatalEnabled()); + + // act + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Debug, t_directoryLogPath); + + // assert + Assert.IsTrue(logger.IsDebugEnabled()); + Assert.IsTrue(logger.IsInfoEnabled()); + Assert.IsTrue(logger.IsWarnEnabled()); + Assert.IsTrue(logger.IsErrorEnabled()); + Assert.IsTrue(logger.IsFatalEnabled()); + } + + [Test] + public void TestThatLogsToProperFileWithProperLogLevelOnly() + { + // arrange + var logger = SFLoggerFactory.GetSimpleLogger(); + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Info, t_directoryLogPath); + + // act + logger.Debug(DebugMessage); + logger.Info(InfoMessage); + logger.Warn(WarnMessage); + logger.Error(ErrorMessage); + logger.Fatal(FatalMessage); + + // assert + var logLines = File.ReadLines(FindLogFilePath(t_directoryLogPath)); + Assert.That(logLines, Has.Exactly(0).Matches(s => s.Contains(DebugMessage))); + Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(InfoMessage))); + Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(WarnMessage))); + Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(ErrorMessage))); + Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(FatalMessage))); + } + + [Test] + public void TestThatOnlyUnknownFieldsAreLogged() + { + // arrange + string expectedFakeLogField = "fake_log_field"; + string ConfigWithUnknownFields = $@"{{ + ""common"": {{ + ""LOG_LEVEL"": ""warn"", + ""lOg_PaTh"": ""path"", + ""{expectedFakeLogField}_1"": ""abc"", + ""{expectedFakeLogField}_2"": ""123"" + }} + }}"; + var configFilePath = Guid.NewGuid().ToString() + ".json"; + using (var writer = File.CreateText(configFilePath)) + { + writer.Write(ConfigWithUnknownFields); + } + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, t_directoryLogPath); + var parser = new EasyLoggingConfigParser(); + + // act + parser.Parse(configFilePath); + + // assert + var logLines = File.ReadLines(FindLogFilePath(t_directoryLogPath)); + Assert.That(logLines, Has.Exactly(2).Matches(s => s.Contains($"Unknown field from config: {expectedFakeLogField}"))); + + // cleanup + File.Delete(configFilePath); + } + + private static string RandomLogsDirectoryPath() + { + var randomName = Path.GetRandomFileName(); + return Path.Combine(s_logsDirectory, $"easy_logging_logs_{randomName}", "dotnet"); + } + + private static string FindLogFilePath(string directoryLogPath) + { + Assert.IsTrue(Directory.Exists(directoryLogPath)); + var files = Directory.GetFiles(directoryLogPath); + Assert.AreEqual(1, files.Length); + return files.First(); + } + + private static void RemoveEasyLoggingLogFiles() + { + Directory.GetFiles(s_logsDirectory) + .Where(filePath => filePath.StartsWith(Path.Combine(s_logsDirectory, "easy_logging_logs"))) + .AsParallel() + .ForAll(filePath => File.Delete(filePath)); + } + } +} diff --git a/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs b/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs index c7e3942c9..262122b2d 100644 --- a/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs +++ b/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs @@ -85,6 +85,26 @@ public void TestSkipUpdateSessionPropertiesWhenPropertiesMissing() Assert.AreEqual(roleName, sfSession.role); } + [Test] + [TestCase(null)] + [TestCase("/some-path/config.json")] + [TestCase("C:\\some-path\\config.json")] + public void TestThatConfiguresEasyLogging(string configPath) + { + // arrange + var easyLoggingStarter = new Moq.Mock(); + var simpleConnectionString = "account=test;user=test;password=test;"; + var connectionString = configPath == null + ? simpleConnectionString + : $"{simpleConnectionString}client_config_file={configPath};"; + + // act + new SFSession(connectionString, null, easyLoggingStarter.Object); + + // assert + easyLoggingStarter.Verify(starter => starter.Init(configPath)); + } + [TestCase(null, "accountDefault", "accountDefault", false)] [TestCase("initial", "initial", "initial", false)] [TestCase("initial", null, "initial", false)] diff --git a/Snowflake.Data.Tests/UnitTests/Tools/HomeDirectoryProviderTest.cs b/Snowflake.Data.Tests/UnitTests/Tools/HomeDirectoryProviderTest.cs deleted file mode 100644 index 488d78f33..000000000 --- a/Snowflake.Data.Tests/UnitTests/Tools/HomeDirectoryProviderTest.cs +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. - */ - -using System; -using Moq; -using NUnit.Framework; -using Snowflake.Data.Core.Tools; - -namespace Snowflake.Data.Tests.Tools -{ - [TestFixture] - public class HomeDirectoryProviderTest - { - private const string HomeDirectory = "/home/user"; - - [ThreadStatic] - private static Mock t_environmentOperations; - - [SetUp] - public void Setup() - { - t_environmentOperations = new Mock(); - } - - [Test] - public void TestThatReturnsHomeDirectorySuccessfully() - { - // arrange - MockHomeDirectory(); - - // act - var actualHomeDirectory = HomeDirectoryProvider.HomeDirectory(t_environmentOperations.Object); - - // assert - Assert.AreEqual(HomeDirectory, actualHomeDirectory); - } - - [Test] - public void TestThatDoesNotFailWhenHomeDirectoryReturnsNull() - { - // arrange - MockHomeDirectoryReturnsNull(); - - // act - var actualHomeDirectory = HomeDirectoryProvider.HomeDirectory(t_environmentOperations.Object); - - // assert - Assert.IsNull(actualHomeDirectory); - t_environmentOperations.Verify(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile), Times.Once); - } - - [Test] - public void TestThatDoesNotFailWhenHomeDirectoryThrowsError() - { - // arrange - MockHomeDirectoryFails(); - - // act - var actualHomeDirectory = HomeDirectoryProvider.HomeDirectory(t_environmentOperations.Object); - - // assert - Assert.IsNull(actualHomeDirectory); - t_environmentOperations.Verify(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile), Times.Once); - } - - private static void MockHomeDirectory() - { - t_environmentOperations - .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) - .Returns(HomeDirectory); - } - - private static void MockHomeDirectoryReturnsNull() - { - t_environmentOperations - .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) - .Returns((string)null); - } - - private static void MockHomeDirectoryFails() - { - t_environmentOperations - .Setup(e => e.GetFolderPath(Environment.SpecialFolder.UserProfile)) - .Throws(() => new Exception("No home directory")); - } - } -} diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs b/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs new file mode 100644 index 000000000..2d9264400 --- /dev/null +++ b/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using Mono.Unix; +using Snowflake.Data.Core.Tools; +using Snowflake.Data.Log; + +namespace Snowflake.Data.Configuration +{ + internal class EasyLoggingConfigFinder + { + private static readonly SFLogger s_logger = SFLoggerFactory.GetSimpleLogger(); + + internal const string ClientConfigFileName = "sf_client_config.json"; + internal const string ClientConfigEnvironmentName = "SF_CLIENT_CONFIG_FILE"; + + private readonly FileOperations _fileOperations; + private readonly UnixOperations _unixOperations; + private readonly EnvironmentOperations _environmentOperations; + + public static readonly EasyLoggingConfigFinder Instance = new EasyLoggingConfigFinder(FileOperations.Instance, UnixOperations.Instance, EnvironmentOperations.Instance); + + internal EasyLoggingConfigFinder(FileOperations fileOperations, UnixOperations unixFileOperations, EnvironmentOperations environmentOperations) + { + _fileOperations = fileOperations; + _unixOperations = unixFileOperations; + _environmentOperations = environmentOperations; + } + + internal EasyLoggingConfigFinder() + { + } + + public virtual string FindConfigFilePath(string configFilePathFromConnectionString) + { + var configFilePath = GetFilePathFromInputParameter(configFilePathFromConnectionString, "connection string") + ?? GetFilePathEnvironmentVariable() + ?? GetFilePathFromDriverLocation() + ?? GetFilePathFromHomeDirectory(); + if (configFilePath != null) + { + CheckIfValidPermissions(configFilePath); + } + return configFilePath; + } + + private string GetFilePathEnvironmentVariable() + { + var filePath = _environmentOperations.GetEnvironmentVariable(ClientConfigEnvironmentName); + return GetFilePathFromInputParameter(filePath, "environment variable"); + } + + private string GetFilePathFromHomeDirectory() => SearchForConfigInDirectory(GetHomeDirectory, "home"); + + private string GetFilePathFromInputParameter(string filePath, string inputDescription) + { + if (string.IsNullOrEmpty(filePath)) + { + return null; + } + s_logger.Info($"Using config file specified from {inputDescription}: {filePath}"); + return filePath; + } + + private string GetHomeDirectory() => HomeDirectoryProvider.HomeDirectory(_environmentOperations); + + private string GetFilePathFromDriverLocation() => SearchForConfigInDirectory(() => _environmentOperations.GetExecutionDirectory(), "driver"); + + private string SearchForConfigInDirectory(Func directoryProvider, string directoryDescription) + { + try + { + var directory = directoryProvider.Invoke(); + if (string.IsNullOrEmpty(directory)) + { + s_logger.Warn($"The {directoryDescription} directory could not be determined and will be skipped"); + return null; + } + + var filePath = Path.Combine(directory, ClientConfigFileName); + return OnlyIfFileExists(filePath, directoryDescription); + } + catch (Exception e) + { + s_logger.Error($"Error while searching for the client config in {directoryDescription} directory: {e}"); + return null; + } + } + + private string OnlyIfFileExists(string filePath, string directoryDescription) + { + if (_fileOperations.Exists(filePath)) + { + s_logger.Info($"Using config file specified from {directoryDescription} directory: {filePath}"); + return filePath; + } + return null; + } + + private void CheckIfValidPermissions(string filePath) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return; + + // Check if others have permissions to modify the file and fail if so + if (_unixOperations.CheckFileHasAnyOfPermissions(filePath, FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite)) + { + var errorMessage = $"Error due to other users having permission to modify the config file: {filePath}"; + s_logger.Error(errorMessage); + throw new Exception(errorMessage); + } + } + } +} diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs b/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs new file mode 100644 index 000000000..2285b754b --- /dev/null +++ b/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Snowflake.Data.Log; + +namespace Snowflake.Data.Configuration +{ + internal class EasyLoggingConfigParser + { + private static readonly SFLogger s_logger = SFLoggerFactory.GetSimpleLogger(); + + public static readonly EasyLoggingConfigParser Instance = new EasyLoggingConfigParser(); + + public virtual ClientConfig Parse(string filePath) + { + var configFile = TryToReadFile(filePath); + return configFile == null ? null : TryToParseFile(configFile); + } + + private string TryToReadFile(string filePath) + { + if (string.IsNullOrEmpty(filePath)) + { + return null; + } + try + { + return File.ReadAllText(filePath); + } + catch (Exception e) + { + var errorMessage = "Finding easy logging configuration failed"; + s_logger.Error(errorMessage, e); + throw new Exception(errorMessage); + } + } + + private ClientConfig TryToParseFile(string fileContent) + { + try + { + var config = JsonConvert.DeserializeObject(fileContent); + Validate(config); + CheckForUnknownFields(fileContent); + return config; + } + catch (Exception e) + { + var errorMessage = "Parsing easy logging configuration failed"; + s_logger.Error(errorMessage, e); + throw new Exception(errorMessage); + } + } + + private void Validate(ClientConfig config) + { + if (config.CommonProps.LogLevel != null) + { + EasyLoggingLogLevelExtensions.From(config.CommonProps.LogLevel); + } + } + + private void CheckForUnknownFields(string fileContent) + { + // Parse the specified config file and get the key-value pairs from the "common" section + List knownProperties = typeof(ClientConfigCommonProps).GetProperties() + .Select(property => property.GetCustomAttribute().PropertyName) + .ToList(); + + JObject.Parse(fileContent).GetValue("common", StringComparison.OrdinalIgnoreCase)? + .Cast() + .Where(property => !knownProperties.Contains(property.Name, StringComparer.OrdinalIgnoreCase)) + .ToList() + .ForEach(unknownKey => s_logger.Warn($"Unknown field from config: {unknownKey.Name}")); + } + } +} diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigProvider.cs b/Snowflake.Data/Configuration/EasyLoggingConfigProvider.cs new file mode 100644 index 000000000..027d6b695 --- /dev/null +++ b/Snowflake.Data/Configuration/EasyLoggingConfigProvider.cs @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +namespace Snowflake.Data.Configuration +{ + internal class EasyLoggingConfigProvider + { + private readonly EasyLoggingConfigFinder _finder; + + private readonly EasyLoggingConfigParser _configParser; + + public static readonly EasyLoggingConfigProvider Instance = new EasyLoggingConfigProvider(); + + internal EasyLoggingConfigProvider() : this(EasyLoggingConfigFinder.Instance, EasyLoggingConfigParser.Instance) + { + } + + internal EasyLoggingConfigProvider(EasyLoggingConfigFinder finder, EasyLoggingConfigParser configParser) + { + _finder = finder; + _configParser = configParser; + } + + public virtual ClientConfig ProvideConfig(string configFilePathFromConnectionString) + { + var filePath = _finder.FindConfigFilePath(configFilePathFromConnectionString); + return filePath == null ? null : _configParser.Parse(filePath); + } + } +} diff --git a/Snowflake.Data/Configuration/EasyLoggingLogLevel.cs b/Snowflake.Data/Configuration/EasyLoggingLogLevel.cs new file mode 100644 index 000000000..450a9bcf1 --- /dev/null +++ b/Snowflake.Data/Configuration/EasyLoggingLogLevel.cs @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; + +namespace Snowflake.Data.Configuration +{ + internal enum EasyLoggingLogLevel + { + Off, + Error, + Warn, + Info, + Debug, + Trace + } + + internal static class EasyLoggingLogLevelExtensions + { + public static EasyLoggingLogLevel From(string logLevel) + { + return (EasyLoggingLogLevel) Enum.Parse(typeof(EasyLoggingLogLevel), logLevel, true); + } + } +} diff --git a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs new file mode 100644 index 000000000..22b9302e6 --- /dev/null +++ b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using Mono.Unix; +using Mono.Unix.Native; +using Snowflake.Data.Configuration; +using Snowflake.Data.Core.Tools; +using Snowflake.Data.Log; + +namespace Snowflake.Data.Core +{ + internal class EasyLoggingStarter + { + private static readonly SFLogger s_logger = SFLoggerFactory.GetSimpleLogger(); + + private readonly EasyLoggingConfigProvider _easyLoggingConfigProvider; + + private readonly EasyLoggerManager _easyLoggerManager; + + private readonly UnixOperations _unixOperations; + + private readonly DirectoryOperations _directoryOperations; + + private readonly EnvironmentOperations _environmentOperations; + + private readonly object _lockForExclusiveInit = new object(); + + private EasyLoggingInitTrialParameters _initTrialParameters = null; + + public static readonly EasyLoggingStarter Instance = new EasyLoggingStarter(EasyLoggingConfigProvider.Instance, + EasyLoggerManager.Instance, UnixOperations.Instance, DirectoryOperations.Instance, EnvironmentOperations.Instance); + + internal EasyLoggingStarter( + EasyLoggingConfigProvider easyLoggingConfigProvider, + EasyLoggerManager easyLoggerManager, + UnixOperations unixOperations, + DirectoryOperations directoryOperations, + EnvironmentOperations environmentOperations) + { + _easyLoggingConfigProvider = easyLoggingConfigProvider; + _easyLoggerManager = easyLoggerManager; + _unixOperations = unixOperations; + _directoryOperations = directoryOperations; + _environmentOperations = environmentOperations; + } + + internal EasyLoggingStarter() + { + } + + public virtual void Init(string configFilePathFromConnectionString) + { + lock (_lockForExclusiveInit) + { + if (!AllowedToInitialize(configFilePathFromConnectionString)) + { + return; + } + if (string.IsNullOrEmpty(configFilePathFromConnectionString)) + { + s_logger.Info($"Attempting to enable easy logging without a config file specified from connection string"); + } + else + { + s_logger.Info($"Attempting to enable easy logging using config file specified from connection string: {configFilePathFromConnectionString}"); + } + var config = _easyLoggingConfigProvider.ProvideConfig(configFilePathFromConnectionString); + if (config == null) + { + _initTrialParameters = new EasyLoggingInitTrialParameters(configFilePathFromConnectionString); + return; + } + var logLevel = GetLogLevel(config.CommonProps.LogLevel); + var logPath = GetLogPath(config.CommonProps.LogPath); + s_logger.Info($"LogLevel set to {logLevel}"); + s_logger.Info($"LogPath set to {logPath}"); + _easyLoggerManager.ReconfigureEasyLogging(logLevel, logPath); + _initTrialParameters = new EasyLoggingInitTrialParameters(configFilePathFromConnectionString); + } + } + + internal void Reset(EasyLoggingLogLevel logLevel) + { + lock (_lockForExclusiveInit) + { + _initTrialParameters = null; + _easyLoggerManager.ResetEasyLogging(logLevel); + } + } + + private bool AllowedToInitialize(string configFilePathFromConnectionString) + { + var everTriedToInitialize = _initTrialParameters != null; + var triedToInitializeWithoutConfigFile = everTriedToInitialize && !_initTrialParameters.IsConfigFilePathGiven(); + var isGivenConfigFilePath = !string.IsNullOrEmpty(configFilePathFromConnectionString); + var isAllowedToInitialize = !everTriedToInitialize || (triedToInitializeWithoutConfigFile && isGivenConfigFilePath); + if (!isAllowedToInitialize && _initTrialParameters.HasDifferentConfigPath(configFilePathFromConnectionString)) + { + s_logger.Warn($"Easy logging will not be configured for CLIENT_CONFIG_FILE={configFilePathFromConnectionString} because it was previously configured for a different client config"); + } + + return isAllowedToInitialize; + } + + private EasyLoggingLogLevel GetLogLevel(string logLevel) + { + if (string.IsNullOrEmpty(logLevel)) + { + s_logger.Warn("LogLevel in client config not found. Using default value: OFF"); + return EasyLoggingLogLevel.Off; + } + return EasyLoggingLogLevelExtensions.From(logLevel); + } + + private string GetLogPath(string logPath) + { + var logPathOrDefault = logPath; + if (string.IsNullOrEmpty(logPath)) + { + s_logger.Warn("LogPath in client config not found. Using home directory as a default value"); + logPathOrDefault = HomeDirectoryProvider.HomeDirectory(_environmentOperations); + if (string.IsNullOrEmpty(logPathOrDefault)) + { + throw new Exception("No log path found for easy logging. Home directory is not configured and log path is not provided"); + } + } + var pathWithDotnetSubdirectory = Path.Combine(logPathOrDefault, "dotnet"); + if (!_directoryOperations.Exists(pathWithDotnetSubdirectory)) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + _directoryOperations.CreateDirectory(pathWithDotnetSubdirectory); + } + else + { + if (!Directory.Exists(logPathOrDefault)) + { + Directory.CreateDirectory(logPathOrDefault); + } + var createDirResult = _unixOperations.CreateDirectoryWithPermissions(pathWithDotnetSubdirectory, + FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR); + if (createDirResult != 0) + { + s_logger.Error($"Failed to create logs directory: {pathWithDotnetSubdirectory}"); + throw new Exception("Failed to create logs directory"); + } + } + } + CheckDirPermissionsOnlyAllowUser(pathWithDotnetSubdirectory); + + return pathWithDotnetSubdirectory; + } + + private void CheckDirPermissionsOnlyAllowUser(string dirPath) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return; + + var dirPermissions = _unixOperations.GetDirPermissions(dirPath); + if (dirPermissions != FileAccessPermissions.UserReadWriteExecute) + { + s_logger.Warn($"Access permission for the logs directory is currently " + + $"{UnixFilePermissionsConverter.ConvertFileAccessPermissionsToInt(dirPermissions)} " + + $"and is potentially accessible to users other than the owner of the logs directory"); + } + } + } + + internal class EasyLoggingInitTrialParameters + { + private readonly string _configFilePathFromConnectionString; + + public EasyLoggingInitTrialParameters( + string configFilePathFromConnectionString) + { + _configFilePathFromConnectionString = configFilePathFromConnectionString; + } + + public bool IsConfigFilePathGiven() + { + return _configFilePathFromConnectionString != null; + } + + public bool HasDifferentConfigPath(string configFilePath) + { + return IsConfigFilePathGiven() + && configFilePath != null + && _configFilePathFromConnectionString != configFilePath; + } + } +} diff --git a/Snowflake.Data/Core/Session/SFSession.cs b/Snowflake.Data/Core/Session/SFSession.cs index 8e5577481..568be8351 100755 --- a/Snowflake.Data/Core/Session/SFSession.cs +++ b/Snowflake.Data/Core/Session/SFSession.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2024 Snowflake Computing Inc. All rights reserved. */ @@ -68,6 +68,8 @@ public class SFSession private int arrayBindStageThreshold = 0; internal int masterValidityInSeconds = 0; + private readonly EasyLoggingStarter _easyLoggingStarter = EasyLoggingStarter.Instance; + private long _startTime = 0; internal string ConnectionString { get; } internal SecureString Password { get; } @@ -157,8 +159,16 @@ internal Uri BuildLoginUrl() /// A string in the form of "key1=value1;key2=value2" internal SFSession( String connectionString, - SecureString password) + SecureString password) : this(connectionString, password, EasyLoggingStarter.Instance) + { + } + + internal SFSession( + String connectionString, + SecureString password, + EasyLoggingStarter easyLoggingStarter) { + _easyLoggingStarter = easyLoggingStarter; ConnectionString = connectionString; Password = password; properties = SFSessionProperties.ParseConnectionString(ConnectionString, Password); @@ -175,6 +185,8 @@ internal SFSession( _HttpClient = HttpUtil.Instance.GetHttpClient(httpClientConfig); restRequester = new RestRequester(_HttpClient); _poolConfig = extractedProperties.BuildConnectionPoolConfig(); + properties.TryGetValue(SFSessionProperty.CLIENT_CONFIG_FILE, out var easyLoggingConfigFile); + _easyLoggingStarter.Init(easyLoggingConfigFile); properties.TryGetValue(SFSessionProperty.QUERY_TAG, out _queryTag); _maxRetryCount = extractedProperties.maxHttpRetries; _maxRetryTimeout = extractedProperties.retryTimeout; diff --git a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs index 291fddd9a..daee66d65 100644 --- a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs +++ b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs @@ -23,5 +23,17 @@ public virtual string GetFolderPath(Environment.SpecialFolder folder) { return Environment.GetFolderPath(folder); } + + public virtual string GetExecutionDirectory() + { + var executablePath = Environment.GetCommandLineArgs()[0]; + var directoryName = string.IsNullOrEmpty(executablePath) ? null : Path.GetDirectoryName(executablePath); + if (string.IsNullOrEmpty(directoryName)) + { + s_logger.LogWarning("Unable to determine execution directory"); + return null; + } + return directoryName; + } } } diff --git a/Snowflake.Data/Logger/EasyLoggerManager.cs b/Snowflake.Data/Logger/EasyLoggerManager.cs new file mode 100644 index 000000000..13347cdfc --- /dev/null +++ b/Snowflake.Data/Logger/EasyLoggerManager.cs @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using System.IO; +using System.Linq; +using log4net; +using log4net.Appender; +using log4net.Layout; +using Snowflake.Data.Configuration; + +namespace Snowflake.Data.Log +{ + internal class EasyLoggerManager + { + public static readonly EasyLoggerManager Instance = new EasyLoggerManager(); + + private readonly object _lockForExclusiveConfigure = new object(); + + private const string AppenderPrefix = "SFEasyLogging"; + + private readonly EasyLoggingLevelMapper _levelMapper = EasyLoggingLevelMapper.Instance; + + public virtual void ReconfigureEasyLogging(EasyLoggingLogLevel easyLoggingLogLevel, string logsPath) + { + var log4netLevel = _levelMapper.ToLog4NetLevel(easyLoggingLogLevel); + lock (_lockForExclusiveConfigure) + { + var repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); + var rootLogger = (log4net.Repository.Hierarchy.Logger)repository.GetLogger("Snowflake.Data"); + rootLogger.Level = log4netLevel; + var appender = string.Equals(logsPath, "STDOUT", StringComparison.OrdinalIgnoreCase) + ? AddConsoleAppender(rootLogger) + : AddRollingFileAppender(rootLogger, logsPath); + RemoveOtherEasyLoggingAppenders(rootLogger, appender); + repository.RaiseConfigurationChanged(EventArgs.Empty); + } + } + + internal void ResetEasyLogging(EasyLoggingLogLevel easyLoggingLogLevel) + { + var log4netLevel = _levelMapper.ToLog4NetLevel(easyLoggingLogLevel); + lock (_lockForExclusiveConfigure) + { + var repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); + var rootLogger = (log4net.Repository.Hierarchy.Logger)repository.GetLogger("Snowflake.Data"); + rootLogger.Level = log4netLevel; + RemoveOtherEasyLoggingAppenders(rootLogger, null); + repository.RaiseConfigurationChanged(EventArgs.Empty); + } + } + + internal static bool HasEasyLoggingAppender() + { + var repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); + var rootLogger = (log4net.Repository.Hierarchy.Logger)repository.GetLogger("Snowflake.Data"); + return rootLogger.Appenders.ToArray().Any(IsEasyLoggingAppender); + } + + private static void RemoveOtherEasyLoggingAppenders(log4net.Repository.Hierarchy.Logger logger, IAppender appender) + { + var existingAppenders = logger.Appenders.ToArray(); + foreach (var existingAppender in existingAppenders) + { + if (IsEasyLoggingAppender(existingAppender) && existingAppender != appender) + { + logger.RemoveAppender(existingAppender); + } + } + } + + private static IAppender AddRollingFileAppender(log4net.Repository.Hierarchy.Logger logger, + string directoryPath) + { + var patternLayout = PatternLayout(); + var randomFileName = $"snowflake_dotnet_{Path.GetRandomFileName()}"; + var logFileName = randomFileName.Substring(0, randomFileName.Length - 4) + ".log"; + var appender = new RollingFileAppender + { + Layout = patternLayout, + AppendToFile = true, + File = Path.Combine(directoryPath, logFileName), + Name = $"{AppenderPrefix}RollingFileAppender", + StaticLogFileName = true, + RollingStyle = RollingFileAppender.RollingMode.Size, + MaximumFileSize = "1GB", + MaxSizeRollBackups = 2, + PreserveLogFileNameExtension = true, + LockingModel = new FileAppender.MinimalLock() + }; + appender.ActivateOptions(); + logger.AddAppender(appender); + return appender; + } + + private static bool IsEasyLoggingAppender(IAppender appender) + { + if (appender.GetType() == typeof(ConsoleAppender)) + { + var consoleAppender = (ConsoleAppender)appender; + return consoleAppender.Name != null && consoleAppender.Name.StartsWith(AppenderPrefix); + } + + if (appender.GetType() == typeof(RollingFileAppender)) + { + var rollingFileAppender = (RollingFileAppender)appender; + return rollingFileAppender.Name != null && rollingFileAppender.Name.StartsWith(AppenderPrefix); + } + + return false; + } + + private static IAppender AddConsoleAppender(log4net.Repository.Hierarchy.Logger logger) + { + var patternLayout = PatternLayout(); + var appender = new ConsoleAppender() + { + Layout = patternLayout, + Name = $"{AppenderPrefix}ConsoleAppender" + }; + appender.ActivateOptions(); + logger.AddAppender(appender); + return appender; + } + + private static PatternLayout PatternLayout() + { + var patternLayout = new PatternLayout + { + ConversionPattern = "[%date] [%t] [%-5level] [%logger] %message%newline" + }; + patternLayout.ActivateOptions(); + return patternLayout; + } + } +} diff --git a/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs b/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs new file mode 100644 index 000000000..c36f489bf --- /dev/null +++ b/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using log4net.Core; +using Snowflake.Data.Configuration; + +namespace Snowflake.Data.Log +{ + internal class EasyLoggingLevelMapper + { + public static readonly EasyLoggingLevelMapper Instance = new EasyLoggingLevelMapper(); + + public Level ToLog4NetLevel(EasyLoggingLogLevel level) + { + switch (level) + { + case EasyLoggingLogLevel.Off: return Level.Off; + case EasyLoggingLogLevel.Error: return Level.Error; + case EasyLoggingLogLevel.Warn: return Level.Warn; + case EasyLoggingLogLevel.Info: return Level.Info; + case EasyLoggingLogLevel.Debug: return Level.Debug; + case EasyLoggingLogLevel.Trace: return Level.Trace; + default: throw new Exception("Unknown log level"); + } + } + } +} diff --git a/Snowflake.Data/Logger/Log4netImpl.cs b/Snowflake.Data/Logger/Log4netImpl.cs new file mode 100644 index 000000000..33479a011 --- /dev/null +++ b/Snowflake.Data/Logger/Log4netImpl.cs @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. + */ + +using log4net; +using System; + +namespace Snowflake.Data.Log +{ + // Default implementation for SFLogger + + class Log4NetImpl : SFLogger + { + private readonly ILog logger; + + public Log4NetImpl(ILog logger) + { + this.logger = logger; + } + + public bool IsDebugEnabled() + { + return logger.IsDebugEnabled; + } + + public bool IsInfoEnabled() + { + return logger.IsInfoEnabled; + } + + public bool IsWarnEnabled() + { + return logger.IsWarnEnabled; + } + + public bool IsErrorEnabled() + { + return logger.IsErrorEnabled; + } + + public bool IsFatalEnabled() + { + return logger.IsFatalEnabled; + } + + public void Debug(string msg, Exception ex = null) + { + msg = SecretDetector.MaskSecrets(msg).maskedText; + logger.Debug(msg, ex); + } + + public void Info(string msg, Exception ex = null) + { + msg = SecretDetector.MaskSecrets(msg).maskedText; + logger.Info(msg, ex); + } + + public void Warn(string msg, Exception ex = null) + { + msg = SecretDetector.MaskSecrets(msg).maskedText; + logger.Warn(msg, ex); + } + + + public void Error(string msg, Exception ex = null) + { + msg = SecretDetector.MaskSecrets(msg).maskedText; + logger.Error(msg, ex); + } + + public void Fatal(string msg, Exception ex = null) + { + msg = SecretDetector.MaskSecrets(msg).maskedText; + logger.Fatal(msg, ex); + } + } + +} diff --git a/Snowflake.Data/Logger/SFLogger.cs b/Snowflake.Data/Logger/SFLogger.cs new file mode 100644 index 000000000..00badc38b --- /dev/null +++ b/Snowflake.Data/Logger/SFLogger.cs @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Snowflake.Data.Log +{ + interface SFLogger + { + bool IsDebugEnabled(); + + bool IsInfoEnabled(); + + bool IsWarnEnabled(); + + bool IsErrorEnabled(); + + bool IsFatalEnabled(); + + void Debug(string msg, Exception ex = null); + + void Info(string msg, Exception ex = null); + + void Warn(string msg, Exception ex = null); + + void Error(string msg, Exception ex = null); + + void Fatal(string msg, Exception ex = null); + } + + enum LoggingEvent + { + DEBUG, INFO, WARN, ERROR, FATAL + } + +} diff --git a/Snowflake.Data/Logger/SFLoggerEmptySimpleImpl.cs b/Snowflake.Data/Logger/SFLoggerEmptySimpleImpl.cs new file mode 100644 index 000000000..d24d4bc9a --- /dev/null +++ b/Snowflake.Data/Logger/SFLoggerEmptySimpleImpl.cs @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. + */ + +using System; + +namespace Snowflake.Data.Log +{ + // Empty implementation of SFLogger + // Used when SFLoggerFactory.disableLogger() is called. + + class SFLoggerEmptySimpleImpl : SFLogger + { + public bool IsDebugEnabled() + { + return false; + } + + public bool IsInfoEnabled() + { + return false; + } + + public bool IsWarnEnabled() + { + return false; + } + + public bool IsErrorEnabled() + { + return false; + } + + public bool IsFatalEnabled() + { + return false; + } + + public void Debug(string msg, Exception ex) + { + return; + } + + public void Info(string msg, Exception ex) + { + return; + } + + public void Warn(string msg, Exception ex) + { + return; + } + + public void Error(string msg, Exception ex) + { + return; + } + + public void Fatal(string msg, Exception ex) + { + return; + } + } + +} diff --git a/Snowflake.Data/Logger/SFLoggerFactory.cs b/Snowflake.Data/Logger/SFLoggerFactory.cs index 7b06454cf..0107b4635 100755 --- a/Snowflake.Data/Logger/SFLoggerFactory.cs +++ b/Snowflake.Data/Logger/SFLoggerFactory.cs @@ -1,7 +1,8 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ +using log4net; using Microsoft.Extensions.Logging; namespace Snowflake.Data.Log @@ -36,6 +37,21 @@ public static void SetCustomLogger(ILogger customLogger) logger = customLogger; } + internal static SFLogger GetSimpleLogger() + { + // If true, return the default/specified logger + if (isLoggerEnabled) + { + ILog loggerL = LogManager.GetLogger(typeof(T)); + return new Log4NetImpl(loggerL); + } + // Else, return the empty logger implementation which outputs nothing + else + { + return new SFLoggerEmptySimpleImpl(); + } + } + internal static ILogger GetLogger() { // If true, return the default/specified logger diff --git a/Snowflake.Data/Snowflake.Data.csproj b/Snowflake.Data/Snowflake.Data.csproj index a61cb465c..b99e078fb 100644 --- a/Snowflake.Data/Snowflake.Data.csproj +++ b/Snowflake.Data/Snowflake.Data.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 Snowflake.Data @@ -22,6 +22,7 @@ + From 3f3a15c75f95ec40bac4041dda49c20a14f11e7f Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Thu, 21 Nov 2024 12:08:36 -0800 Subject: [PATCH 08/35] Refactor original logger to simple logger --- Snowflake.Data.Tests/SFBaseTest.cs | 9 -- .../UnitTests/Logger/SFSimpleLoggerTest.cs | 112 ++++++++++++++++++ Snowflake.Data/Logger/SFLoggerFactory.cs | 28 +++-- 3 files changed, 133 insertions(+), 16 deletions(-) create mode 100644 Snowflake.Data.Tests/UnitTests/Logger/SFSimpleLoggerTest.cs diff --git a/Snowflake.Data.Tests/SFBaseTest.cs b/Snowflake.Data.Tests/SFBaseTest.cs index 6153b337e..c05b042b9 100755 --- a/Snowflake.Data.Tests/SFBaseTest.cs +++ b/Snowflake.Data.Tests/SFBaseTest.cs @@ -195,15 +195,6 @@ public void Setup() var logRepository = log4net.LogManager.GetRepository(Assembly.GetEntryAssembly()); log4net.Config.XmlConfigurator.Configure(logRepository, new FileInfo("App.config")); #endif - ILoggerFactory factory = LoggerFactory.Create( - builder => builder - .AddLog4Net() - .SetMinimumLevel(LogLevel.Debug)); - - var logger = factory.CreateLogger("SFBaseTest"); - SFLoggerFactory.SetCustomLogger(logger); - SFLoggerFactory.EnableLogger(); - var cloud = Environment.GetEnvironmentVariable("snowflake_cloud_env"); Assert.IsTrue(cloud == null || cloud == "AWS" || cloud == "AZURE" || cloud == "GCP", "{0} is not supported. Specify AWS, AZURE or GCP as cloud environment", cloud); diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFSimpleLoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFSimpleLoggerTest.cs new file mode 100644 index 000000000..7ed3f20d8 --- /dev/null +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFSimpleLoggerTest.cs @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. + */ + +using NUnit.Framework; +using Snowflake.Data.Configuration; +using Snowflake.Data.Log; + +namespace Snowflake.Data.Tests.UnitTests +{ + [TestFixture, NonParallelizable] + class SFSimpleLoggerTest + { + SFLogger _logger; + + [OneTimeSetUp] + public static void BeforeTest() + { + // Log level defaults to Warn on net6.0 builds in github actions + // Set the root level to Debug + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Debug, "STDOUT"); + } + + [OneTimeTearDown] + public static void AfterAll() + { + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, "STDOUT"); + } + + [TearDown] + public void AfterTest() + { + // Return to default setting + SFLoggerFactory.EnableSimpleLogger(); + } + + [Test] + public void TestUsingSimpleLogger() + { + SFLoggerFactory.EnableSimpleLogger(); + _logger = SFLoggerFactory.GetSimpleLogger(); + Assert.IsInstanceOf(_logger); + } + + [Test] + public void TestSettingCustomLogger() + { + SFLoggerFactory.DisableSimpleLogger(); + _logger = SFLoggerFactory.GetSimpleLogger(); + Assert.IsInstanceOf(_logger); + } + + [Test] + public void TestIsDebugEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _logger.IsDebugEnabled()); + } + + [Test] + public void TestIsInfoEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _logger.IsInfoEnabled()); + } + + [Test] + public void TestIsWarnEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _logger.IsWarnEnabled()); + } + + [Test] + public void TestIsErrorEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _logger.IsErrorEnabled()); + } + + [Test] + public void TestIsFatalEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _logger.IsFatalEnabled()); + } + + private SFLogger GetLogger(bool isEnabled) + { + if (isEnabled) + { + SFLoggerFactory.EnableSimpleLogger(); + } + else + { + SFLoggerFactory.DisableSimpleLogger(); + } + + return SFLoggerFactory.GetSimpleLogger(); + } + } +} diff --git a/Snowflake.Data/Logger/SFLoggerFactory.cs b/Snowflake.Data/Logger/SFLoggerFactory.cs index 0107b4635..8fe71b486 100755 --- a/Snowflake.Data/Logger/SFLoggerFactory.cs +++ b/Snowflake.Data/Logger/SFLoggerFactory.cs @@ -11,12 +11,26 @@ public class SFLoggerFactory { private static bool isLoggerEnabled = false; - private static ILogger logger = null; + private static bool isSimpleLoggerEnabled = true; + + private static SFLogger simpleLogger = null; + + private static ILogger customLogger = null; private SFLoggerFactory() { } + public static void DisableSimpleLogger() + { + isSimpleLoggerEnabled = false; + } + + public static void EnableSimpleLogger() + { + isSimpleLoggerEnabled = true; + } + public static void DisableLogger() { isLoggerEnabled = false; @@ -29,18 +43,18 @@ public static void EnableLogger() public static void UseDefaultLogger() { - logger = null; + customLogger = null; } public static void SetCustomLogger(ILogger customLogger) - { - logger = customLogger; + { + SFLoggerFactory.customLogger = customLogger; } internal static SFLogger GetSimpleLogger() { // If true, return the default/specified logger - if (isLoggerEnabled) + if (isSimpleLoggerEnabled) { ILog loggerL = LogManager.GetLogger(typeof(T)); return new Log4NetImpl(loggerL); @@ -58,7 +72,7 @@ internal static ILogger GetLogger() if (isLoggerEnabled) { // If no logger specified, use the default logger: Microsoft's console logger - if (logger == null) + if (customLogger == null) { ILoggerFactory factory = LoggerFactory.Create( builder => builder @@ -68,7 +82,7 @@ internal static ILogger GetLogger() return factory.CreateLogger(); } - return logger; + return customLogger; } // Else, return the empty logger implementation which outputs nothing else From 188f82a675472743228e7f7ab35efe12aca26953 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 29 Nov 2024 10:43:21 -0800 Subject: [PATCH 09/35] Add initial impl. for own Snowflake logger --- .../UnitTests/Logger/EasyLoggerManagerTest.cs | 4 +- .../Logger/EasyLoggingStarterTest.cs | 274 ++++++++++++++++ .../UnitTests/Logger/ILoggerTest.cs | 210 ++++++++++++ .../UnitTests/Logger/SFLoggerTest.cs | 247 +++++---------- .../UnitTests/Logger/SFSimpleLoggerTest.cs | 112 ------- .../Configuration/EasyLoggingConfigFinder.cs | 2 +- .../Configuration/EasyLoggingConfigParser.cs | 2 +- .../Core/Session/EasyLoggingStarter.cs | 2 +- Snowflake.Data/Logger/EasyLoggerManager.cs | 77 ++--- .../Logger/EasyLoggingLevelMapper.cs | 15 +- Snowflake.Data/Logger/ILoggerEmptyImpl.cs | 31 ++ Snowflake.Data/Logger/Log4netImpl.cs | 78 ----- Snowflake.Data/Logger/SFLogger.cs | 17 +- Snowflake.Data/Logger/SFLoggerEmptyImpl.cs | 69 +++- .../Logger/SFLoggerEmptySimpleImpl.cs | 65 ---- Snowflake.Data/Logger/SFLoggerFactory.cs | 61 ++-- Snowflake.Data/Logger/SFLoggerImpl.cs | 298 ++++++++++++++++++ Snowflake.Data/Snowflake.Data.csproj | 1 - 18 files changed, 1039 insertions(+), 526 deletions(-) create mode 100644 Snowflake.Data.Tests/UnitTests/Logger/EasyLoggingStarterTest.cs create mode 100644 Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs delete mode 100644 Snowflake.Data.Tests/UnitTests/Logger/SFSimpleLoggerTest.cs create mode 100644 Snowflake.Data/Logger/ILoggerEmptyImpl.cs delete mode 100644 Snowflake.Data/Logger/Log4netImpl.cs delete mode 100644 Snowflake.Data/Logger/SFLoggerEmptySimpleImpl.cs create mode 100644 Snowflake.Data/Logger/SFLoggerImpl.cs diff --git a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs index 599f1ce5a..f9abac8e6 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs @@ -49,7 +49,7 @@ public void AfterEach() public void TestThatChangesLogLevel() { // arrange - var logger = SFLoggerFactory.GetSimpleLogger(); + var logger = SFLoggerFactory.GetSFLogger(); EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, t_directoryLogPath); // assert @@ -74,7 +74,7 @@ public void TestThatChangesLogLevel() public void TestThatLogsToProperFileWithProperLogLevelOnly() { // arrange - var logger = SFLoggerFactory.GetSimpleLogger(); + var logger = SFLoggerFactory.GetSFLogger(); EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Info, t_directoryLogPath); // act diff --git a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggingStarterTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggingStarterTest.cs new file mode 100644 index 000000000..208f17743 --- /dev/null +++ b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggingStarterTest.cs @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using Mono.Unix; +using Mono.Unix.Native; +using Moq; +using NUnit.Framework; +using Snowflake.Data.Configuration; +using Snowflake.Data.Core; +using Snowflake.Data.Core.Tools; +using Snowflake.Data.Log; + +namespace Snowflake.Data.Tests.UnitTests.Session +{ + [TestFixture] + public class EasyLoggingStarterTest + { + private static readonly string HomeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + private static readonly string LogPath = Path.Combine(HomeDirectory, "some-logs-path/some-folder"); + private const string ConfigPath = "/some-path/config.json"; + private const string AnotherConfigPath = "/another/path"; + private static readonly string s_expectedLogPath = Path.Combine(LogPath, "dotnet"); + + private static readonly ClientConfig s_configWithErrorLevel = new ClientConfig + { + CommonProps = new ClientConfigCommonProps + { + LogLevel = "Error", + LogPath = LogPath + } + }; + + private static readonly ClientConfig s_configWithInfoLevel = new ClientConfig + { + CommonProps = new ClientConfigCommonProps + { + LogLevel = "Info", + LogPath = LogPath + } + }; + + private static readonly ClientConfig s_configWithNoLogPath = new ClientConfig + { + CommonProps = new ClientConfigCommonProps + { + LogLevel = "Info" + } + }; + + [ThreadStatic] + private static Mock t_easyLoggingProvider; + + [ThreadStatic] + private static Mock t_easyLoggerManager; + + [ThreadStatic] + private static Mock t_unixOperations; + + [ThreadStatic] + private static Mock t_directoryOperations; + + [ThreadStatic] + private static Mock t_environmentOperations; + + [ThreadStatic] + private static EasyLoggingStarter t_easyLoggerStarter; + + [SetUp] + public void BeforeEach() + { + t_easyLoggingProvider = new Mock(); + t_easyLoggerManager = new Mock(); + t_unixOperations = new Mock(); + t_directoryOperations = new Mock(); + t_environmentOperations = new Mock(); + t_easyLoggerStarter = new EasyLoggingStarter( + t_easyLoggingProvider.Object, + t_easyLoggerManager.Object, + t_unixOperations.Object, + t_directoryOperations.Object, + t_environmentOperations.Object); + } + + [Test] + public void TestThatThrowsErrorWhenLogPathAndHomeDirectoryIsNotSet() + { + // arrange + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(ConfigPath)) + .Returns(s_configWithNoLogPath); + t_environmentOperations + .Setup(env => env.GetFolderPath(Environment.SpecialFolder.UserProfile)) + .Returns(""); + + // act + var thrown = Assert.Throws(() => t_easyLoggerStarter.Init(ConfigPath)); + + // assert + Assert.IsNotNull(thrown); + Assert.AreEqual(thrown.Message, "No log path found for easy logging. Home directory is not configured and log path is not provided"); + } + + [Test] + public void TestThatThrowsErrorWhenLogPathIsNotSetAndHomeDirectoryThrowsAnException() + { + // arrange + var ex = new Exception("No home directory"); + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(ConfigPath)) + .Returns(s_configWithNoLogPath); + t_environmentOperations + .Setup(env => env.GetFolderPath(Environment.SpecialFolder.UserProfile)) + .Throws(() => ex); + + // act + var thrown = Assert.Throws(() => t_easyLoggerStarter.Init(ConfigPath)); + + // assert + Assert.IsNotNull(thrown); + Assert.AreEqual(thrown.Message, "No log path found for easy logging. Home directory is not configured and log path is not provided"); + } + + [Test] + public void TestThatDoesNotFailWhenLogDirectoryPermissionIsNot700() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Assert.Ignore("skip test on Windows"); + } + + // arrange + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(ConfigPath)) + .Returns(s_configWithInfoLevel); + t_directoryOperations + .Setup(dir => dir.Exists(s_expectedLogPath)) + .Returns(true); + t_unixOperations + .Setup(unix => unix.GetDirPermissions(s_expectedLogPath)) + .Returns(FileAccessPermissions.AllPermissions); + + // act + t_easyLoggerStarter.Init(ConfigPath); + + // assert + t_unixOperations.Verify(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, + FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR), Times.Never); + } + + [Test] + public void TestFailIfDirectoryCreationFails() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Assert.Ignore("skip test on Windows"); + } + + // arrange + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(ConfigPath)) + .Returns(s_configWithErrorLevel); + t_unixOperations + .Setup(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR)) + .Returns((int)Errno.EPERM); + + // act + var thrown = Assert.Throws(() => t_easyLoggerStarter.Init(ConfigPath)); + + // assert + Assert.That(thrown.Message, Does.Contain("Failed to create logs directory")); + } + + [Test] + public void TestThatConfiguresEasyLoggingOnlyOnceWhenInitializedWithConfigPath() + { + // arrange + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(ConfigPath)) + .Returns(s_configWithErrorLevel); + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(null)) + .Returns(s_configWithInfoLevel); + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(AnotherConfigPath)) + .Returns(s_configWithInfoLevel); + + // act + t_easyLoggerStarter.Init(ConfigPath); + + // assert + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + t_directoryOperations.Verify(d => d.CreateDirectory(s_expectedLogPath), Times.Once); + } + else + { + t_unixOperations.Verify(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, + FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR), Times.Once); + } + t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Error, s_expectedLogPath), Times.Once); + + // act + t_easyLoggerStarter.Init(null); + t_easyLoggerStarter.Init(ConfigPath); + t_easyLoggerStarter.Init(AnotherConfigPath); + + // assert + t_easyLoggerManager.VerifyNoOtherCalls(); + } + + [Test] + public void TestThatConfiguresEasyLoggingOnlyOnceForInitializationsWithoutConfigPath() + { + // arrange + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(null)) + .Returns(s_configWithErrorLevel); + + // act + t_easyLoggerStarter.Init(null); + t_easyLoggerStarter.Init(null); + + // assert + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + t_directoryOperations.Verify(d => d.CreateDirectory(s_expectedLogPath), Times.Once); + } + else + { + t_unixOperations.Verify(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, + FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR), Times.Once); + } + t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Error, s_expectedLogPath), Times.Once); + } + + [Test] + public void TestThatReconfiguresEasyLoggingWithConfigPathIfNotGivenForTheFirstTime() + { + // arrange + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(null)) + .Returns(s_configWithErrorLevel); + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(ConfigPath)) + .Returns(s_configWithInfoLevel); + + // act + t_easyLoggerStarter.Init(null); + + // assert + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + t_directoryOperations.Verify(d => d.CreateDirectory(s_expectedLogPath), Times.Once); + } + else + { + t_unixOperations.Verify(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, + FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR), Times.Once); + } + t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Error, s_expectedLogPath), Times.Once); + + // act + t_easyLoggerStarter.Init(ConfigPath); + + // assert + t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Info, s_expectedLogPath), Times.Once); + t_easyLoggerManager.VerifyNoOtherCalls(); + } + } +} diff --git a/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs new file mode 100644 index 000000000..c371ac63b --- /dev/null +++ b/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. + */ + +using NUnit.Framework; +using Snowflake.Data.Log; +using Microsoft.Extensions.Logging; +using ILogger = Microsoft.Extensions.Logging.ILogger; +using NLog.Extensions.Logging; +using Serilog; +using Serilog.Extensions.Logging; +using System.IO; +using System; + +namespace Snowflake.Data.Tests.UnitTests +{ + [TestFixture, NonParallelizable] + class ILoggerTest + { + private const string InfoMessage = "Info message"; + private const string DebugMessage = "Debug message"; + private const string WarnMessage = "Warn message"; + private const string ErrorMessage = "Error message"; + private const string CriticalMessage = "critical message"; + + private const string Log4NetFileName = "test_log4net.log"; + private const string SerilogFileName = "test_serilog.log"; + private const string NlogFileName = "test_nlog.log"; + + public abstract class SFBaseLoggerTest + { + protected ILogger _logger; + protected string _logFile; + + [OneTimeSetUp] + public void BeforeTest() + { + SFLoggerFactory.EnableCustomLogger(); + } + + [OneTimeTearDown] + public void AfterTest() + { + // Return to default setting + SFLoggerFactory.UseDefaultLogger(); + SFLoggerFactory.DisableCustomLogger(); + if (_logFile != null) + { + File.Delete(_logFile); + _logFile = null; + } + } + + [Test] + public void TestUsingDefaultLogger() + { + var originalLogger = SFLoggerFactory.GetLogger(); + SFLoggerFactory.UseDefaultLogger(); + _logger = SFLoggerFactory.GetLogger(); + Assert.IsInstanceOf(_logger); + SFLoggerFactory.SetCustomLogger(originalLogger); + } + + [Test] + public void TestSettingCustomLogger() + { + var originalLogger = SFLoggerFactory.GetLogger(); + SFLoggerFactory.SetCustomLogger(new ILoggerEmptyImpl()); + _logger = SFLoggerFactory.GetLogger(); + Assert.IsInstanceOf(_logger); + SFLoggerFactory.SetCustomLogger(originalLogger); + } + + [Test] + public void TestIsDebugEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Debug)); + } + + [Test] + public void TestIsInfoEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Information)); + } + + [Test] + public void TestIsWarnEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Warning)); + } + + [Test] + public void TestIsErrorEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Error)); + } + + [Test] + public void TestIsFatalEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Critical)); + } + + private ILogger GetLogger(bool isEnabled) + { + if (isEnabled) + { + SFLoggerFactory.EnableCustomLogger(); + } + else + { + SFLoggerFactory.DisableCustomLogger(); + } + + return SFLoggerFactory.GetLogger(); + } + + [Test] + public void TestThatLogsToProperFileWithProperLogLevelOnly() + { + _logger = SFLoggerFactory.GetLogger(); + + // act + _logger.LogDebug(DebugMessage); + _logger.LogInformation(InfoMessage); + _logger.LogWarning(WarnMessage); + _logger.LogError(ErrorMessage); + _logger.LogCritical(CriticalMessage); + + // assert + using (FileStream logFileStream = new FileStream(_logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + using (StreamReader logFileReader = new StreamReader(logFileStream)) + { + string logLines = logFileReader.ReadToEnd(); + Assert.IsTrue(logLines.Contains(DebugMessage)); + Assert.IsTrue(logLines.Contains(InfoMessage)); + Assert.IsTrue(logLines.Contains(WarnMessage)); + Assert.IsTrue(logLines.Contains(ErrorMessage)); + Assert.IsTrue(logLines.Contains(CriticalMessage)); + } + } + } + } + + [TestFixture] + public class Log4NetTest : SFBaseLoggerTest + { + [OneTimeSetUp] + public void SetUp() + { + Environment.SetEnvironmentVariable("TEST_LOG4NET_FILE_NAME", Log4NetFileName); + var factory = LoggerFactory.Create( + builder => builder + .AddLog4Net("TestLog4Net.config") + .SetMinimumLevel(LogLevel.Trace)); + + var log4netLogger = factory.CreateLogger("Log4NetTest"); + SFLoggerFactory.SetCustomLogger(log4netLogger); + _logFile = Log4NetFileName; + } + } + + [TestFixture] + public class SerilogTest : SFBaseLoggerTest + { + [OneTimeSetUp] + public void SetUp() + { + var loggerSerilog = new LoggerConfiguration() + //.ReadFrom.Xml("TestSerilog.Config") + .MinimumLevel.Verbose() + .WriteTo.File(SerilogFileName) + .CreateLogger(); + + var serilogLogger = new SerilogLoggerFactory(loggerSerilog).CreateLogger("SerilogTest"); + SFLoggerFactory.SetCustomLogger(serilogLogger); + _logFile = SerilogFileName; + } + } + + [TestFixture] + public class NlogTest : SFBaseLoggerTest + { + [OneTimeSetUp] + public void SetUp() + { + Environment.SetEnvironmentVariable("TEST_NLOG_FILE_NAME", NlogFileName); + var factory = LoggerFactory.Create( + builder => builder + .AddNLog("TestNLog.config") + .SetMinimumLevel(LogLevel.Trace)); + + var nlogLogger = factory.CreateLogger("NlogTest"); + SFLoggerFactory.SetCustomLogger(nlogLogger); + _logFile = NlogFileName; + } + } + } +} diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs index 37fd8a503..f7b7cdde2 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs @@ -1,209 +1,112 @@ -/* - * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. +/* + * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. */ using NUnit.Framework; +using Snowflake.Data.Configuration; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; -using ILogger = Microsoft.Extensions.Logging.ILogger; -using NLog.Extensions.Logging; -using Serilog; -using Serilog.Extensions.Logging; -using System.IO; -using System; namespace Snowflake.Data.Tests.UnitTests { [TestFixture, NonParallelizable] class SFLoggerTest { - private const string InfoMessage = "Info message"; - private const string DebugMessage = "Debug message"; - private const string WarnMessage = "Warn message"; - private const string ErrorMessage = "Error message"; - private const string CriticalMessage = "critical message"; + SFLogger _logger; - private const string Log4NetFileName = "test_log4net.log"; - private const string SerilogFileName = "test_serilog.log"; - private const string NlogFileName = "test_nlog.log"; + [OneTimeSetUp] + public static void BeforeTest() + { + // Log level defaults to Warn on net6.0 builds in github actions + // Set the root level to Debug + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Debug, "STDOUT"); + } - public abstract class SFBaseLoggerTest + [OneTimeTearDown] + public static void AfterAll() { - protected ILogger _logger; - protected string _logFile; + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, "STDOUT"); + } - [OneTimeSetUp] - public void BeforeTest() - { - SFLoggerFactory.EnableLogger(); - } + [TearDown] + public void AfterTest() + { + // Return to default setting + SFLoggerFactory.EnableSFLogger(); + } - [OneTimeTearDown] - public void AfterTest() - { - // Return to default setting - SFLoggerFactory.UseDefaultLogger(); - SFLoggerFactory.DisableLogger(); - if (_logFile != null) - { - File.Delete(_logFile); - _logFile = null; - } - } + [Test] + public void TestUsingSimpleLogger() + { + SFLoggerFactory.EnableSFLogger(); + _logger = SFLoggerFactory.GetSFLogger(); + Assert.IsInstanceOf(_logger); + } - [Test] - public void TestUsingDefaultLogger() - { - var originalLogger = SFLoggerFactory.GetLogger(); - SFLoggerFactory.UseDefaultLogger(); - _logger = SFLoggerFactory.GetLogger(); - Assert.IsInstanceOf(_logger); - SFLoggerFactory.SetCustomLogger(originalLogger); - } + [Test] + public void TestSettingCustomLogger() + { + SFLoggerFactory.DisableSFLogger(); + _logger = SFLoggerFactory.GetSFLogger(); + Assert.IsInstanceOf(_logger); + } - [Test] - public void TestSettingCustomLogger() - { - var originalLogger = SFLoggerFactory.GetLogger(); - SFLoggerFactory.SetCustomLogger(new SFLoggerEmptyImpl()); - _logger = SFLoggerFactory.GetLogger(); - Assert.IsInstanceOf(_logger); - SFLoggerFactory.SetCustomLogger(originalLogger); - } + [Test] + public void TestIsDebugEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); - [Test] - public void TestIsDebugEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); - Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Debug)); - } + Assert.AreEqual(isEnabled, _logger.IsDebugEnabled()); + } - [Test] - public void TestIsInfoEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); - Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Information)); - } + [Test] + public void TestIsInfoEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); - [Test] - public void TestIsWarnEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); - Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Warning)); - } + Assert.AreEqual(isEnabled, _logger.IsInfoEnabled()); + } - [Test] - public void TestIsErrorEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); - Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Error)); - } + [Test] + public void TestIsWarnEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); - [Test] - public void TestIsFatalEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); - Assert.AreEqual(isEnabled, _logger.IsEnabled(LogLevel.Critical)); - } + Assert.AreEqual(isEnabled, _logger.IsWarnEnabled()); + } - private ILogger GetLogger(bool isEnabled) - { - if (isEnabled) - { - SFLoggerFactory.EnableLogger(); - } - else - { - SFLoggerFactory.DisableLogger(); - } - - return SFLoggerFactory.GetLogger(); - } + [Test] + public void TestIsErrorEnabled( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); - [Test] - public void TestThatLogsToProperFileWithProperLogLevelOnly() - { - _logger = SFLoggerFactory.GetLogger(); - - // act - _logger.LogDebug(DebugMessage); - _logger.LogInformation(InfoMessage); - _logger.LogWarning(WarnMessage); - _logger.LogError(ErrorMessage); - _logger.LogCritical(CriticalMessage); - - // assert - using (FileStream logFileStream = new FileStream(_logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - { - using (StreamReader logFileReader = new StreamReader(logFileStream)) - { - string logLines = logFileReader.ReadToEnd(); - Assert.IsTrue(logLines.Contains(DebugMessage)); - Assert.IsTrue(logLines.Contains(InfoMessage)); - Assert.IsTrue(logLines.Contains(WarnMessage)); - Assert.IsTrue(logLines.Contains(ErrorMessage)); - Assert.IsTrue(logLines.Contains(CriticalMessage)); - } - } - } + Assert.AreEqual(isEnabled, _logger.IsErrorEnabled()); } - [TestFixture] - public class Log4NetTest : SFBaseLoggerTest + [Test] + public void TestIsFatalEnabled( + [Values(false, true)] bool isEnabled) { - [OneTimeSetUp] - public void SetUp() - { - Environment.SetEnvironmentVariable("TEST_LOG4NET_FILE_NAME", Log4NetFileName); - var factory = LoggerFactory.Create( - builder => builder - .AddLog4Net("TestLog4Net.config") - .SetMinimumLevel(LogLevel.Trace)); - - var log4netLogger = factory.CreateLogger("Log4NetTest"); - SFLoggerFactory.SetCustomLogger(log4netLogger); - _logFile = Log4NetFileName; - } + _logger = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _logger.IsFatalEnabled()); } - [TestFixture] - public class SerilogTest : SFBaseLoggerTest + private SFLogger GetLogger(bool isEnabled) { - [OneTimeSetUp] - public void SetUp() + if (isEnabled) { - var loggerSerilog = new LoggerConfiguration() - .MinimumLevel.Verbose() - .WriteTo.File(SerilogFileName) - .CreateLogger(); - - var serilogLogger = new SerilogLoggerFactory(loggerSerilog).CreateLogger("SerilogTest"); - SFLoggerFactory.SetCustomLogger(serilogLogger); - _logFile = SerilogFileName; + SFLoggerFactory.EnableSFLogger(); } - } - - [TestFixture] - public class NlogTest : SFBaseLoggerTest - { - [OneTimeSetUp] - public void SetUp() + else { - Environment.SetEnvironmentVariable("TEST_NLOG_FILE_NAME", NlogFileName); - var factory = LoggerFactory.Create( - builder => builder - .AddNLog("TestNLog.config") - .SetMinimumLevel(LogLevel.Trace)); - - var nlogLogger = factory.CreateLogger("NlogTest"); - SFLoggerFactory.SetCustomLogger(nlogLogger); - _logFile = NlogFileName; + SFLoggerFactory.DisableSFLogger(); } + + return SFLoggerFactory.GetSFLogger(); } } } diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFSimpleLoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFSimpleLoggerTest.cs deleted file mode 100644 index 7ed3f20d8..000000000 --- a/Snowflake.Data.Tests/UnitTests/Logger/SFSimpleLoggerTest.cs +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. - */ - -using NUnit.Framework; -using Snowflake.Data.Configuration; -using Snowflake.Data.Log; - -namespace Snowflake.Data.Tests.UnitTests -{ - [TestFixture, NonParallelizable] - class SFSimpleLoggerTest - { - SFLogger _logger; - - [OneTimeSetUp] - public static void BeforeTest() - { - // Log level defaults to Warn on net6.0 builds in github actions - // Set the root level to Debug - EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Debug, "STDOUT"); - } - - [OneTimeTearDown] - public static void AfterAll() - { - EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, "STDOUT"); - } - - [TearDown] - public void AfterTest() - { - // Return to default setting - SFLoggerFactory.EnableSimpleLogger(); - } - - [Test] - public void TestUsingSimpleLogger() - { - SFLoggerFactory.EnableSimpleLogger(); - _logger = SFLoggerFactory.GetSimpleLogger(); - Assert.IsInstanceOf(_logger); - } - - [Test] - public void TestSettingCustomLogger() - { - SFLoggerFactory.DisableSimpleLogger(); - _logger = SFLoggerFactory.GetSimpleLogger(); - Assert.IsInstanceOf(_logger); - } - - [Test] - public void TestIsDebugEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); - - Assert.AreEqual(isEnabled, _logger.IsDebugEnabled()); - } - - [Test] - public void TestIsInfoEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); - - Assert.AreEqual(isEnabled, _logger.IsInfoEnabled()); - } - - [Test] - public void TestIsWarnEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); - - Assert.AreEqual(isEnabled, _logger.IsWarnEnabled()); - } - - [Test] - public void TestIsErrorEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); - - Assert.AreEqual(isEnabled, _logger.IsErrorEnabled()); - } - - [Test] - public void TestIsFatalEnabled( - [Values(false, true)] bool isEnabled) - { - _logger = GetLogger(isEnabled); - - Assert.AreEqual(isEnabled, _logger.IsFatalEnabled()); - } - - private SFLogger GetLogger(bool isEnabled) - { - if (isEnabled) - { - SFLoggerFactory.EnableSimpleLogger(); - } - else - { - SFLoggerFactory.DisableSimpleLogger(); - } - - return SFLoggerFactory.GetSimpleLogger(); - } - } -} diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs b/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs index 2d9264400..d42c2573a 100644 --- a/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs +++ b/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs @@ -13,7 +13,7 @@ namespace Snowflake.Data.Configuration { internal class EasyLoggingConfigFinder { - private static readonly SFLogger s_logger = SFLoggerFactory.GetSimpleLogger(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetSFLogger(); internal const string ClientConfigFileName = "sf_client_config.json"; internal const string ClientConfigEnvironmentName = "SF_CLIENT_CONFIG_FILE"; diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs b/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs index 2285b754b..48b244b57 100644 --- a/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs +++ b/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs @@ -15,7 +15,7 @@ namespace Snowflake.Data.Configuration { internal class EasyLoggingConfigParser { - private static readonly SFLogger s_logger = SFLoggerFactory.GetSimpleLogger(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetSFLogger(); public static readonly EasyLoggingConfigParser Instance = new EasyLoggingConfigParser(); diff --git a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs index 22b9302e6..97487256e 100644 --- a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs +++ b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs @@ -15,7 +15,7 @@ namespace Snowflake.Data.Core { internal class EasyLoggingStarter { - private static readonly SFLogger s_logger = SFLoggerFactory.GetSimpleLogger(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetSFLogger(); private readonly EasyLoggingConfigProvider _easyLoggingConfigProvider; diff --git a/Snowflake.Data/Logger/EasyLoggerManager.cs b/Snowflake.Data/Logger/EasyLoggerManager.cs index 13347cdfc..914c0b2a0 100644 --- a/Snowflake.Data/Logger/EasyLoggerManager.cs +++ b/Snowflake.Data/Logger/EasyLoggerManager.cs @@ -5,9 +5,6 @@ using System; using System.IO; using System.Linq; -using log4net; -using log4net.Appender; -using log4net.Layout; using Snowflake.Data.Configuration; namespace Snowflake.Data.Log @@ -18,49 +15,44 @@ internal class EasyLoggerManager private readonly object _lockForExclusiveConfigure = new object(); - private const string AppenderPrefix = "SFEasyLogging"; + internal const string AppenderPrefix = "SFEasyLogging"; private readonly EasyLoggingLevelMapper _levelMapper = EasyLoggingLevelMapper.Instance; public virtual void ReconfigureEasyLogging(EasyLoggingLogLevel easyLoggingLogLevel, string logsPath) { - var log4netLevel = _levelMapper.ToLog4NetLevel(easyLoggingLogLevel); + var sfLoggerLevel = _levelMapper.ToLoggingEventLevel(easyLoggingLogLevel); lock (_lockForExclusiveConfigure) { - var repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); - var rootLogger = (log4net.Repository.Hierarchy.Logger)repository.GetLogger("Snowflake.Data"); - rootLogger.Level = log4netLevel; + var rootLogger = SFLogRepository.GetRootLogger(); + rootLogger.SetLevel(sfLoggerLevel); var appender = string.Equals(logsPath, "STDOUT", StringComparison.OrdinalIgnoreCase) ? AddConsoleAppender(rootLogger) : AddRollingFileAppender(rootLogger, logsPath); RemoveOtherEasyLoggingAppenders(rootLogger, appender); - repository.RaiseConfigurationChanged(EventArgs.Empty); } } internal void ResetEasyLogging(EasyLoggingLogLevel easyLoggingLogLevel) { - var log4netLevel = _levelMapper.ToLog4NetLevel(easyLoggingLogLevel); + var sfLoggerLevel = _levelMapper.ToLoggingEventLevel(easyLoggingLogLevel); lock (_lockForExclusiveConfigure) { - var repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); - var rootLogger = (log4net.Repository.Hierarchy.Logger)repository.GetLogger("Snowflake.Data"); - rootLogger.Level = log4netLevel; + var rootLogger = SFLogRepository.GetRootLogger(); + rootLogger.SetLevel(sfLoggerLevel); RemoveOtherEasyLoggingAppenders(rootLogger, null); - repository.RaiseConfigurationChanged(EventArgs.Empty); } } internal static bool HasEasyLoggingAppender() { - var repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); - var rootLogger = (log4net.Repository.Hierarchy.Logger)repository.GetLogger("Snowflake.Data"); - return rootLogger.Appenders.ToArray().Any(IsEasyLoggingAppender); + var rootLogger = SFLogRepository.GetRootLogger(); + return rootLogger.GetAppenders().ToArray().Any(IsEasyLoggingAppender); } - private static void RemoveOtherEasyLoggingAppenders(log4net.Repository.Hierarchy.Logger logger, IAppender appender) + private static void RemoveOtherEasyLoggingAppenders(SFLogger logger, SFAppender appender) { - var existingAppenders = logger.Appenders.ToArray(); + var existingAppenders = logger.GetAppenders().ToArray(); foreach (var existingAppender in existingAppenders) { if (IsEasyLoggingAppender(existingAppender) && existingAppender != appender) @@ -70,67 +62,60 @@ private static void RemoveOtherEasyLoggingAppenders(log4net.Repository.Hierarchy } } - private static IAppender AddRollingFileAppender(log4net.Repository.Hierarchy.Logger logger, + private static SFAppender AddRollingFileAppender(SFLogger logger, string directoryPath) { var patternLayout = PatternLayout(); var randomFileName = $"snowflake_dotnet_{Path.GetRandomFileName()}"; var logFileName = randomFileName.Substring(0, randomFileName.Length - 4) + ".log"; - var appender = new RollingFileAppender + var appender = new SFRollingFileAppender { - Layout = patternLayout, - AppendToFile = true, - File = Path.Combine(directoryPath, logFileName), - Name = $"{AppenderPrefix}RollingFileAppender", - StaticLogFileName = true, - RollingStyle = RollingFileAppender.RollingMode.Size, - MaximumFileSize = "1GB", - MaxSizeRollBackups = 2, - PreserveLogFileNameExtension = true, - LockingModel = new FileAppender.MinimalLock() + _patternLayout = patternLayout, + _logFilePath = Path.Combine(directoryPath, logFileName), + _name = $"{AppenderPrefix}RollingFileAppender", + _maximumFileSize = 1000000000, // "1GB" + _maxSizeRollBackups = 2, }; appender.ActivateOptions(); logger.AddAppender(appender); return appender; } - private static bool IsEasyLoggingAppender(IAppender appender) + private static bool IsEasyLoggingAppender(SFAppender appender) { - if (appender.GetType() == typeof(ConsoleAppender)) + if (appender.GetType() == typeof(SFConsoleAppender)) { - var consoleAppender = (ConsoleAppender)appender; - return consoleAppender.Name != null && consoleAppender.Name.StartsWith(AppenderPrefix); + var consoleAppender = (SFConsoleAppender)appender; + return consoleAppender._name != null && consoleAppender._name.StartsWith(AppenderPrefix); } - if (appender.GetType() == typeof(RollingFileAppender)) + if (appender.GetType() == typeof(SFRollingFileAppender)) { - var rollingFileAppender = (RollingFileAppender)appender; - return rollingFileAppender.Name != null && rollingFileAppender.Name.StartsWith(AppenderPrefix); + var rollingFileAppender = (SFRollingFileAppender)appender; + return rollingFileAppender._name != null && rollingFileAppender._name.StartsWith(AppenderPrefix); } return false; } - private static IAppender AddConsoleAppender(log4net.Repository.Hierarchy.Logger logger) + private static SFAppender AddConsoleAppender(SFLogger logger) { var patternLayout = PatternLayout(); - var appender = new ConsoleAppender() + var appender = new SFConsoleAppender() { - Layout = patternLayout, - Name = $"{AppenderPrefix}ConsoleAppender" + _patternLayout = patternLayout, + _name = $"{AppenderPrefix}ConsoleAppender" }; - appender.ActivateOptions(); logger.AddAppender(appender); return appender; } - private static PatternLayout PatternLayout() + internal static PatternLayout PatternLayout() { var patternLayout = new PatternLayout { - ConversionPattern = "[%date] [%t] [%-5level] [%logger] %message%newline" + _conversionPattern = "[%date] [%t] [%-5level] [%logger] %message%newline" }; - patternLayout.ActivateOptions(); return patternLayout; } } diff --git a/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs b/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs index c36f489bf..221109237 100644 --- a/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs +++ b/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs @@ -3,7 +3,6 @@ */ using System; -using log4net.Core; using Snowflake.Data.Configuration; namespace Snowflake.Data.Log @@ -12,16 +11,16 @@ internal class EasyLoggingLevelMapper { public static readonly EasyLoggingLevelMapper Instance = new EasyLoggingLevelMapper(); - public Level ToLog4NetLevel(EasyLoggingLogLevel level) + public LoggingEvent ToLoggingEventLevel(EasyLoggingLogLevel level) { switch (level) { - case EasyLoggingLogLevel.Off: return Level.Off; - case EasyLoggingLogLevel.Error: return Level.Error; - case EasyLoggingLogLevel.Warn: return Level.Warn; - case EasyLoggingLogLevel.Info: return Level.Info; - case EasyLoggingLogLevel.Debug: return Level.Debug; - case EasyLoggingLogLevel.Trace: return Level.Trace; + case EasyLoggingLogLevel.Off: return LoggingEvent.OFF; + case EasyLoggingLogLevel.Error: return LoggingEvent.ERROR; + case EasyLoggingLogLevel.Warn: return LoggingEvent.WARN; + case EasyLoggingLogLevel.Info: return LoggingEvent.INFO; + case EasyLoggingLogLevel.Debug: return LoggingEvent.DEBUG; + case EasyLoggingLogLevel.Trace: return LoggingEvent.TRACE; default: throw new Exception("Unknown log level"); } } diff --git a/Snowflake.Data/Logger/ILoggerEmptyImpl.cs b/Snowflake.Data/Logger/ILoggerEmptyImpl.cs new file mode 100644 index 000000000..4a0d83374 --- /dev/null +++ b/Snowflake.Data/Logger/ILoggerEmptyImpl.cs @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. + */ + +using Microsoft.Extensions.Logging; +using System; + +namespace Snowflake.Data.Log +{ + // Empty implementation of SFLogger + // Used when SFLoggerFactory.disableLogger() is called. + + class ILoggerEmptyImpl : ILogger + { + IDisposable ILogger.BeginScope(TState state) + { + throw new NotImplementedException(); + } + + bool ILogger.IsEnabled(LogLevel logLevel) + { + return false; + } + + void ILogger.Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + return; + } + } + +} diff --git a/Snowflake.Data/Logger/Log4netImpl.cs b/Snowflake.Data/Logger/Log4netImpl.cs deleted file mode 100644 index 33479a011..000000000 --- a/Snowflake.Data/Logger/Log4netImpl.cs +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. - */ - -using log4net; -using System; - -namespace Snowflake.Data.Log -{ - // Default implementation for SFLogger - - class Log4NetImpl : SFLogger - { - private readonly ILog logger; - - public Log4NetImpl(ILog logger) - { - this.logger = logger; - } - - public bool IsDebugEnabled() - { - return logger.IsDebugEnabled; - } - - public bool IsInfoEnabled() - { - return logger.IsInfoEnabled; - } - - public bool IsWarnEnabled() - { - return logger.IsWarnEnabled; - } - - public bool IsErrorEnabled() - { - return logger.IsErrorEnabled; - } - - public bool IsFatalEnabled() - { - return logger.IsFatalEnabled; - } - - public void Debug(string msg, Exception ex = null) - { - msg = SecretDetector.MaskSecrets(msg).maskedText; - logger.Debug(msg, ex); - } - - public void Info(string msg, Exception ex = null) - { - msg = SecretDetector.MaskSecrets(msg).maskedText; - logger.Info(msg, ex); - } - - public void Warn(string msg, Exception ex = null) - { - msg = SecretDetector.MaskSecrets(msg).maskedText; - logger.Warn(msg, ex); - } - - - public void Error(string msg, Exception ex = null) - { - msg = SecretDetector.MaskSecrets(msg).maskedText; - logger.Error(msg, ex); - } - - public void Fatal(string msg, Exception ex = null) - { - msg = SecretDetector.MaskSecrets(msg).maskedText; - logger.Fatal(msg, ex); - } - } - -} diff --git a/Snowflake.Data/Logger/SFLogger.cs b/Snowflake.Data/Logger/SFLogger.cs index 00badc38b..16b375c0f 100644 --- a/Snowflake.Data/Logger/SFLogger.cs +++ b/Snowflake.Data/Logger/SFLogger.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Text; namespace Snowflake.Data.Log { @@ -29,11 +28,23 @@ interface SFLogger void Error(string msg, Exception ex = null); void Fatal(string msg, Exception ex = null); + + List GetAppenders(); + + void AddAppender(SFAppender appender); + + void RemoveAppender(SFAppender appender); + + void SetLevel(LoggingEvent level); } - enum LoggingEvent + public enum LoggingEvent { - DEBUG, INFO, WARN, ERROR, FATAL + OFF, TRACE, DEBUG, INFO, WARN, ERROR, FATAL } + public interface SFAppender + { + void Append(string logLevel, string message, Type type, Exception ex = null); + } } diff --git a/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs b/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs index 0f6e49f5f..1e6eb2e68 100644 --- a/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs +++ b/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs @@ -1,31 +1,86 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ -using Microsoft.Extensions.Logging; using System; +using System.Collections.Generic; namespace Snowflake.Data.Log { // Empty implementation of SFLogger // Used when SFLoggerFactory.disableLogger() is called. - class SFLoggerEmptyImpl : ILogger + class SFLoggerEmptyImpl : SFLogger { - IDisposable ILogger.BeginScope(TState state) + public bool IsDebugEnabled() { - throw new NotImplementedException(); + return false; + } + + public bool IsInfoEnabled() + { + return false; } - bool ILogger.IsEnabled(LogLevel logLevel) + public bool IsWarnEnabled() { return false; } - void ILogger.Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + public bool IsErrorEnabled() + { + return false; + } + + public bool IsFatalEnabled() + { + return false; + } + + public void Debug(string msg, Exception ex) + { + return; + } + + public void Info(string msg, Exception ex) + { + return; + } + + public void Warn(string msg, Exception ex) + { + return; + } + + public void Error(string msg, Exception ex) + { + return; + } + + public void Fatal(string msg, Exception ex) { return; } + + List SFLogger.GetAppenders() + { + throw new NotImplementedException(); + } + + void SFLogger.AddAppender(SFAppender appender) + { + throw new NotImplementedException(); + } + + void SFLogger.RemoveAppender(SFAppender appender) + { + throw new NotImplementedException(); + } + + void SFLogger.SetLevel(LoggingEvent level) + { + throw new NotImplementedException(); + } } } diff --git a/Snowflake.Data/Logger/SFLoggerEmptySimpleImpl.cs b/Snowflake.Data/Logger/SFLoggerEmptySimpleImpl.cs deleted file mode 100644 index d24d4bc9a..000000000 --- a/Snowflake.Data/Logger/SFLoggerEmptySimpleImpl.cs +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. - */ - -using System; - -namespace Snowflake.Data.Log -{ - // Empty implementation of SFLogger - // Used when SFLoggerFactory.disableLogger() is called. - - class SFLoggerEmptySimpleImpl : SFLogger - { - public bool IsDebugEnabled() - { - return false; - } - - public bool IsInfoEnabled() - { - return false; - } - - public bool IsWarnEnabled() - { - return false; - } - - public bool IsErrorEnabled() - { - return false; - } - - public bool IsFatalEnabled() - { - return false; - } - - public void Debug(string msg, Exception ex) - { - return; - } - - public void Info(string msg, Exception ex) - { - return; - } - - public void Warn(string msg, Exception ex) - { - return; - } - - public void Error(string msg, Exception ex) - { - return; - } - - public void Fatal(string msg, Exception ex) - { - return; - } - } - -} diff --git a/Snowflake.Data/Logger/SFLoggerFactory.cs b/Snowflake.Data/Logger/SFLoggerFactory.cs index 8fe71b486..517d5b1fe 100755 --- a/Snowflake.Data/Logger/SFLoggerFactory.cs +++ b/Snowflake.Data/Logger/SFLoggerFactory.cs @@ -2,77 +2,80 @@ * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ -using log4net; using Microsoft.Extensions.Logging; +using System.IO; namespace Snowflake.Data.Log { public class SFLoggerFactory { - private static bool isLoggerEnabled = false; + private static bool s_isCustomLoggerEnabled = false; - private static bool isSimpleLoggerEnabled = true; + private static bool s_isSFLoggerEnabled = true; - private static SFLogger simpleLogger = null; + private static ILogger s_customLogger = null; - private static ILogger customLogger = null; - - private SFLoggerFactory() - { - } - - public static void DisableSimpleLogger() + public static void DisableSFLogger() { - isSimpleLoggerEnabled = false; + s_isSFLoggerEnabled = false; } - public static void EnableSimpleLogger() + public static void EnableSFLogger() { - isSimpleLoggerEnabled = true; + s_isSFLoggerEnabled = true; } - public static void DisableLogger() + public static void DisableCustomLogger() { - isLoggerEnabled = false; + s_isCustomLoggerEnabled = false; } - public static void EnableLogger() + public static void EnableCustomLogger() { - isLoggerEnabled = true; + s_isCustomLoggerEnabled = true; } public static void UseDefaultLogger() { - customLogger = null; + s_customLogger = null; } public static void SetCustomLogger(ILogger customLogger) { - SFLoggerFactory.customLogger = customLogger; + SFLoggerFactory.s_customLogger = customLogger; } - internal static SFLogger GetSimpleLogger() + internal static SFLogger GetSFLogger() { // If true, return the default/specified logger - if (isSimpleLoggerEnabled) + if (s_isSFLoggerEnabled) { - ILog loggerL = LogManager.GetLogger(typeof(T)); - return new Log4NetImpl(loggerL); + var logger = new SFLoggerImpl(typeof(T)); + var fileAppender = new SFRollingFileAppender() + { + _name = "RollingFileAppender", + _logFilePath = Path.Combine(Directory.GetCurrentDirectory(), "test_snowflake_log.log"), + _maximumFileSize = 1000000000, // "1GB" + _maxSizeRollBackups = 0, + _patternLayout = EasyLoggerManager.PatternLayout() + }; + logger.AddAppender(fileAppender); + return logger; } // Else, return the empty logger implementation which outputs nothing else { - return new SFLoggerEmptySimpleImpl(); + return new SFLoggerEmptyImpl(); } } internal static ILogger GetLogger() { // If true, return the default/specified logger - if (isLoggerEnabled) + if (s_isCustomLoggerEnabled) { // If no logger specified, use the default logger: Microsoft's console logger - if (customLogger == null) + if (s_customLogger == null) { ILoggerFactory factory = LoggerFactory.Create( builder => builder @@ -82,12 +85,12 @@ internal static ILogger GetLogger() return factory.CreateLogger(); } - return customLogger; + return s_customLogger; } // Else, return the empty logger implementation which outputs nothing else { - return new SFLoggerEmptyImpl(); + return new ILoggerEmptyImpl(); } } } diff --git a/Snowflake.Data/Logger/SFLoggerImpl.cs b/Snowflake.Data/Logger/SFLoggerImpl.cs new file mode 100644 index 000000000..03d3d6954 --- /dev/null +++ b/Snowflake.Data/Logger/SFLoggerImpl.cs @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. + */ + +using Snowflake.Data.Log; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; + +public static class SFLogRepository +{ + //internal static Dictionary _logRepository = new Dictionary(); + + internal static SFLogger s_rootLogger = s_rootLogger = new SFLoggerImpl(typeof(SFLogRepository)); + + internal static SFLogger GetRootLogger() + { + return s_rootLogger; + } +} + +internal class PatternLayout +{ + internal string _conversionPattern; + + public PatternLayout() { } + + public string Format(string logLevel, string message, Type type) + { + var formattedMessage = _conversionPattern + .Replace("%date", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")) + .Replace("%t", Thread.CurrentThread.ManagedThreadId.ToString()) + .Replace("%-5level", logLevel) + .Replace("%logger", type.ToString()) + .Replace("%message", message) + .Replace("%newline", "\n"); + + return formattedMessage; + } +} + +internal class SFConsoleAppender : SFAppender +{ + internal string _name; + internal PatternLayout _patternLayout; + + public SFConsoleAppender() { } + + public void Append(string logLevel, string message, Type type, Exception ex = null) + { + var formattedMessage = _patternLayout.Format(logLevel, message, type); + Console.Write(formattedMessage); + if (ex != null) + { + Console.WriteLine(ex.Message); + } + } +} + +internal class SFRollingFileAppender : SFAppender +{ + internal string _name; + internal string _logFilePath; + internal long _maximumFileSize; + internal int _maxSizeRollBackups; + internal PatternLayout _patternLayout; + + public SFRollingFileAppender() { } + + public void Append(string logLevel, string message, Type type, Exception ex = null) + { + try + { + if (FileIsTooLarge()) + { + RollFile(); + } + + var formattedMessage = _patternLayout.Format(logLevel, message, type); + using (var writer = new StreamWriter(_logFilePath, true)) + { + writer.Write(formattedMessage); + if (ex != null) + { + writer.WriteLine(ex.Message); + } + } + } + catch (Exception logEx) + { + Console.WriteLine($"Failed to log message: {logEx.Message}"); + } + } + + public void ActivateOptions() + { + var logDir = Path.GetDirectoryName(_logFilePath); + if (!Directory.Exists(logDir)) + { + Directory.CreateDirectory(logDir); + } + if (!File.Exists(_logFilePath)) + { + var file = File.Create(_logFilePath); + file.Close(); + } + } + + private bool FileIsTooLarge() + { + FileInfo fileInfo = new FileInfo(_logFilePath); + return fileInfo.Exists && fileInfo.Length > _maximumFileSize; + } + + private void RollFile() + { + string rollFilePath = $"{_logFilePath}.{DateTime.Now:yyyyMMddHHmmss}.bak"; + File.Move(_logFilePath, rollFilePath); + + var logDirectory = Path.GetDirectoryName(_logFilePath); + var logFileName = Path.GetFileName(_logFilePath); + var rollFiles = Directory.GetFiles(logDirectory, $"{logFileName}.*.bak") + .OrderByDescending(f => f) + .Skip(_maxSizeRollBackups); + foreach (var oldRollFile in rollFiles) + { + File.Delete(oldRollFile); + } + } +} + +public class SFLoggerImpl : SFLogger +{ + private readonly Type _type; + internal readonly List _appenders; + internal LoggingEvent _level; + + private bool _isDebugEnabled; + private bool _isInfoEnabled; + private bool _isWarnEnabled; + private bool _isErrorEnabled; + private bool _isFatalEnabled; + + internal SFLoggerImpl(Type type, LoggingEvent level = LoggingEvent.DEBUG) + { + _appenders = new List(); + _type = type; + SetLevel(level); + } + + public void SetLevel(LoggingEvent level) + { + _level = level; + SetEnableValues(); + } + + private void SetEnableValues() + { + var enabled = _level != LoggingEvent.OFF; + _isDebugEnabled = enabled; + _isInfoEnabled = enabled; + _isWarnEnabled = enabled; + _isErrorEnabled = enabled; + _isFatalEnabled = enabled; + + if (enabled) + { + switch (_level) + { + case LoggingEvent.TRACE: + case LoggingEvent.DEBUG: + break; + case LoggingEvent.FATAL: + _isErrorEnabled = false; + goto case LoggingEvent.ERROR; + case LoggingEvent.ERROR: + _isWarnEnabled = false; + goto case LoggingEvent.WARN; + case LoggingEvent.WARN: + _isInfoEnabled = false; + goto case LoggingEvent.INFO; + case LoggingEvent.INFO: + _isDebugEnabled = false; + break; + default: + break; + } + } + } + + public List GetAppenders() + { + return _appenders; + } + + public void AddAppender(SFAppender appender) + { + _appenders.Add(appender); + } + + public void RemoveAppender(SFAppender appender) + { + _appenders.Remove(appender); + } + + public bool IsDebugEnabled() + { + return SFLogRepository.s_rootLogger == this ? + _isDebugEnabled : + SFLogRepository.s_rootLogger.IsDebugEnabled(); + } + + public bool IsInfoEnabled() + { + return SFLogRepository.s_rootLogger == this ? + _isInfoEnabled : + SFLogRepository.s_rootLogger.IsInfoEnabled(); + } + + public bool IsWarnEnabled() + { + return SFLogRepository.s_rootLogger == this ? + _isWarnEnabled : + SFLogRepository.s_rootLogger.IsWarnEnabled(); + } + + public bool IsErrorEnabled() + { + return SFLogRepository.s_rootLogger == this ? + _isErrorEnabled : + SFLogRepository.s_rootLogger.IsErrorEnabled(); + } + + public bool IsFatalEnabled() + { + return SFLogRepository.s_rootLogger == this ? + _isFatalEnabled : + SFLogRepository.s_rootLogger.IsFatalEnabled(); + } + + public void Debug(string msg, Exception ex = null) + { + if (IsDebugEnabled()) + { + msg = SecretDetector.MaskSecrets(msg).maskedText; + Log(LoggingEvent.DEBUG.ToString(), msg, ex); + } + } + + public void Info(string msg, Exception ex = null) + { + if (IsInfoEnabled()) + { + msg = SecretDetector.MaskSecrets(msg).maskedText; + Log(LoggingEvent.INFO.ToString(), msg, ex); + } + } + + public void Warn(string msg, Exception ex = null) + { + if (IsWarnEnabled()) + { + msg = SecretDetector.MaskSecrets(msg).maskedText; + Log(LoggingEvent.WARN.ToString(), msg, ex); + } + } + + + public void Error(string msg, Exception ex = null) + { + if (IsErrorEnabled()) + { + msg = SecretDetector.MaskSecrets(msg).maskedText; + Log(LoggingEvent.ERROR.ToString(), msg, ex); + } + } + + public void Fatal(string msg, Exception ex = null) + { + if (IsFatalEnabled()) + { + msg = SecretDetector.MaskSecrets(msg).maskedText; + Log(LoggingEvent.FATAL.ToString(), msg, ex); + } + } + + private void Log(string logLevel, string logMessage, Exception ex = null) + { + var rootAppenders = SFLogRepository.s_rootLogger.GetAppenders(); + var appenders = rootAppenders.Count > 0 ? rootAppenders : _appenders; + foreach (var appender in appenders) + { + appender.Append(logLevel, logMessage, _type, ex); + } + } +} diff --git a/Snowflake.Data/Snowflake.Data.csproj b/Snowflake.Data/Snowflake.Data.csproj index b99e078fb..dcc361f34 100644 --- a/Snowflake.Data/Snowflake.Data.csproj +++ b/Snowflake.Data/Snowflake.Data.csproj @@ -22,7 +22,6 @@ - From 26ef937a500974fdb857d8329f531000b9f8fa48 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 29 Nov 2024 10:52:37 -0800 Subject: [PATCH 10/35] Fix log --- Snowflake.Data/Core/Tools/Diagnostics.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Snowflake.Data/Core/Tools/Diagnostics.cs b/Snowflake.Data/Core/Tools/Diagnostics.cs index 694607fba..90ad4c80d 100644 --- a/Snowflake.Data/Core/Tools/Diagnostics.cs +++ b/Snowflake.Data/Core/Tools/Diagnostics.cs @@ -40,7 +40,7 @@ private static string GetDiagnosticInfo() catch (Exception exception) { var errorMessage = $"Error caught while collecting diagnostic info: {exception.Message}"; - s_logger.Error(errorMessage, exception); + s_logger.LogError(errorMessage, exception); info.AppendLine(errorMessage); } return info.ToString(); From 1c7afd39af0d0a2ad6f83688087a576b7e51789c Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 29 Nov 2024 17:11:56 -0800 Subject: [PATCH 11/35] Add tests for new log functions --- .../UnitTests/Logger/EasyLoggerManagerTest.cs | 78 +++++++++++++++++- .../UnitTests/Logger/ILoggerTest.cs | 8 +- .../UnitTests/Logger/SFLoggerTest.cs | 80 ++++++++++++++++++- .../Configuration/EasyLoggingLogLevel.cs | 3 +- .../Logger/EasyLoggingLevelMapper.cs | 1 + Snowflake.Data/Logger/SFLoggerFactory.cs | 30 ++++--- Snowflake.Data/Logger/SFLoggerImpl.cs | 4 - 7 files changed, 181 insertions(+), 23 deletions(-) diff --git a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs index f9abac8e6..69716492f 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs @@ -50,6 +50,38 @@ public void TestThatChangesLogLevel() { // arrange var logger = SFLoggerFactory.GetSFLogger(); + + // act + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Off, t_directoryLogPath); + + // assert + Assert.IsFalse(logger.IsDebugEnabled()); + Assert.IsFalse(logger.IsInfoEnabled()); + Assert.IsFalse(logger.IsWarnEnabled()); + Assert.IsFalse(logger.IsErrorEnabled()); + Assert.IsFalse(logger.IsFatalEnabled()); + + // act + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Fatal, t_directoryLogPath); + + // assert + Assert.IsFalse(logger.IsDebugEnabled()); + Assert.IsFalse(logger.IsInfoEnabled()); + Assert.IsFalse(logger.IsWarnEnabled()); + Assert.IsFalse(logger.IsErrorEnabled()); + Assert.IsTrue(logger.IsFatalEnabled()); + + // act + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Error, t_directoryLogPath); + + // assert + Assert.IsFalse(logger.IsDebugEnabled()); + Assert.IsFalse(logger.IsInfoEnabled()); + Assert.IsFalse(logger.IsWarnEnabled()); + Assert.IsTrue(logger.IsErrorEnabled()); + Assert.IsTrue(logger.IsFatalEnabled()); + + // act EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, t_directoryLogPath); // assert @@ -91,6 +123,48 @@ public void TestThatLogsToProperFileWithProperLogLevelOnly() Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(WarnMessage))); Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(ErrorMessage))); Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(FatalMessage))); + + // arrange + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Debug, t_directoryLogPath); + + // act + logger.Debug(DebugMessage); + + // assert + logLines = File.ReadLines(FindLogFilePath(t_directoryLogPath, 2)); + Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(DebugMessage))); + } + + [Test] + public void TestThatRollsLogIfSizeIsTooBig() + { + // arrange + var logger = SFLoggerFactory.GetSFLogger(); + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Trace, t_directoryLogPath); + + var appenders = SFLogRepository.s_rootLogger.GetAppenders(); + appenders.Remove(appenders[0]); + var randomFileName = $"snowflake_dotnet_{Path.GetRandomFileName()}"; + var logFileName = randomFileName.Substring(0, randomFileName.Length - 4) + ".log"; + appenders.Add(new SFRollingFileAppender() + { + _name = "RollingFileAppender", + _logFilePath = Path.Combine(t_directoryLogPath, logFileName), + _maximumFileSize = 1, + _maxSizeRollBackups = 2, + _patternLayout = EasyLoggerManager.PatternLayout() + }); + + // act + for (int i = 0; i < 5; i++) + { + logger.Debug(DebugMessage); + System.Threading.Thread.Sleep(1000); + } + var backupLogs = Directory.GetFiles(t_directoryLogPath, $"{logFileName}.*.bak"); + + // assert + Assert.AreEqual(2, backupLogs.Length); } [Test] @@ -131,11 +205,11 @@ private static string RandomLogsDirectoryPath() return Path.Combine(s_logsDirectory, $"easy_logging_logs_{randomName}", "dotnet"); } - private static string FindLogFilePath(string directoryLogPath) + private static string FindLogFilePath(string directoryLogPath, int expectedFileCount = 1) { Assert.IsTrue(Directory.Exists(directoryLogPath)); var files = Directory.GetFiles(directoryLogPath); - Assert.AreEqual(1, files.Length); + Assert.AreEqual(expectedFileCount, files.Length); return files.First(); } diff --git a/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs index c371ac63b..789f80f92 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs @@ -27,7 +27,7 @@ class ILoggerTest private const string SerilogFileName = "test_serilog.log"; private const string NlogFileName = "test_nlog.log"; - public abstract class SFBaseLoggerTest + public abstract class ILoggerBaseTest { protected ILogger _logger; protected string _logFile; @@ -154,7 +154,7 @@ public void TestThatLogsToProperFileWithProperLogLevelOnly() } [TestFixture] - public class Log4NetTest : SFBaseLoggerTest + public class Log4NetTest : ILoggerBaseTest { [OneTimeSetUp] public void SetUp() @@ -172,7 +172,7 @@ public void SetUp() } [TestFixture] - public class SerilogTest : SFBaseLoggerTest + public class SerilogTest : ILoggerBaseTest { [OneTimeSetUp] public void SetUp() @@ -190,7 +190,7 @@ public void SetUp() } [TestFixture] - public class NlogTest : SFBaseLoggerTest + public class NlogTest : ILoggerBaseTest { [OneTimeSetUp] public void SetUp() diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs index f7b7cdde2..0c0fc5a71 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using Snowflake.Data.Configuration; using Snowflake.Data.Log; +using System; namespace Snowflake.Data.Tests.UnitTests { @@ -35,7 +36,7 @@ public void AfterTest() } [Test] - public void TestUsingSimpleLogger() + public void TestUsingSFLogger() { SFLoggerFactory.EnableSFLogger(); _logger = SFLoggerFactory.GetSFLogger(); @@ -43,7 +44,7 @@ public void TestUsingSimpleLogger() } [Test] - public void TestSettingCustomLogger() + public void TestUsingEmptyLogger() { SFLoggerFactory.DisableSFLogger(); _logger = SFLoggerFactory.GetSFLogger(); @@ -57,6 +58,7 @@ public void TestIsDebugEnabled( _logger = GetLogger(isEnabled); Assert.AreEqual(isEnabled, _logger.IsDebugEnabled()); + _logger.Debug("debug log message", new Exception("test exception")); } [Test] @@ -66,6 +68,7 @@ public void TestIsInfoEnabled( _logger = GetLogger(isEnabled); Assert.AreEqual(isEnabled, _logger.IsInfoEnabled()); + _logger.Info("info log message", new Exception("test exception")); } [Test] @@ -75,6 +78,7 @@ public void TestIsWarnEnabled( _logger = GetLogger(isEnabled); Assert.AreEqual(isEnabled, _logger.IsWarnEnabled()); + _logger.Warn("warn log message", new Exception("test exception")); } [Test] @@ -84,6 +88,7 @@ public void TestIsErrorEnabled( _logger = GetLogger(isEnabled); Assert.AreEqual(isEnabled, _logger.IsErrorEnabled()); + _logger.Error("error log message", new Exception("test exception")); } [Test] @@ -93,6 +98,75 @@ public void TestIsFatalEnabled( _logger = GetLogger(isEnabled); Assert.AreEqual(isEnabled, _logger.IsFatalEnabled()); + _logger.Fatal("fatal log message", new Exception("test exception")); + } + + [Test] + public void TestGetAppenders( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + if (isEnabled) + { + var appenders = _logger.GetAppenders(); + Assert.IsInstanceOf(appenders[0]); + } + else + { + Assert.Throws(() => _logger.GetAppenders()); + } + } + + [Test] + public void TestAddAppender( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + if (isEnabled) + { + var appenders = _logger.GetAppenders(); + Assert.AreEqual(1, appenders.Count); + _logger.AddAppender(new SFConsoleAppender()); + Assert.AreEqual(2, appenders.Count); + } + else + { + Assert.Throws(() => _logger.AddAppender(new SFConsoleAppender())); + } + } + + [Test] + public void TestRemoveAppender( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + if (isEnabled) + { + var appenders = _logger.GetAppenders(); + Assert.AreEqual(1, appenders.Count); + _logger.RemoveAppender(appenders[0]); + Assert.AreEqual(0, appenders.Count); + } + else + { + Assert.Throws(() => _logger.RemoveAppender(new SFConsoleAppender())); + } + } + + [Test] + public void TestSetLevel( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + if (isEnabled) + { + _logger.SetLevel(LoggingEvent.DEBUG); + Assert.AreEqual(LoggingEvent.DEBUG, ((SFLoggerImpl)_logger)._level); + } + else + { + Assert.Throws(() => _logger.SetLevel(LoggingEvent.DEBUG)); + } } private SFLogger GetLogger(bool isEnabled) @@ -106,7 +180,7 @@ private SFLogger GetLogger(bool isEnabled) SFLoggerFactory.DisableSFLogger(); } - return SFLoggerFactory.GetSFLogger(); + return SFLoggerFactory.GetSFLogger(false); } } } diff --git a/Snowflake.Data/Configuration/EasyLoggingLogLevel.cs b/Snowflake.Data/Configuration/EasyLoggingLogLevel.cs index 450a9bcf1..0b6ebe31c 100644 --- a/Snowflake.Data/Configuration/EasyLoggingLogLevel.cs +++ b/Snowflake.Data/Configuration/EasyLoggingLogLevel.cs @@ -6,9 +6,10 @@ namespace Snowflake.Data.Configuration { - internal enum EasyLoggingLogLevel + public enum EasyLoggingLogLevel { Off, + Fatal, Error, Warn, Info, diff --git a/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs b/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs index 221109237..6364321f2 100644 --- a/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs +++ b/Snowflake.Data/Logger/EasyLoggingLevelMapper.cs @@ -16,6 +16,7 @@ public LoggingEvent ToLoggingEventLevel(EasyLoggingLogLevel level) switch (level) { case EasyLoggingLogLevel.Off: return LoggingEvent.OFF; + case EasyLoggingLogLevel.Fatal: return LoggingEvent.FATAL; case EasyLoggingLogLevel.Error: return LoggingEvent.ERROR; case EasyLoggingLogLevel.Warn: return LoggingEvent.WARN; case EasyLoggingLogLevel.Info: return LoggingEvent.INFO; diff --git a/Snowflake.Data/Logger/SFLoggerFactory.cs b/Snowflake.Data/Logger/SFLoggerFactory.cs index 517d5b1fe..bc695bc3a 100755 --- a/Snowflake.Data/Logger/SFLoggerFactory.cs +++ b/Snowflake.Data/Logger/SFLoggerFactory.cs @@ -45,21 +45,33 @@ public static void SetCustomLogger(ILogger customLogger) SFLoggerFactory.s_customLogger = customLogger; } - internal static SFLogger GetSFLogger() + internal static SFLogger GetSFLogger(bool useFileAppender = true) { // If true, return the default/specified logger if (s_isSFLoggerEnabled) { var logger = new SFLoggerImpl(typeof(T)); - var fileAppender = new SFRollingFileAppender() + if (useFileAppender) { - _name = "RollingFileAppender", - _logFilePath = Path.Combine(Directory.GetCurrentDirectory(), "test_snowflake_log.log"), - _maximumFileSize = 1000000000, // "1GB" - _maxSizeRollBackups = 0, - _patternLayout = EasyLoggerManager.PatternLayout() - }; - logger.AddAppender(fileAppender); + var fileAppender = new SFRollingFileAppender() + { + _name = "RollingFileAppender", + _logFilePath = Path.Combine(Directory.GetCurrentDirectory(), "test_snowflake_log.log"), + _maximumFileSize = 1000000000, // "1GB" + _maxSizeRollBackups = 0, + _patternLayout = EasyLoggerManager.PatternLayout() + }; + logger.AddAppender(fileAppender); + } + else + { + var consoleAppender = new SFConsoleAppender() + { + _name = "ConsoleAppender", + _patternLayout = EasyLoggerManager.PatternLayout() + }; + logger.AddAppender(consoleAppender); + } return logger; } // Else, return the empty logger implementation which outputs nothing diff --git a/Snowflake.Data/Logger/SFLoggerImpl.cs b/Snowflake.Data/Logger/SFLoggerImpl.cs index 03d3d6954..39f924aa3 100644 --- a/Snowflake.Data/Logger/SFLoggerImpl.cs +++ b/Snowflake.Data/Logger/SFLoggerImpl.cs @@ -11,8 +11,6 @@ public static class SFLogRepository { - //internal static Dictionary _logRepository = new Dictionary(); - internal static SFLogger s_rootLogger = s_rootLogger = new SFLoggerImpl(typeof(SFLogRepository)); internal static SFLogger GetRootLogger() @@ -184,8 +182,6 @@ private void SetEnableValues() case LoggingEvent.INFO: _isDebugEnabled = false; break; - default: - break; } } } From 1d4e73237f51df06f114bdc889b2d8c33041eecd Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 29 Nov 2024 17:49:40 -0800 Subject: [PATCH 12/35] Retrigger checks From c1b8d5a0ade695fa8645b9a0755e93fdf6bb9b4a Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Mon, 2 Dec 2024 09:42:58 -0800 Subject: [PATCH 13/35] Retrigger checks From 2fe82b138451590ce97a03760e44b1e8753955ff Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Tue, 3 Dec 2024 12:05:38 -0800 Subject: [PATCH 14/35] Refactor classes and tests --- .../UnitTests/Logger/EasyLoggerManagerTest.cs | 12 +- Snowflake.Data/Logger/SFAppender.cs | 13 ++ Snowflake.Data/Logger/SFAppenderImpl.cs | 119 ++++++++++++++++++ Snowflake.Data/Logger/SFLogger.cs | 5 - Snowflake.Data/Logger/SFLoggerImpl.cs | 113 ----------------- 5 files changed, 139 insertions(+), 123 deletions(-) create mode 100644 Snowflake.Data/Logger/SFAppender.cs create mode 100644 Snowflake.Data/Logger/SFAppenderImpl.cs diff --git a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs index 69716492f..76913b629 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs @@ -125,13 +125,14 @@ public void TestThatLogsToProperFileWithProperLogLevelOnly() Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(FatalMessage))); // arrange + File.Delete(FindLogFilePath(t_directoryLogPath)); EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Debug, t_directoryLogPath); // act logger.Debug(DebugMessage); // assert - logLines = File.ReadLines(FindLogFilePath(t_directoryLogPath, 2)); + logLines = File.ReadLines(FindLogFilePath(t_directoryLogPath)); Assert.That(logLines, Has.Exactly(1).Matches(s => s.Contains(DebugMessage))); } @@ -139,6 +140,7 @@ public void TestThatLogsToProperFileWithProperLogLevelOnly() public void TestThatRollsLogIfSizeIsTooBig() { // arrange + const int expecetedBackupLogCount = 2; var logger = SFLoggerFactory.GetSFLogger(); EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Trace, t_directoryLogPath); @@ -151,7 +153,7 @@ public void TestThatRollsLogIfSizeIsTooBig() _name = "RollingFileAppender", _logFilePath = Path.Combine(t_directoryLogPath, logFileName), _maximumFileSize = 1, - _maxSizeRollBackups = 2, + _maxSizeRollBackups = expecetedBackupLogCount, _patternLayout = EasyLoggerManager.PatternLayout() }); @@ -164,7 +166,7 @@ public void TestThatRollsLogIfSizeIsTooBig() var backupLogs = Directory.GetFiles(t_directoryLogPath, $"{logFileName}.*.bak"); // assert - Assert.AreEqual(2, backupLogs.Length); + Assert.AreEqual(expecetedBackupLogCount, backupLogs.Length); } [Test] @@ -205,11 +207,11 @@ private static string RandomLogsDirectoryPath() return Path.Combine(s_logsDirectory, $"easy_logging_logs_{randomName}", "dotnet"); } - private static string FindLogFilePath(string directoryLogPath, int expectedFileCount = 1) + private static string FindLogFilePath(string directoryLogPath) { Assert.IsTrue(Directory.Exists(directoryLogPath)); var files = Directory.GetFiles(directoryLogPath); - Assert.AreEqual(expectedFileCount, files.Length); + Assert.AreEqual(1, files.Length); return files.First(); } diff --git a/Snowflake.Data/Logger/SFAppender.cs b/Snowflake.Data/Logger/SFAppender.cs new file mode 100644 index 000000000..becfebc7f --- /dev/null +++ b/Snowflake.Data/Logger/SFAppender.cs @@ -0,0 +1,13 @@ +/* + //* Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. + */ + +using System; + +namespace Snowflake.Data.Log +{ + public interface SFAppender + { + void Append(string logLevel, string message, Type type, Exception ex = null); + } +} diff --git a/Snowflake.Data/Logger/SFAppenderImpl.cs b/Snowflake.Data/Logger/SFAppenderImpl.cs new file mode 100644 index 000000000..ad864fc61 --- /dev/null +++ b/Snowflake.Data/Logger/SFAppenderImpl.cs @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. + */ + +using Snowflake.Data.Log; +using System; +using System.IO; +using System.Linq; +using System.Threading; + +internal class PatternLayout +{ + internal string _conversionPattern; + + public PatternLayout() { } + + public string Format(string logLevel, string message, Type type) + { + var formattedMessage = _conversionPattern + .Replace("%date", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")) + .Replace("%t", Thread.CurrentThread.ManagedThreadId.ToString()) + .Replace("%-5level", logLevel) + .Replace("%logger", type.ToString()) + .Replace("%message", message) + .Replace("%newline", "\n"); + + return formattedMessage; + } +} + +internal class SFConsoleAppender : SFAppender +{ + internal string _name; + internal PatternLayout _patternLayout; + + public SFConsoleAppender() { } + + public void Append(string logLevel, string message, Type type, Exception ex = null) + { + var formattedMessage = _patternLayout.Format(logLevel, message, type); + Console.Write(formattedMessage); + if (ex != null) + { + Console.WriteLine(ex.Message); + } + } +} + +internal class SFRollingFileAppender : SFAppender +{ + internal string _name; + internal string _logFilePath; + internal long _maximumFileSize; + internal int _maxSizeRollBackups; + internal PatternLayout _patternLayout; + + public SFRollingFileAppender() { } + + public void Append(string logLevel, string message, Type type, Exception ex = null) + { + try + { + if (FileIsTooLarge()) + { + RollFile(); + } + + var formattedMessage = _patternLayout.Format(logLevel, message, type); + using (var writer = new StreamWriter(_logFilePath, true)) + { + writer.Write(formattedMessage); + if (ex != null) + { + writer.WriteLine(ex.Message); + } + } + } + catch (Exception logEx) + { + Console.WriteLine($"Failed to log message: {logEx.Message}"); + } + } + + public void ActivateOptions() + { + var logDir = Path.GetDirectoryName(_logFilePath); + if (!Directory.Exists(logDir)) + { + Directory.CreateDirectory(logDir); + } + if (!File.Exists(_logFilePath)) + { + var file = File.Create(_logFilePath); + file.Close(); + } + } + + private bool FileIsTooLarge() + { + FileInfo fileInfo = new FileInfo(_logFilePath); + return fileInfo.Exists && fileInfo.Length > _maximumFileSize; + } + + private void RollFile() + { + string rollFilePath = $"{_logFilePath}.{DateTime.Now:yyyyMMddHHmmss}.bak"; + File.Move(_logFilePath, rollFilePath); + + var logDirectory = Path.GetDirectoryName(_logFilePath); + var logFileName = Path.GetFileName(_logFilePath); + var rollFiles = Directory.GetFiles(logDirectory, $"{logFileName}.*.bak") + .OrderByDescending(f => f) + .Skip(_maxSizeRollBackups); + foreach (var oldRollFile in rollFiles) + { + File.Delete(oldRollFile); + } + } +} diff --git a/Snowflake.Data/Logger/SFLogger.cs b/Snowflake.Data/Logger/SFLogger.cs index 16b375c0f..0aa35e925 100644 --- a/Snowflake.Data/Logger/SFLogger.cs +++ b/Snowflake.Data/Logger/SFLogger.cs @@ -42,9 +42,4 @@ public enum LoggingEvent { OFF, TRACE, DEBUG, INFO, WARN, ERROR, FATAL } - - public interface SFAppender - { - void Append(string logLevel, string message, Type type, Exception ex = null); - } } diff --git a/Snowflake.Data/Logger/SFLoggerImpl.cs b/Snowflake.Data/Logger/SFLoggerImpl.cs index 39f924aa3..c33e491d4 100644 --- a/Snowflake.Data/Logger/SFLoggerImpl.cs +++ b/Snowflake.Data/Logger/SFLoggerImpl.cs @@ -5,9 +5,6 @@ using Snowflake.Data.Log; using System; using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; public static class SFLogRepository { @@ -19,116 +16,6 @@ internal static SFLogger GetRootLogger() } } -internal class PatternLayout -{ - internal string _conversionPattern; - - public PatternLayout() { } - - public string Format(string logLevel, string message, Type type) - { - var formattedMessage = _conversionPattern - .Replace("%date", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")) - .Replace("%t", Thread.CurrentThread.ManagedThreadId.ToString()) - .Replace("%-5level", logLevel) - .Replace("%logger", type.ToString()) - .Replace("%message", message) - .Replace("%newline", "\n"); - - return formattedMessage; - } -} - -internal class SFConsoleAppender : SFAppender -{ - internal string _name; - internal PatternLayout _patternLayout; - - public SFConsoleAppender() { } - - public void Append(string logLevel, string message, Type type, Exception ex = null) - { - var formattedMessage = _patternLayout.Format(logLevel, message, type); - Console.Write(formattedMessage); - if (ex != null) - { - Console.WriteLine(ex.Message); - } - } -} - -internal class SFRollingFileAppender : SFAppender -{ - internal string _name; - internal string _logFilePath; - internal long _maximumFileSize; - internal int _maxSizeRollBackups; - internal PatternLayout _patternLayout; - - public SFRollingFileAppender() { } - - public void Append(string logLevel, string message, Type type, Exception ex = null) - { - try - { - if (FileIsTooLarge()) - { - RollFile(); - } - - var formattedMessage = _patternLayout.Format(logLevel, message, type); - using (var writer = new StreamWriter(_logFilePath, true)) - { - writer.Write(formattedMessage); - if (ex != null) - { - writer.WriteLine(ex.Message); - } - } - } - catch (Exception logEx) - { - Console.WriteLine($"Failed to log message: {logEx.Message}"); - } - } - - public void ActivateOptions() - { - var logDir = Path.GetDirectoryName(_logFilePath); - if (!Directory.Exists(logDir)) - { - Directory.CreateDirectory(logDir); - } - if (!File.Exists(_logFilePath)) - { - var file = File.Create(_logFilePath); - file.Close(); - } - } - - private bool FileIsTooLarge() - { - FileInfo fileInfo = new FileInfo(_logFilePath); - return fileInfo.Exists && fileInfo.Length > _maximumFileSize; - } - - private void RollFile() - { - string rollFilePath = $"{_logFilePath}.{DateTime.Now:yyyyMMddHHmmss}.bak"; - File.Move(_logFilePath, rollFilePath); - - var logDirectory = Path.GetDirectoryName(_logFilePath); - var logFileName = Path.GetFileName(_logFilePath); - var rollFiles = Directory.GetFiles(logDirectory, $"{logFileName}.*.bak") - .OrderByDescending(f => f) - .Skip(_maxSizeRollBackups); - foreach (var oldRollFile in rollFiles) - { - File.Delete(oldRollFile); - } - } -} - public class SFLoggerImpl : SFLogger { private readonly Type _type; From 7bb3f98740a7fe93b5568b335c5927d207679472 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Tue, 3 Dec 2024 17:05:02 -0800 Subject: [PATCH 15/35] Rename log functions and add test for BeginScope --- .../ConnectionMultiplePoolsAsyncIT.cs | 2 +- .../ConnectionPoolCommonIT.cs | 2 +- .../IntegrationTests/SFBindTestIT.cs | 2 +- .../IntegrationTests/SFConnectionIT.cs | 4 +- .../SFConnectionWithTomlIT.cs | 2 +- .../Mock/MockSnowflakeDbConnection.cs | 2 +- Snowflake.Data.Tests/SFBaseTest.cs | 2 +- .../UnitTests/Logger/EasyLoggerManagerTest.cs | 2 +- .../UnitTests/Logger/ILoggerTest.cs | 24 ++++++--- .../Util/ConnectingThreads.cs | 2 +- .../Util/DbConnectionExtensions.cs | 2 +- Snowflake.Data/Client/SnowflakeDbCommand.cs | 49 +++++++++++++------ .../Client/SnowflakeDbConnection.cs | 2 +- .../Client/SnowflakeDbConnectionPool.cs | 2 +- .../Client/SnowflakeDbDataReader.cs | 2 +- .../Client/SnowflakeDbTransaction.cs | 2 +- Snowflake.Data/Core/ArrowResultSet.cs | 2 +- .../Core/Authenticator/BasicAuthenticator.cs | 2 +- .../ExternalBrowserAuthenticator.cs | 2 +- .../Core/Authenticator/IAuthenticator.cs | 4 +- .../Authenticator/KeyPairAuthenticator.cs | 2 +- .../Core/Authenticator/OAuthAuthenticator.cs | 2 +- .../Core/Authenticator/OktaAuthenticator.cs | 2 +- Snowflake.Data/Core/ChunkDownloaderFactory.cs | 2 +- Snowflake.Data/Core/ChunkParserFactory.cs | 2 +- .../StructuredTypesReadingHandler.cs | 2 +- Snowflake.Data/Core/FastParser.cs | 2 +- .../Core/FileTransfer/EncryptionProvider.cs | 2 +- .../FileTransfer/GcmEncryptionProvider.cs | 2 +- .../Core/FileTransfer/SFFileTransferAgent.cs | 2 +- .../FileTransfer/StorageClient/SFGCSClient.cs | 2 +- .../FileTransfer/StorageClient/SFS3Client.cs | 2 +- .../StorageClient/SFSnowflakeAzureClient.cs | 2 +- Snowflake.Data/Core/HttpUtil.cs | 4 +- Snowflake.Data/Core/QueryContextCache.cs | 2 +- Snowflake.Data/Core/QueryResultsAwaiter.cs | 2 +- Snowflake.Data/Core/RestRequester.cs | 2 +- Snowflake.Data/Core/SFBindUploader.cs | 2 +- .../Core/SFBlockingChunkDownloaderV3.cs | 2 +- .../Core/SFMultiStatementsResultSet.cs | 2 +- Snowflake.Data/Core/SFResultSet.cs | 2 +- Snowflake.Data/Core/SFResultSetMetaData.cs | 2 +- Snowflake.Data/Core/SFStatement.cs | 2 +- .../Core/Session/ConnectionPoolManager.cs | 2 +- Snowflake.Data/Core/Session/SFSession.cs | 2 +- .../Session/SFSessionHttpClientProperties.cs | 2 +- .../Core/Session/SFSessionProperty.cs | 2 +- Snowflake.Data/Core/Session/SessionPool.cs | 2 +- ...ionPropertiesWithDefaultValuesExtractor.cs | 2 +- Snowflake.Data/Core/TomlConnectionBuilder.cs | 2 +- Snowflake.Data/Core/Tools/Diagnostics.cs | 2 +- .../Core/Tools/EnvironmentOperations.cs | 2 +- .../Core/Tools/HomeDirectoryProvider.cs | 2 +- Snowflake.Data/Logger/EasyLoggerManager.cs | 2 +- Snowflake.Data/Logger/SFAppenderImpl.cs | 12 ++--- Snowflake.Data/Logger/SFLoggerFactory.cs | 6 +-- 56 files changed, 115 insertions(+), 86 deletions(-) diff --git a/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs b/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs index 0d61e5933..c0ce63eed 100644 --- a/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs @@ -18,7 +18,7 @@ namespace Snowflake.Data.Tests.IntegrationTests public class ConnectionMultiplePoolsAsyncIT: SFBaseTestAsync { private readonly PoolConfig _previousPoolConfig = new PoolConfig(); - private readonly ILogger logger = SFLoggerFactory.GetLogger(); + private readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); [SetUp] public new void BeforeTest() diff --git a/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs b/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs index db7fd0c20..2bcbb389a 100644 --- a/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs @@ -21,7 +21,7 @@ namespace Snowflake.Data.Tests.IntegrationTests class ConnectionPoolCommonIT : SFBaseTest { private readonly ConnectionPoolType _connectionPoolTypeUnderTest; - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private readonly PoolConfig _previousPoolConfig; public ConnectionPoolCommonIT(ConnectionPoolType connectionPoolTypeUnderTest) diff --git a/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs index 74c0d284e..d51e65de5 100755 --- a/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs @@ -24,7 +24,7 @@ namespace Snowflake.Data.Tests.IntegrationTests [TestFixture] class SFBindTestIT : SFBaseTest { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); [Test] public void TestArrayBind() diff --git a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs index edc8ac8fb..073053d41 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs @@ -25,7 +25,7 @@ namespace Snowflake.Data.Tests.IntegrationTests [TestFixture] class SFConnectionIT : SFBaseTest { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); [Test] public void TestBasicConnection() @@ -1868,7 +1868,7 @@ public void TestKeepAlive() [TestFixture] class SFConnectionITAsync : SFBaseTestAsync { - private static ILogger logger = SFLoggerFactory.GetLogger(); + private static ILogger logger = SFLoggerFactory.GetCustomLogger(); [Test] diff --git a/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs index d5f8a5c55..b9bab0e80 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs @@ -21,7 +21,7 @@ namespace Snowflake.Data.Tests.IntegrationTests [TestFixture, NonParallelizable] class SFConnectionWithTomlIT : SFBaseTest { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private static string s_workingDirectory; diff --git a/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs b/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs index 0c3d59e1a..68cb8fad3 100644 --- a/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs +++ b/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs @@ -15,7 +15,7 @@ namespace Snowflake.Data.Tests.Mock { class MockSnowflakeDbConnection : SnowflakeDbConnection { - private ILogger logger = SFLoggerFactory.GetLogger(); + private ILogger logger = SFLoggerFactory.GetCustomLogger(); private IMockRestRequester _restRequester; diff --git a/Snowflake.Data.Tests/SFBaseTest.cs b/Snowflake.Data.Tests/SFBaseTest.cs index c05b042b9..a49e4c73c 100755 --- a/Snowflake.Data.Tests/SFBaseTest.cs +++ b/Snowflake.Data.Tests/SFBaseTest.cs @@ -58,7 +58,7 @@ public static void TearDownContext() #endif public class SFBaseTestAsync { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private const string ConnectionStringWithoutAuthFmt = "scheme={0};host={1};port={2};" + "account={3};role={4};db={5};schema={6};warehouse={7}"; diff --git a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs index 76913b629..b3aaab92e 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs @@ -152,7 +152,7 @@ public void TestThatRollsLogIfSizeIsTooBig() { _name = "RollingFileAppender", _logFilePath = Path.Combine(t_directoryLogPath, logFileName), - _maximumFileSize = 1, + _maximumFileSizeInBytes = 1, _maxSizeRollBackups = expecetedBackupLogCount, _patternLayout = EasyLoggerManager.PatternLayout() }); diff --git a/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs index 789f80f92..d0e3959b5 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/ILoggerTest.cs @@ -54,9 +54,9 @@ public void AfterTest() [Test] public void TestUsingDefaultLogger() { - var originalLogger = SFLoggerFactory.GetLogger(); + var originalLogger = SFLoggerFactory.GetCustomLogger(); SFLoggerFactory.UseDefaultLogger(); - _logger = SFLoggerFactory.GetLogger(); + _logger = SFLoggerFactory.GetCustomLogger(); Assert.IsInstanceOf(_logger); SFLoggerFactory.SetCustomLogger(originalLogger); } @@ -64,13 +64,25 @@ public void TestUsingDefaultLogger() [Test] public void TestSettingCustomLogger() { - var originalLogger = SFLoggerFactory.GetLogger(); + var originalLogger = SFLoggerFactory.GetCustomLogger(); SFLoggerFactory.SetCustomLogger(new ILoggerEmptyImpl()); - _logger = SFLoggerFactory.GetLogger(); + _logger = SFLoggerFactory.GetCustomLogger(); Assert.IsInstanceOf(_logger); SFLoggerFactory.SetCustomLogger(originalLogger); } + [Test] + public void TestBeginScope( + [Values(false, true)] bool isEnabled) + { + _logger = GetLogger(isEnabled); + + if (_logger is ILoggerEmptyImpl) + { + Assert.Throws(() => _logger.BeginScope("Test")); + } + } + [Test] public void TestIsDebugEnabled( [Values(false, true)] bool isEnabled) @@ -122,13 +134,13 @@ private ILogger GetLogger(bool isEnabled) SFLoggerFactory.DisableCustomLogger(); } - return SFLoggerFactory.GetLogger(); + return SFLoggerFactory.GetCustomLogger(); } [Test] public void TestThatLogsToProperFileWithProperLogLevelOnly() { - _logger = SFLoggerFactory.GetLogger(); + _logger = SFLoggerFactory.GetCustomLogger(); // act _logger.LogDebug(DebugMessage); diff --git a/Snowflake.Data.Tests/Util/ConnectingThreads.cs b/Snowflake.Data.Tests/Util/ConnectingThreads.cs index de5b6e462..305e6b0f6 100644 --- a/Snowflake.Data.Tests/Util/ConnectingThreads.cs +++ b/Snowflake.Data.Tests/Util/ConnectingThreads.cs @@ -56,7 +56,7 @@ public ConnectingThreads JoinAll() public void Enqueue(ThreadEvent threadEvent) => _events.Enqueue(threadEvent); - public static ILogger Logger() => SFLoggerFactory.GetLogger(); // we have to choose a class from Snowflake.Data package otherwise it will be visible in GH build output + public static ILogger Logger() => SFLoggerFactory.GetCustomLogger(); // we have to choose a class from Snowflake.Data package otherwise it will be visible in GH build output } class ConnectingThread diff --git a/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs b/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs index 8f91c11bf..055de6441 100644 --- a/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs +++ b/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs @@ -9,7 +9,7 @@ namespace Snowflake.Data.Tests.Util { public static class DbConnectionExtensions { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); internal static IDbCommand CreateCommand(this IDbConnection connection, string commandText) { diff --git a/Snowflake.Data/Client/SnowflakeDbCommand.cs b/Snowflake.Data/Client/SnowflakeDbCommand.cs index 47caef55b..a5a17a9fc 100755 --- a/Snowflake.Data/Client/SnowflakeDbCommand.cs +++ b/Snowflake.Data/Client/SnowflakeDbCommand.cs @@ -23,13 +23,16 @@ public class SnowflakeDbCommand : DbCommand private SnowflakeDbParameterCollection parameterCollection; - private ILogger logger = SFLoggerFactory.GetLogger(); + private SFLogger _snowflakeLogger = SFLoggerFactory.GetSFLogger(); + + private ILogger _customLogger = SFLoggerFactory.GetCustomLogger(); private readonly QueryResultsAwaiter _queryResultsAwaiter = QueryResultsAwaiter.Instance; public SnowflakeDbCommand() { - logger.LogDebug("Constructing SnowflakeDbCommand class"); + _snowflakeLogger.Debug("Constructing SnowflakeDbCommand class"); + _customLogger.LogDebug("Constructing SnowflakeDbCommand class"); // by default, no query timeout this.CommandTimeout = 0; parameterCollection = new SnowflakeDbParameterCollection(); @@ -166,7 +169,8 @@ public override void Cancel() public override int ExecuteNonQuery() { - logger.LogDebug($"ExecuteNonQuery"); + _snowflakeLogger.Debug($"ExecuteNonQuery"); + _customLogger.LogDebug($"ExecuteNonQuery"); SFBaseResultSet resultSet = ExecuteInternal(); long total = 0; do @@ -191,7 +195,8 @@ public override int ExecuteNonQuery() public override async Task ExecuteNonQueryAsync(CancellationToken cancellationToken) { - logger.LogDebug($"ExecuteNonQueryAsync"); + _snowflakeLogger.Debug($"ExecuteNonQueryAsync"); + _customLogger.LogDebug($"ExecuteNonQueryAsync"); cancellationToken.ThrowIfCancellationRequested(); var resultSet = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -218,7 +223,8 @@ public override async Task ExecuteNonQueryAsync(CancellationToken cancellat public override object ExecuteScalar() { - logger.LogDebug($"ExecuteScalar"); + _snowflakeLogger.Debug($"ExecuteScalar"); + _customLogger.LogDebug($"ExecuteScalar"); SFBaseResultSet resultSet = ExecuteInternal(); if(resultSet.Next()) @@ -229,7 +235,8 @@ public override object ExecuteScalar() public override async Task ExecuteScalarAsync(CancellationToken cancellationToken) { - logger.LogDebug($"ExecuteScalarAsync"); + _snowflakeLogger.Debug($"ExecuteScalarAsync"); + _customLogger.LogDebug($"ExecuteScalarAsync"); cancellationToken.ThrowIfCancellationRequested(); var result = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -264,14 +271,16 @@ protected override DbParameter CreateDbParameter() protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) { - logger.LogDebug($"ExecuteDbDataReader"); + _snowflakeLogger.Debug($"ExecuteDbDataReader"); + _customLogger.LogDebug($"ExecuteDbDataReader"); SFBaseResultSet resultSet = ExecuteInternal(); return new SnowflakeDbDataReader(this, resultSet); } protected override async Task ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) { - logger.LogDebug($"ExecuteDbDataReaderAsync"); + _snowflakeLogger.Debug($"ExecuteDbDataReaderAsync"); + _customLogger.LogDebug($"ExecuteDbDataReaderAsync"); try { var result = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -279,7 +288,8 @@ protected override async Task ExecuteDbDataReaderAsync(CommandBeha } catch (Exception ex) { - logger.LogError("The command failed to execute.", ex); + _snowflakeLogger.Error("The command failed to execute.", ex); + _customLogger.LogError("The command failed to execute.", ex); throw; } } @@ -291,7 +301,8 @@ protected override async Task ExecuteDbDataReaderAsync(CommandBeha /// The query id. public string ExecuteInAsyncMode() { - logger.LogDebug($"ExecuteInAsyncMode"); + _snowflakeLogger.Debug($"ExecuteInAsyncMode"); + _customLogger.LogDebug($"ExecuteInAsyncMode"); SFBaseResultSet resultSet = ExecuteInternal(asyncExec: true); return resultSet.queryId; } @@ -304,7 +315,8 @@ public string ExecuteInAsyncMode() /// The query id. public async Task ExecuteAsyncInAsyncMode(CancellationToken cancellationToken) { - logger.LogDebug($"ExecuteAsyncInAsyncMode"); + _snowflakeLogger.Debug($"ExecuteAsyncInAsyncMode"); + _customLogger.LogDebug($"ExecuteAsyncInAsyncMode"); var resultSet = await ExecuteInternalAsync(cancellationToken, asyncExec: true).ConfigureAwait(false); return resultSet.queryId; } @@ -316,7 +328,8 @@ public async Task ExecuteAsyncInAsyncMode(CancellationToken cancellation /// The query status. public QueryStatus GetQueryStatus(string queryId) { - logger.LogDebug($"GetQueryStatus"); + _snowflakeLogger.Debug($"GetQueryStatus"); + _customLogger.LogDebug($"GetQueryStatus"); return _queryResultsAwaiter.GetQueryStatus(connection, queryId); } @@ -328,7 +341,8 @@ public QueryStatus GetQueryStatus(string queryId) /// The query status. public async Task GetQueryStatusAsync(string queryId, CancellationToken cancellationToken) { - logger.LogDebug($"GetQueryStatusAsync"); + _snowflakeLogger.Debug($"GetQueryStatusAsync"); + _customLogger.LogDebug($"GetQueryStatusAsync"); return await _queryResultsAwaiter.GetQueryStatusAsync(connection, queryId, cancellationToken); } @@ -339,7 +353,8 @@ public async Task GetQueryStatusAsync(string queryId, CancellationT /// The query results. public DbDataReader GetResultsFromQueryId(string queryId) { - logger.LogDebug($"GetResultsFromQueryId"); + _snowflakeLogger.Debug($"GetResultsFromQueryId"); + _customLogger.LogDebug($"GetResultsFromQueryId"); Task task = _queryResultsAwaiter.RetryUntilQueryResultIsAvailable(connection, queryId, CancellationToken.None, false); task.Wait(); @@ -357,7 +372,8 @@ public DbDataReader GetResultsFromQueryId(string queryId) /// The query results. public async Task GetResultsFromQueryIdAsync(string queryId, CancellationToken cancellationToken) { - logger.LogDebug($"GetResultsFromQueryIdAsync"); + _snowflakeLogger.Debug($"GetResultsFromQueryIdAsync"); + _customLogger.LogDebug($"GetResultsFromQueryIdAsync"); await _queryResultsAwaiter.RetryUntilQueryResultIsAvailable(connection, queryId, cancellationToken, true); @@ -465,7 +481,8 @@ private void CheckIfCommandTextIsSet() if (string.IsNullOrEmpty(CommandText)) { var errorMessage = "Unable to execute command due to command text not being set"; - logger.LogError(errorMessage); + _snowflakeLogger.Debug(errorMessage); + _customLogger.LogError(errorMessage); throw new Exception(errorMessage); } } diff --git a/Snowflake.Data/Client/SnowflakeDbConnection.cs b/Snowflake.Data/Client/SnowflakeDbConnection.cs index 8ee7d6f62..632137aae 100755 --- a/Snowflake.Data/Client/SnowflakeDbConnection.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnection.cs @@ -17,7 +17,7 @@ namespace Snowflake.Data.Client [System.ComponentModel.DesignerCategory("Code")] public class SnowflakeDbConnection : DbConnection { - private ILogger logger = SFLoggerFactory.GetLogger(); + private ILogger logger = SFLoggerFactory.GetCustomLogger(); internal SFSession SfSession { get; set; } diff --git a/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs b/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs index 64c47703b..c5066ec3b 100644 --- a/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs @@ -16,7 +16,7 @@ namespace Snowflake.Data.Client { public class SnowflakeDbConnectionPool { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private static readonly Object s_connectionManagerInstanceLock = new Object(); private static IConnectionManager s_connectionManager; internal const ConnectionPoolType DefaultConnectionPoolType = ConnectionPoolType.MultipleConnectionPool; diff --git a/Snowflake.Data/Client/SnowflakeDbDataReader.cs b/Snowflake.Data/Client/SnowflakeDbDataReader.cs index cefc2a193..5d5453f9d 100755 --- a/Snowflake.Data/Client/SnowflakeDbDataReader.cs +++ b/Snowflake.Data/Client/SnowflakeDbDataReader.cs @@ -19,7 +19,7 @@ namespace Snowflake.Data.Client { public class SnowflakeDbDataReader : DbDataReader { - static private readonly ILogger logger = SFLoggerFactory.GetLogger(); + static private readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); private SnowflakeDbCommand dbCommand; diff --git a/Snowflake.Data/Client/SnowflakeDbTransaction.cs b/Snowflake.Data/Client/SnowflakeDbTransaction.cs index c10dd44ba..e15adc69f 100755 --- a/Snowflake.Data/Client/SnowflakeDbTransaction.cs +++ b/Snowflake.Data/Client/SnowflakeDbTransaction.cs @@ -13,7 +13,7 @@ namespace Snowflake.Data.Client { public class SnowflakeDbTransaction : DbTransaction { - private ILogger logger = SFLoggerFactory.GetLogger(); + private ILogger logger = SFLoggerFactory.GetCustomLogger(); private IsolationLevel isolationLevel; diff --git a/Snowflake.Data/Core/ArrowResultSet.cs b/Snowflake.Data/Core/ArrowResultSet.cs index fe398b82a..7f2a6c88c 100644 --- a/Snowflake.Data/Core/ArrowResultSet.cs +++ b/Snowflake.Data/Core/ArrowResultSet.cs @@ -18,7 +18,7 @@ class ArrowResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => ResultFormat.ARROW; - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private readonly int _totalChunkCount; private BaseResultChunk _currentChunk; diff --git a/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs b/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs index 84f58404e..060c88207 100644 --- a/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs @@ -12,7 +12,7 @@ namespace Snowflake.Data.Core.Authenticator class BasicAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "snowflake"; - private static readonly ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); internal BasicAuthenticator(SFSession session) : base(session, AUTH_NAME) { diff --git a/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs b/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs index 83e47dcbf..86b4e00f4 100644 --- a/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs @@ -23,7 +23,7 @@ namespace Snowflake.Data.Core.Authenticator class ExternalBrowserAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "externalbrowser"; - private static readonly ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); private static readonly string TOKEN_REQUEST_PREFIX = "?token="; private static readonly byte[] SUCCESS_RESPONSE = System.Text.Encoding.UTF8.GetBytes( "" + diff --git a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs index e077f2966..d7e0a0cc9 100644 --- a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs @@ -47,7 +47,7 @@ internal abstract class BaseAuthenticator { // The logger. private static readonly ILogger logger = - SFLoggerFactory.GetLogger(); + SFLoggerFactory.GetCustomLogger(); // The name of the authenticator. private string authName; @@ -135,7 +135,7 @@ private SFRestRequest BuildLoginRequest() /// internal class AuthenticatorFactory { - private static readonly ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); /// /// Generate the authenticator given the session /// diff --git a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs index fea927b57..e26a75ad2 100644 --- a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs @@ -34,7 +34,7 @@ class KeyPairAuthenticator : BaseAuthenticator, IAuthenticator // The logger. private static readonly ILogger logger = - SFLoggerFactory.GetLogger(); + SFLoggerFactory.GetCustomLogger(); // The RSA provider to use to sign the tokens private RSACryptoServiceProvider rsaProvider; diff --git a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs index 74f39d99c..c8ee881ce 100644 --- a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs @@ -19,7 +19,7 @@ class OAuthAuthenticator : BaseAuthenticator, IAuthenticator // The logger. private static readonly ILogger logger = - SFLoggerFactory.GetLogger(); + SFLoggerFactory.GetCustomLogger(); /// /// Constructor for the oauth authenticator. diff --git a/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs b/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs index 77a9a41cf..ec19475c6 100644 --- a/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs @@ -24,7 +24,7 @@ namespace Snowflake.Data.Core.Authenticator class OktaAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "okta"; - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); internal const string RetryCountHeader = "RetryCount"; internal const string TimeoutElapsedHeader = "TimeoutElapsed"; diff --git a/Snowflake.Data/Core/ChunkDownloaderFactory.cs b/Snowflake.Data/Core/ChunkDownloaderFactory.cs index cad3f3562..8836e142f 100755 --- a/Snowflake.Data/Core/ChunkDownloaderFactory.cs +++ b/Snowflake.Data/Core/ChunkDownloaderFactory.cs @@ -12,7 +12,7 @@ namespace Snowflake.Data.Core { class ChunkDownloaderFactory { - private static ILogger s_logger = SFLoggerFactory.GetLogger(); + private static ILogger s_logger = SFLoggerFactory.GetCustomLogger(); public static IChunkDownloader GetDownloader(QueryExecResponseData responseData, SFBaseResultSet resultSet, CancellationToken cancellationToken) diff --git a/Snowflake.Data/Core/ChunkParserFactory.cs b/Snowflake.Data/Core/ChunkParserFactory.cs index e5e9d6fb1..8521ca84f 100755 --- a/Snowflake.Data/Core/ChunkParserFactory.cs +++ b/Snowflake.Data/Core/ChunkParserFactory.cs @@ -12,7 +12,7 @@ namespace Snowflake.Data.Core { class ChunkParserFactory : IChunkParserFactory { - private static ILogger s_logger = SFLoggerFactory.GetLogger(); + private static ILogger s_logger = SFLoggerFactory.GetCustomLogger(); public static IChunkParserFactory Instance = new ChunkParserFactory(); public IChunkParser GetParser(ResultFormat resultFormat, Stream stream) diff --git a/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs b/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs index 4a2ebeee2..a8645390a 100644 --- a/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs +++ b/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs @@ -7,7 +7,7 @@ namespace Snowflake.Data.Core.Converter { public class StructuredTypesReadingHandler { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); public static SnowflakeDbException ToSnowflakeDbException(Exception exception, string context) { diff --git a/Snowflake.Data/Core/FastParser.cs b/Snowflake.Data/Core/FastParser.cs index 3d82668b8..2b9a0d470 100644 --- a/Snowflake.Data/Core/FastParser.cs +++ b/Snowflake.Data/Core/FastParser.cs @@ -7,7 +7,7 @@ namespace Snowflake.Data.Core { public class FastParser { - private static readonly ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); public static Int64 FastParseInt64(byte[] s, int offset, int len) { diff --git a/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs b/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs index 8ed71ebfa..3e2194c19 100644 --- a/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs +++ b/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs @@ -23,7 +23,7 @@ class EncryptionProvider /// /// The logger. /// - private static readonly ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); /// /// Encrypt data and write to the outStream. diff --git a/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs b/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs index 092a993a3..e334d5894 100644 --- a/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs +++ b/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs @@ -16,7 +16,7 @@ internal class GcmEncryptionProvider private const int InitVectorSizeInBytes = 12; private const string AesGcmNoPaddingCipher = "AES/GCM/NoPadding"; - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private static readonly SecureRandom s_random = SecureRandom.GetInstance("SHA1PRNG"); diff --git a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs index 6aa0363b6..9b7d99973 100644 --- a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs +++ b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs @@ -61,7 +61,7 @@ class SFFileTransferAgent /// /// The logger. /// - private static readonly ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); /// /// Auto-detect keyword for source compression type auto detection. diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs index 3da340924..303086cfc 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs @@ -43,7 +43,7 @@ class SFGCSClient : ISFRemoteStorageClient /// /// The logger. /// - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); /// /// The storage client. diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs index eb89c8d25..2abed3d2b 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs @@ -72,7 +72,7 @@ internal class S3Metadata /// /// The logger. /// - private static readonly ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); /// /// The underlying S3 client. diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs index e621f1363..3912defbd 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs @@ -31,7 +31,7 @@ class SFSnowflakeAzureClient : ISFRemoteStorageClient /// /// The logger. /// - private static readonly ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); /// /// The cloud blob client to use to upload and download data on Azure. diff --git a/Snowflake.Data/Core/HttpUtil.cs b/Snowflake.Data/Core/HttpUtil.cs index a8e1b0021..8b8758c07 100644 --- a/Snowflake.Data/Core/HttpUtil.cs +++ b/Snowflake.Data/Core/HttpUtil.cs @@ -78,7 +78,7 @@ public sealed class HttpUtil static internal readonly int MAX_BACKOFF = 16; private static readonly int s_baseBackOffTime = 1; private static readonly int s_exponentialFactor = 2; - private static readonly Microsoft.Extensions.Logging.ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly Microsoft.Extensions.Logging.ILogger logger = SFLoggerFactory.GetCustomLogger(); private static readonly List s_supportedEndpointsForRetryPolicy = new List { @@ -334,7 +334,7 @@ internal Uri Update(int retryReason = 0) } private class RetryHandler : DelegatingHandler { - static private ILogger logger = SFLoggerFactory.GetLogger(); + static private ILogger logger = SFLoggerFactory.GetCustomLogger(); private bool disableRetry; private bool forceRetryOn404; diff --git a/Snowflake.Data/Core/QueryContextCache.cs b/Snowflake.Data/Core/QueryContextCache.cs index 5b6e67ec3..e3fb53b24 100644 --- a/Snowflake.Data/Core/QueryContextCache.cs +++ b/Snowflake.Data/Core/QueryContextCache.cs @@ -76,7 +76,7 @@ internal class QueryContextCache private Dictionary _priorityMap; // Map for priority and QCC private Dictionary _newPriorityMap; // Intermediate map for priority and QCC for current round of merging private SortedSet _cacheSet; // Order data as per priority - private ILogger _logger = SFLoggerFactory.GetLogger(); + private ILogger _logger = SFLoggerFactory.GetCustomLogger(); public QueryContextCache(int capacity) { diff --git a/Snowflake.Data/Core/QueryResultsAwaiter.cs b/Snowflake.Data/Core/QueryResultsAwaiter.cs index 65c2f19de..7a31858f2 100644 --- a/Snowflake.Data/Core/QueryResultsAwaiter.cs +++ b/Snowflake.Data/Core/QueryResultsAwaiter.cs @@ -37,7 +37,7 @@ internal QueryResultsRetryConfig(int asyncNoDataMaxRetry, int[] asyncRetryPatter internal class QueryResultsAwaiter { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private static readonly Regex UuidRegex = new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); diff --git a/Snowflake.Data/Core/RestRequester.cs b/Snowflake.Data/Core/RestRequester.cs index 30fa1e415..aa10378c4 100644 --- a/Snowflake.Data/Core/RestRequester.cs +++ b/Snowflake.Data/Core/RestRequester.cs @@ -40,7 +40,7 @@ internal interface IMockRestRequester : IRestRequester internal class RestRequester : IRestRequester { - private static ILogger logger = SFLoggerFactory.GetLogger(); + private static ILogger logger = SFLoggerFactory.GetCustomLogger(); protected HttpClient _HttpClient; diff --git a/Snowflake.Data/Core/SFBindUploader.cs b/Snowflake.Data/Core/SFBindUploader.cs index 93d79ff11..b36d2ae6f 100644 --- a/Snowflake.Data/Core/SFBindUploader.cs +++ b/Snowflake.Data/Core/SFBindUploader.cs @@ -36,7 +36,7 @@ class SFBindUploader private string requestId; - private ILogger logger = SFLoggerFactory.GetLogger(); + private ILogger logger = SFLoggerFactory.GetCustomLogger(); private string stagePath; diff --git a/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs b/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs index c41e15581..741b1f90d 100755 --- a/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs +++ b/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs @@ -23,7 +23,7 @@ namespace Snowflake.Data.Core { class SFBlockingChunkDownloaderV3 : IChunkDownloader { - static private ILogger logger = SFLoggerFactory.GetLogger(); + static private ILogger logger = SFLoggerFactory.GetCustomLogger(); private List chunkDatas = new List(); diff --git a/Snowflake.Data/Core/SFMultiStatementsResultSet.cs b/Snowflake.Data/Core/SFMultiStatementsResultSet.cs index 448787632..71fc4dc2a 100644 --- a/Snowflake.Data/Core/SFMultiStatementsResultSet.cs +++ b/Snowflake.Data/Core/SFMultiStatementsResultSet.cs @@ -16,7 +16,7 @@ class SFMultiStatementsResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => curResultSet.ResultFormat; - private static readonly ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); private string[] resultIds; diff --git a/Snowflake.Data/Core/SFResultSet.cs b/Snowflake.Data/Core/SFResultSet.cs index dde625a50..4694d2792 100755 --- a/Snowflake.Data/Core/SFResultSet.cs +++ b/Snowflake.Data/Core/SFResultSet.cs @@ -17,7 +17,7 @@ class SFResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => ResultFormat.JSON; - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private readonly int _totalChunkCount; diff --git a/Snowflake.Data/Core/SFResultSetMetaData.cs b/Snowflake.Data/Core/SFResultSetMetaData.cs index b37e0fbb6..83470eda8 100755 --- a/Snowflake.Data/Core/SFResultSetMetaData.cs +++ b/Snowflake.Data/Core/SFResultSetMetaData.cs @@ -13,7 +13,7 @@ namespace Snowflake.Data.Core { class SFResultSetMetaData { - static private readonly ILogger logger = SFLoggerFactory.GetLogger(); + static private readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); private int columnCount; diff --git a/Snowflake.Data/Core/SFStatement.cs b/Snowflake.Data/Core/SFStatement.cs index c9eec6385..08ea0a166 100644 --- a/Snowflake.Data/Core/SFStatement.cs +++ b/Snowflake.Data/Core/SFStatement.cs @@ -98,7 +98,7 @@ internal static bool IsAnError(QueryStatus status) class SFStatement { - static private ILogger s_logger = SFLoggerFactory.GetLogger(); + static private ILogger s_logger = SFLoggerFactory.GetCustomLogger(); internal SFSession SfSession { get; set; } diff --git a/Snowflake.Data/Core/Session/ConnectionPoolManager.cs b/Snowflake.Data/Core/Session/ConnectionPoolManager.cs index a6ba12e38..067a4636a 100644 --- a/Snowflake.Data/Core/Session/ConnectionPoolManager.cs +++ b/Snowflake.Data/Core/Session/ConnectionPoolManager.cs @@ -17,7 +17,7 @@ namespace Snowflake.Data.Core.Session { internal sealed class ConnectionPoolManager : IConnectionManager { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private static readonly Object s_poolsLock = new Object(); private static readonly Exception s_operationNotAvailable = new Exception("You cannot change connection pool parameters for all the pools. Instead you can change it on a particular pool"); private readonly Dictionary _pools; diff --git a/Snowflake.Data/Core/Session/SFSession.cs b/Snowflake.Data/Core/Session/SFSession.cs index 568be8351..89643e306 100755 --- a/Snowflake.Data/Core/Session/SFSession.cs +++ b/Snowflake.Data/Core/Session/SFSession.cs @@ -24,7 +24,7 @@ public class SFSession { public const int SF_SESSION_EXPIRED_CODE = 390112; - private static readonly ILogger logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); private static readonly Regex APPLICATION_REGEX = new Regex(@"^[A-Za-z]([A-Za-z0-9.\-_]){1,50}$"); diff --git a/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs b/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs index a398507e2..d23b2e39b 100644 --- a/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs +++ b/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs @@ -22,7 +22,7 @@ internal class SFSessionHttpClientProperties public const bool DefaultPoolingEnabled = true; public const int DefaultMaxHttpRetries = 7; public static readonly TimeSpan DefaultRetryTimeout = TimeSpan.FromSeconds(300); - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); internal bool validateDefaultParameters; internal bool clientSessionKeepAlive; diff --git a/Snowflake.Data/Core/Session/SFSessionProperty.cs b/Snowflake.Data/Core/Session/SFSessionProperty.cs index e35f1d3d6..98e844599 100644 --- a/Snowflake.Data/Core/Session/SFSessionProperty.cs +++ b/Snowflake.Data/Core/Session/SFSessionProperty.cs @@ -127,7 +127,7 @@ class SFSessionPropertyAttr : Attribute class SFSessionProperties : Dictionary { - private static ILogger logger = SFLoggerFactory.GetLogger(); + private static ILogger logger = SFLoggerFactory.GetCustomLogger(); internal string ConnectionStringWithoutSecrets { get; set; } diff --git a/Snowflake.Data/Core/Session/SessionPool.cs b/Snowflake.Data/Core/Session/SessionPool.cs index 885b263ce..080f9ca1b 100644 --- a/Snowflake.Data/Core/Session/SessionPool.cs +++ b/Snowflake.Data/Core/Session/SessionPool.cs @@ -17,7 +17,7 @@ namespace Snowflake.Data.Core.Session { sealed class SessionPool : IDisposable { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private readonly object _sessionPoolLock = new object(); private static ISessionFactory s_sessionFactory = new SessionFactory(); diff --git a/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs b/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs index 11492787e..0d4e393cc 100644 --- a/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs +++ b/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs @@ -9,7 +9,7 @@ namespace Snowflake.Data.Core.Session { internal class SessionPropertiesWithDefaultValuesExtractor { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private static readonly Regex s_timeoutFormatRegex = new Regex(@"^(-)?[0-9]{1,10}[mM]?[sS]?$"); private readonly SFSessionProperties _propertiesDictionary; diff --git a/Snowflake.Data/Core/TomlConnectionBuilder.cs b/Snowflake.Data/Core/TomlConnectionBuilder.cs index 6976e593f..5bbe0c2d6 100644 --- a/Snowflake.Data/Core/TomlConnectionBuilder.cs +++ b/Snowflake.Data/Core/TomlConnectionBuilder.cs @@ -28,7 +28,7 @@ internal class TomlConnectionBuilder internal const string SnowflakeDefaultConnectionName = "SNOWFLAKE_DEFAULT_CONNECTION_NAME"; internal const string SnowflakeHome = "SNOWFLAKE_HOME"; - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); private readonly Dictionary _tomlToNetPropertiesMapper = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { diff --git a/Snowflake.Data/Core/Tools/Diagnostics.cs b/Snowflake.Data/Core/Tools/Diagnostics.cs index 90ad4c80d..f6faa39de 100644 --- a/Snowflake.Data/Core/Tools/Diagnostics.cs +++ b/Snowflake.Data/Core/Tools/Diagnostics.cs @@ -11,7 +11,7 @@ namespace Snowflake.Data.Core.Tools internal class Diagnostics { private const int PadRight = -25; - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); public static void LogDiagnostics() => s_logger.LogInformation(GetDiagnosticInfo()); diff --git a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs index daee66d65..da501edb7 100644 --- a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs +++ b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs @@ -12,7 +12,7 @@ namespace Snowflake.Data.Core.Tools internal class EnvironmentOperations { public static readonly EnvironmentOperations Instance = new EnvironmentOperations(); - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); public virtual string GetEnvironmentVariable(string variable) { diff --git a/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs b/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs index a273363b4..d22380c9d 100644 --- a/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs +++ b/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs @@ -10,7 +10,7 @@ namespace Snowflake.Data.Core.Tools { internal class HomeDirectoryProvider { - private static readonly ILogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); public static string HomeDirectory(EnvironmentOperations _environmentOperations) { try diff --git a/Snowflake.Data/Logger/EasyLoggerManager.cs b/Snowflake.Data/Logger/EasyLoggerManager.cs index 914c0b2a0..0a5cb681d 100644 --- a/Snowflake.Data/Logger/EasyLoggerManager.cs +++ b/Snowflake.Data/Logger/EasyLoggerManager.cs @@ -73,7 +73,7 @@ private static SFAppender AddRollingFileAppender(SFLogger logger, _patternLayout = patternLayout, _logFilePath = Path.Combine(directoryPath, logFileName), _name = $"{AppenderPrefix}RollingFileAppender", - _maximumFileSize = 1000000000, // "1GB" + _maximumFileSizeInBytes = 1000000000, // "1GB" _maxSizeRollBackups = 2, }; appender.ActivateOptions(); diff --git a/Snowflake.Data/Logger/SFAppenderImpl.cs b/Snowflake.Data/Logger/SFAppenderImpl.cs index ad864fc61..9b44285f3 100644 --- a/Snowflake.Data/Logger/SFAppenderImpl.cs +++ b/Snowflake.Data/Logger/SFAppenderImpl.cs @@ -50,7 +50,7 @@ internal class SFRollingFileAppender : SFAppender { internal string _name; internal string _logFilePath; - internal long _maximumFileSize; + internal long _maximumFileSizeInBytes; internal int _maxSizeRollBackups; internal PatternLayout _patternLayout; @@ -60,9 +60,9 @@ public void Append(string logLevel, string message, Type type, Exception ex = nu { try { - if (FileIsTooLarge()) + if (LogFileIsTooLarge()) { - RollFile(); + RollLogFile(); } var formattedMessage = _patternLayout.Format(logLevel, message, type); @@ -95,13 +95,13 @@ public void ActivateOptions() } } - private bool FileIsTooLarge() + private bool LogFileIsTooLarge() { FileInfo fileInfo = new FileInfo(_logFilePath); - return fileInfo.Exists && fileInfo.Length > _maximumFileSize; + return fileInfo.Exists && fileInfo.Length > _maximumFileSizeInBytes; } - private void RollFile() + private void RollLogFile() { string rollFilePath = $"{_logFilePath}.{DateTime.Now:yyyyMMddHHmmss}.bak"; File.Move(_logFilePath, rollFilePath); diff --git a/Snowflake.Data/Logger/SFLoggerFactory.cs b/Snowflake.Data/Logger/SFLoggerFactory.cs index bc695bc3a..b17b4e55e 100755 --- a/Snowflake.Data/Logger/SFLoggerFactory.cs +++ b/Snowflake.Data/Logger/SFLoggerFactory.cs @@ -42,7 +42,7 @@ public static void UseDefaultLogger() public static void SetCustomLogger(ILogger customLogger) { - SFLoggerFactory.s_customLogger = customLogger; + s_customLogger = customLogger; } internal static SFLogger GetSFLogger(bool useFileAppender = true) @@ -57,7 +57,7 @@ internal static SFLogger GetSFLogger(bool useFileAppender = true) { _name = "RollingFileAppender", _logFilePath = Path.Combine(Directory.GetCurrentDirectory(), "test_snowflake_log.log"), - _maximumFileSize = 1000000000, // "1GB" + _maximumFileSizeInBytes = 1000000000, // "1GB" _maxSizeRollBackups = 0, _patternLayout = EasyLoggerManager.PatternLayout() }; @@ -81,7 +81,7 @@ internal static SFLogger GetSFLogger(bool useFileAppender = true) } } - internal static ILogger GetLogger() + internal static ILogger GetCustomLogger() { // If true, return the default/specified logger if (s_isCustomLoggerEnabled) From c9d8d92eb4ae41a503a04a80beaafe278519131d Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Wed, 4 Dec 2024 17:58:45 -0800 Subject: [PATCH 16/35] Refactor logger functions add logger pair class --- .../UnitTests/Logger/EasyLoggerManagerTest.cs | 24 ++++----- .../UnitTests/Logger/SFLoggerTest.cs | 8 +-- Snowflake.Data/Client/SnowflakeDbCommand.cs | 49 ++++++------------- .../Configuration/EasyLoggingConfigFinder.cs | 6 +-- .../Configuration/EasyLoggingConfigParser.cs | 2 +- .../Core/Session/EasyLoggingStarter.cs | 16 +++--- Snowflake.Data/Logger/SFLogger.cs | 8 +-- Snowflake.Data/Logger/SFLoggerEmptyImpl.cs | 8 +-- Snowflake.Data/Logger/SFLoggerImpl.cs | 18 +++---- Snowflake.Data/Logger/SFLoggerPair.cs | 48 ++++++++++++++++++ 10 files changed, 109 insertions(+), 78 deletions(-) create mode 100644 Snowflake.Data/Logger/SFLoggerPair.cs diff --git a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs index b3aaab92e..57d0cb1a6 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs @@ -56,8 +56,8 @@ public void TestThatChangesLogLevel() // assert Assert.IsFalse(logger.IsDebugEnabled()); - Assert.IsFalse(logger.IsInfoEnabled()); - Assert.IsFalse(logger.IsWarnEnabled()); + Assert.IsFalse(logger.IsInformationEnabled()); + Assert.IsFalse(logger.IsWarningEnabled()); Assert.IsFalse(logger.IsErrorEnabled()); Assert.IsFalse(logger.IsFatalEnabled()); @@ -66,8 +66,8 @@ public void TestThatChangesLogLevel() // assert Assert.IsFalse(logger.IsDebugEnabled()); - Assert.IsFalse(logger.IsInfoEnabled()); - Assert.IsFalse(logger.IsWarnEnabled()); + Assert.IsFalse(logger.IsInformationEnabled()); + Assert.IsFalse(logger.IsWarningEnabled()); Assert.IsFalse(logger.IsErrorEnabled()); Assert.IsTrue(logger.IsFatalEnabled()); @@ -76,8 +76,8 @@ public void TestThatChangesLogLevel() // assert Assert.IsFalse(logger.IsDebugEnabled()); - Assert.IsFalse(logger.IsInfoEnabled()); - Assert.IsFalse(logger.IsWarnEnabled()); + Assert.IsFalse(logger.IsInformationEnabled()); + Assert.IsFalse(logger.IsWarningEnabled()); Assert.IsTrue(logger.IsErrorEnabled()); Assert.IsTrue(logger.IsFatalEnabled()); @@ -86,8 +86,8 @@ public void TestThatChangesLogLevel() // assert Assert.IsFalse(logger.IsDebugEnabled()); - Assert.IsFalse(logger.IsInfoEnabled()); - Assert.IsTrue(logger.IsWarnEnabled()); + Assert.IsFalse(logger.IsInformationEnabled()); + Assert.IsTrue(logger.IsWarningEnabled()); Assert.IsTrue(logger.IsErrorEnabled()); Assert.IsTrue(logger.IsFatalEnabled()); @@ -96,8 +96,8 @@ public void TestThatChangesLogLevel() // assert Assert.IsTrue(logger.IsDebugEnabled()); - Assert.IsTrue(logger.IsInfoEnabled()); - Assert.IsTrue(logger.IsWarnEnabled()); + Assert.IsTrue(logger.IsInformationEnabled()); + Assert.IsTrue(logger.IsWarningEnabled()); Assert.IsTrue(logger.IsErrorEnabled()); Assert.IsTrue(logger.IsFatalEnabled()); } @@ -111,8 +111,8 @@ public void TestThatLogsToProperFileWithProperLogLevelOnly() // act logger.Debug(DebugMessage); - logger.Info(InfoMessage); - logger.Warn(WarnMessage); + logger.Information(InfoMessage); + logger.Warning(WarnMessage); logger.Error(ErrorMessage); logger.Fatal(FatalMessage); diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs index 0c0fc5a71..c217dfeba 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs @@ -67,8 +67,8 @@ public void TestIsInfoEnabled( { _logger = GetLogger(isEnabled); - Assert.AreEqual(isEnabled, _logger.IsInfoEnabled()); - _logger.Info("info log message", new Exception("test exception")); + Assert.AreEqual(isEnabled, _logger.IsInformationEnabled()); + _logger.Information("info log message", new Exception("test exception")); } [Test] @@ -77,8 +77,8 @@ public void TestIsWarnEnabled( { _logger = GetLogger(isEnabled); - Assert.AreEqual(isEnabled, _logger.IsWarnEnabled()); - _logger.Warn("warn log message", new Exception("test exception")); + Assert.AreEqual(isEnabled, _logger.IsWarningEnabled()); + _logger.Warning("warn log message", new Exception("test exception")); } [Test] diff --git a/Snowflake.Data/Client/SnowflakeDbCommand.cs b/Snowflake.Data/Client/SnowflakeDbCommand.cs index a5a17a9fc..6050b163c 100755 --- a/Snowflake.Data/Client/SnowflakeDbCommand.cs +++ b/Snowflake.Data/Client/SnowflakeDbCommand.cs @@ -23,16 +23,13 @@ public class SnowflakeDbCommand : DbCommand private SnowflakeDbParameterCollection parameterCollection; - private SFLogger _snowflakeLogger = SFLoggerFactory.GetSFLogger(); - - private ILogger _customLogger = SFLoggerFactory.GetCustomLogger(); + private SFLoggerPair _loggerPair = SFLoggerPair.GetLoggerPair(); private readonly QueryResultsAwaiter _queryResultsAwaiter = QueryResultsAwaiter.Instance; public SnowflakeDbCommand() { - _snowflakeLogger.Debug("Constructing SnowflakeDbCommand class"); - _customLogger.LogDebug("Constructing SnowflakeDbCommand class"); + _loggerPair.LogDebug("Constructing SnowflakeDbCommand class"); // by default, no query timeout this.CommandTimeout = 0; parameterCollection = new SnowflakeDbParameterCollection(); @@ -169,8 +166,7 @@ public override void Cancel() public override int ExecuteNonQuery() { - _snowflakeLogger.Debug($"ExecuteNonQuery"); - _customLogger.LogDebug($"ExecuteNonQuery"); + _loggerPair.LogDebug($"ExecuteNonQuery"); SFBaseResultSet resultSet = ExecuteInternal(); long total = 0; do @@ -195,8 +191,7 @@ public override int ExecuteNonQuery() public override async Task ExecuteNonQueryAsync(CancellationToken cancellationToken) { - _snowflakeLogger.Debug($"ExecuteNonQueryAsync"); - _customLogger.LogDebug($"ExecuteNonQueryAsync"); + _loggerPair.LogDebug($"ExecuteNonQueryAsync"); cancellationToken.ThrowIfCancellationRequested(); var resultSet = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -223,8 +218,7 @@ public override async Task ExecuteNonQueryAsync(CancellationToken cancellat public override object ExecuteScalar() { - _snowflakeLogger.Debug($"ExecuteScalar"); - _customLogger.LogDebug($"ExecuteScalar"); + _loggerPair.LogDebug($"ExecuteScalar"); SFBaseResultSet resultSet = ExecuteInternal(); if(resultSet.Next()) @@ -235,8 +229,7 @@ public override object ExecuteScalar() public override async Task ExecuteScalarAsync(CancellationToken cancellationToken) { - _snowflakeLogger.Debug($"ExecuteScalarAsync"); - _customLogger.LogDebug($"ExecuteScalarAsync"); + _loggerPair.LogDebug($"ExecuteScalarAsync"); cancellationToken.ThrowIfCancellationRequested(); var result = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -271,16 +264,14 @@ protected override DbParameter CreateDbParameter() protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) { - _snowflakeLogger.Debug($"ExecuteDbDataReader"); - _customLogger.LogDebug($"ExecuteDbDataReader"); + _loggerPair.LogDebug($"ExecuteDbDataReader"); SFBaseResultSet resultSet = ExecuteInternal(); return new SnowflakeDbDataReader(this, resultSet); } protected override async Task ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) { - _snowflakeLogger.Debug($"ExecuteDbDataReaderAsync"); - _customLogger.LogDebug($"ExecuteDbDataReaderAsync"); + _loggerPair.LogDebug($"ExecuteDbDataReaderAsync"); try { var result = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -288,8 +279,7 @@ protected override async Task ExecuteDbDataReaderAsync(CommandBeha } catch (Exception ex) { - _snowflakeLogger.Error("The command failed to execute.", ex); - _customLogger.LogError("The command failed to execute.", ex); + _loggerPair.LogError("The command failed to execute.", ex); throw; } } @@ -301,8 +291,7 @@ protected override async Task ExecuteDbDataReaderAsync(CommandBeha /// The query id. public string ExecuteInAsyncMode() { - _snowflakeLogger.Debug($"ExecuteInAsyncMode"); - _customLogger.LogDebug($"ExecuteInAsyncMode"); + _loggerPair.LogDebug($"ExecuteInAsyncMode"); SFBaseResultSet resultSet = ExecuteInternal(asyncExec: true); return resultSet.queryId; } @@ -315,8 +304,7 @@ public string ExecuteInAsyncMode() /// The query id. public async Task ExecuteAsyncInAsyncMode(CancellationToken cancellationToken) { - _snowflakeLogger.Debug($"ExecuteAsyncInAsyncMode"); - _customLogger.LogDebug($"ExecuteAsyncInAsyncMode"); + _loggerPair.LogDebug($"ExecuteAsyncInAsyncMode"); var resultSet = await ExecuteInternalAsync(cancellationToken, asyncExec: true).ConfigureAwait(false); return resultSet.queryId; } @@ -328,8 +316,7 @@ public async Task ExecuteAsyncInAsyncMode(CancellationToken cancellation /// The query status. public QueryStatus GetQueryStatus(string queryId) { - _snowflakeLogger.Debug($"GetQueryStatus"); - _customLogger.LogDebug($"GetQueryStatus"); + _loggerPair.LogDebug($"GetQueryStatus"); return _queryResultsAwaiter.GetQueryStatus(connection, queryId); } @@ -341,8 +328,7 @@ public QueryStatus GetQueryStatus(string queryId) /// The query status. public async Task GetQueryStatusAsync(string queryId, CancellationToken cancellationToken) { - _snowflakeLogger.Debug($"GetQueryStatusAsync"); - _customLogger.LogDebug($"GetQueryStatusAsync"); + _loggerPair.LogDebug($"GetQueryStatusAsync"); return await _queryResultsAwaiter.GetQueryStatusAsync(connection, queryId, cancellationToken); } @@ -353,8 +339,7 @@ public async Task GetQueryStatusAsync(string queryId, CancellationT /// The query results. public DbDataReader GetResultsFromQueryId(string queryId) { - _snowflakeLogger.Debug($"GetResultsFromQueryId"); - _customLogger.LogDebug($"GetResultsFromQueryId"); + _loggerPair.LogDebug($"GetResultsFromQueryId"); Task task = _queryResultsAwaiter.RetryUntilQueryResultIsAvailable(connection, queryId, CancellationToken.None, false); task.Wait(); @@ -372,8 +357,7 @@ public DbDataReader GetResultsFromQueryId(string queryId) /// The query results. public async Task GetResultsFromQueryIdAsync(string queryId, CancellationToken cancellationToken) { - _snowflakeLogger.Debug($"GetResultsFromQueryIdAsync"); - _customLogger.LogDebug($"GetResultsFromQueryIdAsync"); + _loggerPair.LogDebug($"GetResultsFromQueryIdAsync"); await _queryResultsAwaiter.RetryUntilQueryResultIsAvailable(connection, queryId, cancellationToken, true); @@ -481,8 +465,7 @@ private void CheckIfCommandTextIsSet() if (string.IsNullOrEmpty(CommandText)) { var errorMessage = "Unable to execute command due to command text not being set"; - _snowflakeLogger.Debug(errorMessage); - _customLogger.LogError(errorMessage); + _loggerPair.LogError(errorMessage); throw new Exception(errorMessage); } } diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs b/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs index d42c2573a..a53300bb9 100644 --- a/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs +++ b/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs @@ -62,7 +62,7 @@ private string GetFilePathFromInputParameter(string filePath, string inputDescri { return null; } - s_logger.Info($"Using config file specified from {inputDescription}: {filePath}"); + s_logger.Information($"Using config file specified from {inputDescription}: {filePath}"); return filePath; } @@ -77,7 +77,7 @@ private string SearchForConfigInDirectory(Func directoryProvider, string var directory = directoryProvider.Invoke(); if (string.IsNullOrEmpty(directory)) { - s_logger.Warn($"The {directoryDescription} directory could not be determined and will be skipped"); + s_logger.Warning($"The {directoryDescription} directory could not be determined and will be skipped"); return null; } @@ -95,7 +95,7 @@ private string OnlyIfFileExists(string filePath, string directoryDescription) { if (_fileOperations.Exists(filePath)) { - s_logger.Info($"Using config file specified from {directoryDescription} directory: {filePath}"); + s_logger.Information($"Using config file specified from {directoryDescription} directory: {filePath}"); return filePath; } return null; diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs b/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs index 48b244b57..5989ac27b 100644 --- a/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs +++ b/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs @@ -79,7 +79,7 @@ private void CheckForUnknownFields(string fileContent) .Cast() .Where(property => !knownProperties.Contains(property.Name, StringComparer.OrdinalIgnoreCase)) .ToList() - .ForEach(unknownKey => s_logger.Warn($"Unknown field from config: {unknownKey.Name}")); + .ForEach(unknownKey => s_logger.Warning($"Unknown field from config: {unknownKey.Name}")); } } } diff --git a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs index 97487256e..05b80164a 100644 --- a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs +++ b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs @@ -62,11 +62,11 @@ public virtual void Init(string configFilePathFromConnectionString) } if (string.IsNullOrEmpty(configFilePathFromConnectionString)) { - s_logger.Info($"Attempting to enable easy logging without a config file specified from connection string"); + s_logger.Information($"Attempting to enable easy logging without a config file specified from connection string"); } else { - s_logger.Info($"Attempting to enable easy logging using config file specified from connection string: {configFilePathFromConnectionString}"); + s_logger.Information($"Attempting to enable easy logging using config file specified from connection string: {configFilePathFromConnectionString}"); } var config = _easyLoggingConfigProvider.ProvideConfig(configFilePathFromConnectionString); if (config == null) @@ -76,8 +76,8 @@ public virtual void Init(string configFilePathFromConnectionString) } var logLevel = GetLogLevel(config.CommonProps.LogLevel); var logPath = GetLogPath(config.CommonProps.LogPath); - s_logger.Info($"LogLevel set to {logLevel}"); - s_logger.Info($"LogPath set to {logPath}"); + s_logger.Information($"LogLevel set to {logLevel}"); + s_logger.Information($"LogPath set to {logPath}"); _easyLoggerManager.ReconfigureEasyLogging(logLevel, logPath); _initTrialParameters = new EasyLoggingInitTrialParameters(configFilePathFromConnectionString); } @@ -100,7 +100,7 @@ private bool AllowedToInitialize(string configFilePathFromConnectionString) var isAllowedToInitialize = !everTriedToInitialize || (triedToInitializeWithoutConfigFile && isGivenConfigFilePath); if (!isAllowedToInitialize && _initTrialParameters.HasDifferentConfigPath(configFilePathFromConnectionString)) { - s_logger.Warn($"Easy logging will not be configured for CLIENT_CONFIG_FILE={configFilePathFromConnectionString} because it was previously configured for a different client config"); + s_logger.Warning($"Easy logging will not be configured for CLIENT_CONFIG_FILE={configFilePathFromConnectionString} because it was previously configured for a different client config"); } return isAllowedToInitialize; @@ -110,7 +110,7 @@ private EasyLoggingLogLevel GetLogLevel(string logLevel) { if (string.IsNullOrEmpty(logLevel)) { - s_logger.Warn("LogLevel in client config not found. Using default value: OFF"); + s_logger.Warning("LogLevel in client config not found. Using default value: OFF"); return EasyLoggingLogLevel.Off; } return EasyLoggingLogLevelExtensions.From(logLevel); @@ -121,7 +121,7 @@ private string GetLogPath(string logPath) var logPathOrDefault = logPath; if (string.IsNullOrEmpty(logPath)) { - s_logger.Warn("LogPath in client config not found. Using home directory as a default value"); + s_logger.Warning("LogPath in client config not found. Using home directory as a default value"); logPathOrDefault = HomeDirectoryProvider.HomeDirectory(_environmentOperations); if (string.IsNullOrEmpty(logPathOrDefault)) { @@ -163,7 +163,7 @@ private void CheckDirPermissionsOnlyAllowUser(string dirPath) var dirPermissions = _unixOperations.GetDirPermissions(dirPath); if (dirPermissions != FileAccessPermissions.UserReadWriteExecute) { - s_logger.Warn($"Access permission for the logs directory is currently " + + s_logger.Warning($"Access permission for the logs directory is currently " + $"{UnixFilePermissionsConverter.ConvertFileAccessPermissionsToInt(dirPermissions)} " + $"and is potentially accessible to users other than the owner of the logs directory"); } diff --git a/Snowflake.Data/Logger/SFLogger.cs b/Snowflake.Data/Logger/SFLogger.cs index 0aa35e925..e4d4596c3 100644 --- a/Snowflake.Data/Logger/SFLogger.cs +++ b/Snowflake.Data/Logger/SFLogger.cs @@ -11,9 +11,9 @@ interface SFLogger { bool IsDebugEnabled(); - bool IsInfoEnabled(); + bool IsInformationEnabled(); - bool IsWarnEnabled(); + bool IsWarningEnabled(); bool IsErrorEnabled(); @@ -21,9 +21,9 @@ interface SFLogger void Debug(string msg, Exception ex = null); - void Info(string msg, Exception ex = null); + void Information(string msg, Exception ex = null); - void Warn(string msg, Exception ex = null); + void Warning(string msg, Exception ex = null); void Error(string msg, Exception ex = null); diff --git a/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs b/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs index 1e6eb2e68..ebfac2f8a 100644 --- a/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs +++ b/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs @@ -17,12 +17,12 @@ public bool IsDebugEnabled() return false; } - public bool IsInfoEnabled() + public bool IsInformationEnabled() { return false; } - public bool IsWarnEnabled() + public bool IsWarningEnabled() { return false; } @@ -42,12 +42,12 @@ public void Debug(string msg, Exception ex) return; } - public void Info(string msg, Exception ex) + public void Information(string msg, Exception ex) { return; } - public void Warn(string msg, Exception ex) + public void Warning(string msg, Exception ex) { return; } diff --git a/Snowflake.Data/Logger/SFLoggerImpl.cs b/Snowflake.Data/Logger/SFLoggerImpl.cs index c33e491d4..5fa4b0431 100644 --- a/Snowflake.Data/Logger/SFLoggerImpl.cs +++ b/Snowflake.Data/Logger/SFLoggerImpl.cs @@ -8,7 +8,7 @@ public static class SFLogRepository { - internal static SFLogger s_rootLogger = s_rootLogger = new SFLoggerImpl(typeof(SFLogRepository)); + internal static SFLogger s_rootLogger = new SFLoggerImpl(typeof(SFLogRepository)); internal static SFLogger GetRootLogger() { @@ -95,18 +95,18 @@ public bool IsDebugEnabled() SFLogRepository.s_rootLogger.IsDebugEnabled(); } - public bool IsInfoEnabled() + public bool IsInformationEnabled() { return SFLogRepository.s_rootLogger == this ? _isInfoEnabled : - SFLogRepository.s_rootLogger.IsInfoEnabled(); + SFLogRepository.s_rootLogger.IsInformationEnabled(); } - public bool IsWarnEnabled() + public bool IsWarningEnabled() { return SFLogRepository.s_rootLogger == this ? _isWarnEnabled : - SFLogRepository.s_rootLogger.IsWarnEnabled(); + SFLogRepository.s_rootLogger.IsWarningEnabled(); } public bool IsErrorEnabled() @@ -132,18 +132,18 @@ public void Debug(string msg, Exception ex = null) } } - public void Info(string msg, Exception ex = null) + public void Information(string msg, Exception ex = null) { - if (IsInfoEnabled()) + if (IsInformationEnabled()) { msg = SecretDetector.MaskSecrets(msg).maskedText; Log(LoggingEvent.INFO.ToString(), msg, ex); } } - public void Warn(string msg, Exception ex = null) + public void Warning(string msg, Exception ex = null) { - if (IsWarnEnabled()) + if (IsWarningEnabled()) { msg = SecretDetector.MaskSecrets(msg).maskedText; Log(LoggingEvent.WARN.ToString(), msg, ex); diff --git a/Snowflake.Data/Logger/SFLoggerPair.cs b/Snowflake.Data/Logger/SFLoggerPair.cs new file mode 100644 index 000000000..a0f49e497 --- /dev/null +++ b/Snowflake.Data/Logger/SFLoggerPair.cs @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. + */ + +using Microsoft.Extensions.Logging; +using Snowflake.Data.Log; +using System; + +public class SFLoggerPair +{ + private static SFLogger s_snowflakeLogger; + private static ILogger s_customLogger; + + SFLoggerPair(SFLogger snowflakLogger, ILogger customLogger) + { + s_snowflakeLogger = snowflakLogger; + s_customLogger = customLogger; + } + + internal static SFLoggerPair GetLoggerPair() + { + return new SFLoggerPair(SFLoggerFactory.GetSFLogger(), SFLoggerFactory.GetCustomLogger()); + } + + internal void LogDebug(string message, Exception ex = null) + { + s_snowflakeLogger.Debug(message, ex); + s_customLogger.LogDebug(message, ex); + } + + internal void LogInformation(string message, Exception ex = null) + { + s_snowflakeLogger.Information(message, ex); + s_customLogger.LogInformation(message, ex); + } + + internal void LogWarning(string message, Exception ex = null) + { + s_snowflakeLogger.Warning(message, ex); + s_customLogger.LogWarning(message, ex); + } + + internal void LogError(string message, Exception ex = null) + { + s_snowflakeLogger.Error(message, ex); + s_customLogger.LogError(message, ex); + } +} From f0da3e75ce0ec6d69361b60592224e3fe0e5600d Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Wed, 4 Dec 2024 19:16:27 -0800 Subject: [PATCH 17/35] Replace ILogger with logger pair --- Snowflake.Data/Client/SnowflakeDbCommand.cs | 1 - .../Client/SnowflakeDbConnection.cs | 47 +++++----- .../Client/SnowflakeDbConnectionPool.cs | 37 ++++---- .../Client/SnowflakeDbDataReader.cs | 3 +- .../Client/SnowflakeDbTransaction.cs | 13 ++- Snowflake.Data/Core/ArrowResultSet.cs | 11 +-- .../Core/Authenticator/BasicAuthenticator.cs | 5 +- .../ExternalBrowserAuthenticator.cs | 35 ++++--- .../Core/Authenticator/IAuthenticator.cs | 15 ++- .../Authenticator/KeyPairAuthenticator.cs | 13 ++- .../Core/Authenticator/OAuthAuthenticator.cs | 5 +- .../Core/Authenticator/OktaAuthenticator.cs | 57 ++++++------ Snowflake.Data/Core/ChunkDownloaderFactory.cs | 9 +- Snowflake.Data/Core/ChunkParserFactory.cs | 9 +- .../StructuredTypesReadingHandler.cs | 7 +- Snowflake.Data/Core/FastParser.cs | 9 +- .../Core/FileTransfer/EncryptionProvider.cs | 7 +- .../FileTransfer/GcmEncryptionProvider.cs | 5 +- .../Core/FileTransfer/SFFileTransferAgent.cs | 59 ++++++------ .../FileTransfer/StorageClient/SFGCSClient.cs | 17 ++-- .../FileTransfer/StorageClient/SFS3Client.cs | 11 +-- .../StorageClient/SFSnowflakeAzureClient.cs | 5 +- Snowflake.Data/Core/HttpUtil.cs | 39 ++++---- Snowflake.Data/Core/QueryContextCache.cs | 25 +++-- Snowflake.Data/Core/QueryResultsAwaiter.cs | 11 +-- Snowflake.Data/Core/RestRequester.cs | 11 +-- Snowflake.Data/Core/SFBindUploader.cs | 7 +- .../Core/SFBlockingChunkDownloaderV3.cs | 13 ++- .../Core/SFMultiStatementsResultSet.cs | 5 +- Snowflake.Data/Core/SFResultSet.cs | 13 ++- Snowflake.Data/Core/SFResultSetMetaData.cs | 5 +- Snowflake.Data/Core/SFStatement.cs | 43 +++++---- .../Core/Session/ConnectionPoolManager.cs | 27 +++--- Snowflake.Data/Core/Session/SFSession.cs | 59 ++++++------ .../Session/SFSessionHttpClientProperties.cs | 27 +++--- .../Core/Session/SFSessionProperty.cs | 35 ++++--- Snowflake.Data/Core/Session/SessionPool.cs | 91 +++++++++---------- ...ionPropertiesWithDefaultValuesExtractor.cs | 13 ++- Snowflake.Data/Core/TomlConnectionBuilder.cs | 13 ++- Snowflake.Data/Core/Tools/Diagnostics.cs | 7 +- .../Core/Tools/EnvironmentOperations.cs | 5 +- .../Core/Tools/HomeDirectoryProvider.cs | 5 +- Snowflake.Data/Logger/SFAppenderImpl.cs | 19 ++-- Snowflake.Data/Logger/SFLoggerPair.cs | 82 +++++++++-------- 44 files changed, 452 insertions(+), 483 deletions(-) diff --git a/Snowflake.Data/Client/SnowflakeDbCommand.cs b/Snowflake.Data/Client/SnowflakeDbCommand.cs index 6050b163c..22a4e53ed 100755 --- a/Snowflake.Data/Client/SnowflakeDbCommand.cs +++ b/Snowflake.Data/Client/SnowflakeDbCommand.cs @@ -10,7 +10,6 @@ using System.Threading; using System.Threading.Tasks; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Client { diff --git a/Snowflake.Data/Client/SnowflakeDbConnection.cs b/Snowflake.Data/Client/SnowflakeDbConnection.cs index 632137aae..205308eda 100755 --- a/Snowflake.Data/Client/SnowflakeDbConnection.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnection.cs @@ -10,14 +10,13 @@ using System.Threading.Tasks; using Snowflake.Data.Core; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Client { [System.ComponentModel.DesignerCategory("Code")] public class SnowflakeDbConnection : DbConnection { - private ILogger logger = SFLoggerFactory.GetCustomLogger(); + private SFLoggerPair _loggerPair = SFLoggerPair.GetLoggerPair(); internal SFSession SfSession { get; set; } @@ -121,7 +120,7 @@ public void PreventPooling() throw new Exception("Session not yet created for this connection. Unable to prevent the session from pooling"); } SfSession.SetPooling(false); - logger.LogDebug($"Session {SfSession.sessionId} marked not to be pooled any more"); + _loggerPair.LogDebug($"Session {SfSession.sessionId} marked not to be pooled any more"); } internal bool HasActiveExplicitTransaction() => ExplicitTransaction != null && ExplicitTransaction.IsActive; @@ -139,7 +138,7 @@ private bool TryToReturnSessionToPool() var sessionReturnedToPool = SnowflakeDbConnectionPool.AddSession(SfSession); if (sessionReturnedToPool) { - logger.LogDebug($"Session pooled: {SfSession.sessionId}"); + _loggerPair.LogDebug($"Session pooled: {SfSession.sessionId}"); } return sessionReturnedToPool; } @@ -150,13 +149,13 @@ private TransactionRollbackStatus TerminateTransactionForDirtyConnectionReturnin return TransactionRollbackStatus.Success; try { - logger.LogDebug("Closing dirty connection: an active transaction exists in session: " + SfSession.sessionId); + _loggerPair.LogDebug("Closing dirty connection: an active transaction exists in session: " + SfSession.sessionId); using (IDbCommand command = CreateCommand()) { command.CommandText = "ROLLBACK"; command.ExecuteNonQuery(); // error to indicate a problem within application code that a connection was closed while still having a pending transaction - logger.LogError("Closing dirty connection: rollback transaction in session " + SfSession.sessionId + " succeeded."); + _loggerPair.LogError("Closing dirty connection: rollback transaction in session " + SfSession.sessionId + " succeeded."); ExplicitTransaction = null; return TransactionRollbackStatus.Success; } @@ -164,14 +163,14 @@ private TransactionRollbackStatus TerminateTransactionForDirtyConnectionReturnin catch (Exception exception) { // error to indicate a problem with rollback of an active transaction and inability to return dirty connection to the pool - logger.LogError("Closing dirty connection: rollback transaction in session: " + SfSession.sessionId + " failed, exception: " + exception.Message); + _loggerPair.LogError("Closing dirty connection: rollback transaction in session: " + SfSession.sessionId + " failed, exception: " + exception.Message); return TransactionRollbackStatus.Failure; // connection won't be pooled } } public override void ChangeDatabase(string databaseName) { - logger.LogDebug($"ChangeDatabase to:{databaseName}"); + _loggerPair.LogDebug($"ChangeDatabase to:{databaseName}"); string alterDbCommand = $"use database {databaseName}"; @@ -184,7 +183,7 @@ public override void ChangeDatabase(string databaseName) public override void Close() { - logger.LogDebug("Close Connection."); + _loggerPair.LogDebug("Close Connection."); if (IsNonClosedWithSession()) { var returnedToPool = TryToReturnSessionToPool(); @@ -208,7 +207,7 @@ public override async Task CloseAsync() public virtual async Task CloseAsync(CancellationToken cancellationToken) { - logger.LogDebug("Close Connection."); + _loggerPair.LogDebug("Close Connection."); TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); if (cancellationToken.IsCancellationRequested) @@ -233,18 +232,18 @@ await SfSession.CloseAsync(cancellationToken).ContinueWith( if (previousTask.IsFaulted) { // Exception from SfSession.CloseAsync - logger.LogError("Error closing the session", previousTask.Exception); + _loggerPair.LogError("Error closing the session", previousTask.Exception); taskCompletionSource.SetException(previousTask.Exception); } else if (previousTask.IsCanceled) { _connectionState = ConnectionState.Closed; - logger.LogDebug("Session close canceled"); + _loggerPair.LogDebug("Session close canceled"); taskCompletionSource.SetCanceled(); } else { - logger.LogDebug("Session closed successfully"); + _loggerPair.LogDebug("Session closed successfully"); _connectionState = ConnectionState.Closed; taskCompletionSource.SetResult(null); } @@ -253,7 +252,7 @@ await SfSession.CloseAsync(cancellationToken).ContinueWith( } else { - logger.LogDebug("Session not opened. Nothing to do."); + _loggerPair.LogDebug("Session not opened. Nothing to do."); taskCompletionSource.SetResult(null); } } @@ -268,10 +267,10 @@ protected virtual bool CanReuseSession(TransactionRollbackStatus transactionRoll public override void Open() { - logger.LogDebug("Open Connection."); + _loggerPair.LogDebug("Open Connection."); if (_connectionState != ConnectionState.Closed) { - logger.LogDebug($"Open with a connection already opened: {_connectionState}"); + _loggerPair.LogDebug($"Open with a connection already opened: {_connectionState}"); return; } try @@ -281,14 +280,14 @@ public override void Open() SfSession = SnowflakeDbConnectionPool.GetSession(ConnectionString, Password); if (SfSession == null) throw new SnowflakeDbException(SFError.INTERNAL_ERROR, "Could not open session"); - logger.LogDebug($"Connection open with pooled session: {SfSession.sessionId}"); + _loggerPair.LogDebug($"Connection open with pooled session: {SfSession.sessionId}"); OnSessionEstablished(); } catch (Exception e) { // Otherwise when Dispose() is called, the close request would timeout. _connectionState = ConnectionState.Closed; - logger.LogError("Unable to connect: ", e); + _loggerPair.LogError("Unable to connect: ", e); if (e is SnowflakeDbException) { throw; @@ -311,10 +310,10 @@ internal void FillConnectionStringFromTomlConfigIfNotSet() public override Task OpenAsync(CancellationToken cancellationToken) { - logger.LogDebug("Open Connection Async."); + _loggerPair.LogDebug("Open Connection Async."); if (_connectionState != ConnectionState.Closed) { - logger.LogDebug($"Open with a connection already opened: {_connectionState}"); + _loggerPair.LogDebug($"Open with a connection already opened: {_connectionState}"); return Task.CompletedTask; } registerConnectionCancellationCallback(cancellationToken); @@ -329,7 +328,7 @@ public override Task OpenAsync(CancellationToken cancellationToken) // Exception from SfSession.OpenAsync Exception sfSessionEx = previousTask.Exception; _connectionState = ConnectionState.Closed; - logger.LogError("Unable to connect", sfSessionEx); + _loggerPair.LogError("Unable to connect", sfSessionEx); throw new SnowflakeDbException( sfSessionEx, SnowflakeDbException.CONNECTION_FAILURE_SSTATE, @@ -339,14 +338,14 @@ public override Task OpenAsync(CancellationToken cancellationToken) else if (previousTask.IsCanceled) { _connectionState = ConnectionState.Closed; - logger.LogDebug("Connection canceled"); + _loggerPair.LogDebug("Connection canceled"); throw new TaskCanceledException("Connecting was cancelled"); } else { // Only continue if the session was opened successfully SfSession = previousTask.Result; - logger.LogDebug($"Connection open with pooled session: {SfSession.sessionId}"); + _loggerPair.LogDebug($"Connection open with pooled session: {SfSession.sessionId}"); OnSessionEstablished(); } }, TaskContinuationOptions.None); // this continuation should be executed always (even if the whole operation was canceled) because it sets the proper state of the connection @@ -410,7 +409,7 @@ protected override void Dispose(bool disposing) catch (Exception ex) { // Prevent an exception from being thrown when disposing of this object - logger.LogError("Unable to close connection", ex); + _loggerPair.LogError("Unable to close connection", ex); } } else diff --git a/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs b/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs index c5066ec3b..ee33b276e 100644 --- a/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs @@ -10,13 +10,12 @@ using Snowflake.Data.Core.Session; using Snowflake.Data.Core.Tools; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Client { public class SnowflakeDbConnectionPool { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private static readonly Object s_connectionManagerInstanceLock = new Object(); private static IConnectionManager s_connectionManager; internal const ConnectionPoolType DefaultConnectionPoolType = ConnectionPoolType.MultipleConnectionPool; @@ -34,91 +33,91 @@ private static IConnectionManager ConnectionManager internal static SFSession GetSession(string connectionString, SecureString password) { - s_logger.LogDebug($"SnowflakeDbConnectionPool::GetSession"); + s_loggerPair.LogDebug($"SnowflakeDbConnectionPool::GetSession"); return ConnectionManager.GetSession(connectionString, password); } internal static Task GetSessionAsync(string connectionString, SecureString password, CancellationToken cancellationToken) { - s_logger.LogDebug($"SnowflakeDbConnectionPool::GetSessionAsync"); + s_loggerPair.LogDebug($"SnowflakeDbConnectionPool::GetSessionAsync"); return ConnectionManager.GetSessionAsync(connectionString, password, cancellationToken); } public static SnowflakeDbSessionPool GetPool(string connectionString, SecureString password) { - s_logger.LogDebug($"SnowflakeDbConnectionPool::GetPool"); + s_loggerPair.LogDebug($"SnowflakeDbConnectionPool::GetPool"); return new SnowflakeDbSessionPool(ConnectionManager.GetPool(connectionString, password)); } public static SnowflakeDbSessionPool GetPool(string connectionString) { - s_logger.LogDebug($"SnowflakeDbConnectionPool::GetPool"); + s_loggerPair.LogDebug($"SnowflakeDbConnectionPool::GetPool"); return new SnowflakeDbSessionPool(ConnectionManager.GetPool(connectionString)); } internal static SessionPool GetPoolInternal(string connectionString) { - s_logger.LogDebug($"SnowflakeDbConnectionPool::GetPoolInternal"); + s_loggerPair.LogDebug($"SnowflakeDbConnectionPool::GetPoolInternal"); return ConnectionManager.GetPool(connectionString); } internal static bool AddSession(SFSession session) { - s_logger.LogDebug("SnowflakeDbConnectionPool::AddSession"); + s_loggerPair.LogDebug("SnowflakeDbConnectionPool::AddSession"); return ConnectionManager.AddSession(session); } internal static void ReleaseBusySession(SFSession session) { - s_logger.LogDebug("SnowflakeDbConnectionPool::ReleaseBusySession"); + s_loggerPair.LogDebug("SnowflakeDbConnectionPool::ReleaseBusySession"); ConnectionManager.ReleaseBusySession(session); } public static void ClearAllPools() { - s_logger.LogDebug("SnowflakeDbConnectionPool::ClearAllPools"); + s_loggerPair.LogDebug("SnowflakeDbConnectionPool::ClearAllPools"); ConnectionManager.ClearAllPools(); } public static void SetMaxPoolSize(int maxPoolSize) { - s_logger.LogDebug("SnowflakeDbConnectionPool::SetMaxPoolSize"); + s_loggerPair.LogDebug("SnowflakeDbConnectionPool::SetMaxPoolSize"); ConnectionManager.SetMaxPoolSize(maxPoolSize); } public static int GetMaxPoolSize() { - s_logger.LogDebug("SnowflakeDbConnectionPool::GetMaxPoolSize"); + s_loggerPair.LogDebug("SnowflakeDbConnectionPool::GetMaxPoolSize"); return ConnectionManager.GetMaxPoolSize(); } public static void SetTimeout(long connectionTimeout) { - s_logger.LogDebug("SnowflakeDbConnectionPool::SetTimeout"); + s_loggerPair.LogDebug("SnowflakeDbConnectionPool::SetTimeout"); ConnectionManager.SetTimeout(connectionTimeout); } public static long GetTimeout() { - s_logger.LogDebug("SnowflakeDbConnectionPool::GetTimeout"); + s_loggerPair.LogDebug("SnowflakeDbConnectionPool::GetTimeout"); return ConnectionManager.GetTimeout(); } public static int GetCurrentPoolSize() { - s_logger.LogDebug("SnowflakeDbConnectionPool::GetCurrentPoolSize"); + s_loggerPair.LogDebug("SnowflakeDbConnectionPool::GetCurrentPoolSize"); return ConnectionManager.GetCurrentPoolSize(); } public static bool SetPooling(bool isEnable) { - s_logger.LogDebug("SnowflakeDbConnectionPool::SetPooling"); + s_loggerPair.LogDebug("SnowflakeDbConnectionPool::SetPooling"); return ConnectionManager.SetPooling(isEnable); } public static bool GetPooling() { - s_logger.LogDebug("SnowflakeDbConnectionPool::GetPooling"); + s_loggerPair.LogDebug("SnowflakeDbConnectionPool::GetPooling"); return ConnectionManager.GetPooling(); } @@ -138,12 +137,12 @@ private static void SetConnectionPoolVersion(ConnectionPoolType requestedPoolTyp if (requestedPoolType == ConnectionPoolType.MultipleConnectionPool) { s_connectionManager = new ConnectionPoolManager(); - s_logger.LogInformation("SnowflakeDbConnectionPool - multiple connection pools enabled"); + s_loggerPair.LogInformation("SnowflakeDbConnectionPool - multiple connection pools enabled"); } if (requestedPoolType == ConnectionPoolType.SingleConnectionCache) { s_connectionManager = new ConnectionCacheManager(); - s_logger.LogWarning("SnowflakeDbConnectionPool - connection cache enabled"); + s_loggerPair.LogWarning("SnowflakeDbConnectionPool - connection cache enabled"); } } } diff --git a/Snowflake.Data/Client/SnowflakeDbDataReader.cs b/Snowflake.Data/Client/SnowflakeDbDataReader.cs index 5d5453f9d..5e0bd6de7 100755 --- a/Snowflake.Data/Client/SnowflakeDbDataReader.cs +++ b/Snowflake.Data/Client/SnowflakeDbDataReader.cs @@ -13,13 +13,12 @@ using Snowflake.Data.Log; using Newtonsoft.Json.Linq; using Snowflake.Data.Core.Converter; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Client { public class SnowflakeDbDataReader : DbDataReader { - static private readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + static private readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private SnowflakeDbCommand dbCommand; diff --git a/Snowflake.Data/Client/SnowflakeDbTransaction.cs b/Snowflake.Data/Client/SnowflakeDbTransaction.cs index e15adc69f..53815c61b 100755 --- a/Snowflake.Data/Client/SnowflakeDbTransaction.cs +++ b/Snowflake.Data/Client/SnowflakeDbTransaction.cs @@ -7,13 +7,12 @@ using System.Data.Common; using Snowflake.Data.Core; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Client { public class SnowflakeDbTransaction : DbTransaction { - private ILogger logger = SFLoggerFactory.GetCustomLogger(); + private SFLoggerPair _loggerPair = SFLoggerPair.GetLoggerPair(); private IsolationLevel isolationLevel; @@ -26,19 +25,19 @@ public class SnowflakeDbTransaction : DbTransaction public SnowflakeDbTransaction(IsolationLevel isolationLevel, SnowflakeDbConnection connection) { - logger.LogDebug("Begin transaction."); + _loggerPair.LogDebug("Begin transaction."); if (isolationLevel != IsolationLevel.ReadCommitted) { throw new SnowflakeDbException(SFError.UNSUPPORTED_FEATURE); } if (connection == null) { - logger.LogError("Transaction cannot be started for an unknown connection"); + _loggerPair.LogError("Transaction cannot be started for an unknown connection"); throw new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY); } if (!connection.IsOpen()) { - logger.LogError("Transaction cannot be started for a closed connection"); + _loggerPair.LogError("Transaction cannot be started for a closed connection"); throw new SnowflakeDbException(SFError.UNSUPPORTED_FEATURE); } @@ -72,7 +71,7 @@ protected override DbConnection DbConnection public override void Commit() { - logger.LogDebug("Commit transaction."); + _loggerPair.LogDebug("Commit transaction."); if (!isCommittedOrRollbacked) { using (IDbCommand command = connection.CreateCommand()) @@ -86,7 +85,7 @@ public override void Commit() public override void Rollback() { - logger.LogDebug("Rollback transaction."); + _loggerPair.LogDebug("Rollback transaction."); if (!isCommittedOrRollbacked) { using (IDbCommand command = connection.CreateCommand()) diff --git a/Snowflake.Data/Core/ArrowResultSet.cs b/Snowflake.Data/Core/ArrowResultSet.cs index 7f2a6c88c..45fe60e16 100644 --- a/Snowflake.Data/Core/ArrowResultSet.cs +++ b/Snowflake.Data/Core/ArrowResultSet.cs @@ -10,7 +10,6 @@ using Apache.Arrow.Ipc; using Snowflake.Data.Client; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -18,7 +17,7 @@ class ArrowResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => ResultFormat.ARROW; - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private readonly int _totalChunkCount; private BaseResultChunk _currentChunk; @@ -50,7 +49,7 @@ public ArrowResultSet(QueryExecResponseData responseData, SFStatement sfStatemen } catch(Exception ex) { - s_logger.LogError("Result set error queryId="+responseData.queryId, ex); + s_loggerPair.LogError("Result set error queryId="+responseData.queryId, ex); throw; } } @@ -87,7 +86,7 @@ internal override async Task NextAsync() if (_totalChunkCount > 0) { - s_logger.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_loggerPair.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); _currentChunk = await _chunkDownloader.GetNextChunkAsync().ConfigureAwait(false); @@ -106,7 +105,7 @@ internal override bool Next() if (_totalChunkCount > 0) { - s_logger.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_loggerPair.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); _currentChunk = Task.Run(async() => await (_chunkDownloader.GetNextChunkAsync()).ConfigureAwait(false)).Result; @@ -150,7 +149,7 @@ internal override bool Rewind() if (_currentChunk.ChunkIndex > 0) { - s_logger.LogWarning("Unable to rewind to the previous chunk"); + s_loggerPair.LogWarning("Unable to rewind to the previous chunk"); } return false; diff --git a/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs b/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs index 060c88207..e8e717ee6 100644 --- a/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs @@ -1,18 +1,17 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ using Snowflake.Data.Log; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { class BasicAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "snowflake"; - private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); internal BasicAuthenticator(SFSession session) : base(session, AUTH_NAME) { diff --git a/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs b/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs index 86b4e00f4..c01ffb1e4 100644 --- a/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -13,7 +13,6 @@ using Snowflake.Data.Client; using System.Text.RegularExpressions; using System.Collections.Generic; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { @@ -23,7 +22,7 @@ namespace Snowflake.Data.Core.Authenticator class ExternalBrowserAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "externalbrowser"; - private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private static readonly string TOKEN_REQUEST_PREFIX = "?token="; private static readonly byte[] SUCCESS_RESPONSE = System.Text.Encoding.UTF8.GetBytes( "" + @@ -48,14 +47,14 @@ internal ExternalBrowserAuthenticator(SFSession session) : base(session, AUTH_NA /// async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) { - logger.LogInformation("External Browser Authentication"); + s_loggerPair.LogInformation("External Browser Authentication"); int localPort = GetRandomUnusedPort(); using (var httpListener = GetHttpListener(localPort)) { httpListener.Start(); - logger.LogDebug("Get IdpUrl and ProofKey"); + s_loggerPair.LogDebug("Get IdpUrl and ProofKey"); string loginUrl; if (session._disableConsoleLogin) { @@ -76,37 +75,37 @@ await session.restRequester.PostAsync( loginUrl = GetLoginUrl(_proofKey, localPort); } - logger.LogDebug("Open browser"); + s_loggerPair.LogDebug("Open browser"); StartBrowser(loginUrl); - logger.LogDebug("Get the redirect SAML request"); + s_loggerPair.LogDebug("Get the redirect SAML request"); _successEvent = new ManualResetEvent(false); httpListener.BeginGetContext(GetContextCallback, httpListener); var timeoutInSec = int.Parse(session.properties[SFSessionProperty.BROWSER_RESPONSE_TIMEOUT]); if (!_successEvent.WaitOne(timeoutInSec * 1000)) { - logger.LogWarning("Browser response timeout"); + s_loggerPair.LogWarning("Browser response timeout"); throw new SnowflakeDbException(SFError.BROWSER_RESPONSE_TIMEOUT, timeoutInSec); } httpListener.Stop(); } - logger.LogDebug("Send login request"); + s_loggerPair.LogDebug("Send login request"); await base.LoginAsync(cancellationToken).ConfigureAwait(false); } /// void IAuthenticator.Authenticate() { - logger.LogInformation("External Browser Authentication"); + s_loggerPair.LogInformation("External Browser Authentication"); int localPort = GetRandomUnusedPort(); using (var httpListener = GetHttpListener(localPort)) { httpListener.Start(); - logger.LogDebug("Get IdpUrl and ProofKey"); + s_loggerPair.LogDebug("Get IdpUrl and ProofKey"); string loginUrl; if (session._disableConsoleLogin) { @@ -123,23 +122,23 @@ void IAuthenticator.Authenticate() loginUrl = GetLoginUrl(_proofKey, localPort); } - logger.LogDebug("Open browser"); + s_loggerPair.LogDebug("Open browser"); StartBrowser(loginUrl); - logger.LogDebug("Get the redirect SAML request"); + s_loggerPair.LogDebug("Get the redirect SAML request"); _successEvent = new ManualResetEvent(false); httpListener.BeginGetContext(GetContextCallback, httpListener); var timeoutInSec = int.Parse(session.properties[SFSessionProperty.BROWSER_RESPONSE_TIMEOUT]); if (!_successEvent.WaitOne(timeoutInSec * 1000)) { - logger.LogWarning("Browser response timeout"); + s_loggerPair.LogWarning("Browser response timeout"); throw new SnowflakeDbException(SFError.BROWSER_RESPONSE_TIMEOUT, timeoutInSec); } httpListener.Stop(); } - logger.LogDebug("Send login request"); + s_loggerPair.LogDebug("Send login request"); base.Login(); } @@ -164,7 +163,7 @@ private void GetContextCallback(IAsyncResult result) catch { // Ignore the exception as it does not affect the overall authentication flow - logger.LogWarning("External browser response not sent out"); + s_loggerPair.LogWarning("External browser response not sent out"); } } @@ -194,13 +193,13 @@ private static void StartBrowser(string url) Match m = Regex.Match(url, regexStr, RegexOptions.IgnoreCase); if (!m.Success) { - logger.LogError("Failed to start browser. Invalid url."); + s_loggerPair.LogError("Failed to start browser. Invalid url."); throw new SnowflakeDbException(SFError.INVALID_BROWSER_URL); } if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) { - logger.LogError("Failed to start browser. Invalid url."); + s_loggerPair.LogError("Failed to start browser. Invalid url."); throw new SnowflakeDbException(SFError.INVALID_BROWSER_URL); } diff --git a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs index d7e0a0cc9..52e3f42cd 100644 --- a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved. */ @@ -7,7 +7,6 @@ using System.Threading.Tasks; using Snowflake.Data.Client; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { @@ -46,8 +45,8 @@ internal enum SFAuthenticatorType internal abstract class BaseAuthenticator { // The logger. - private static readonly ILogger logger = - SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = + SFLoggerPair.GetLoggerPair(); // The name of the authenticator. private string authName; @@ -135,7 +134,7 @@ private SFRestRequest BuildLoginRequest() /// internal class AuthenticatorFactory { - private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); /// /// Generate the authenticator given the session /// @@ -165,7 +164,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) var error = new SnowflakeDbException( SFError.INVALID_CONNECTION_STRING, new object[] { invalidStringDetail }); - logger.LogError(error.Message, error); + s_loggerPair.LogError(error.Message, error); throw error; } @@ -182,7 +181,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) var error = new SnowflakeDbException( SFError.INVALID_CONNECTION_STRING, new object[] { invalidStringDetail }); - logger.LogError(error.Message, error); + s_loggerPair.LogError(error.Message, error); throw error; } @@ -193,7 +192,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) { return new OktaAuthenticator(session, type); } - logger.LogError($"Unknown authenticator {type}"); + s_loggerPair.LogError($"Unknown authenticator {type}"); throw new SnowflakeDbException(SFError.UNKNOWN_AUTHENTICATOR, type); } } diff --git a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs index e26a75ad2..d32a9d7b1 100644 --- a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved. */ @@ -19,7 +19,6 @@ using Org.BouncyCastle.X509; using System.Security.Claims; using Microsoft.IdentityModel.Tokens; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { @@ -33,8 +32,8 @@ class KeyPairAuthenticator : BaseAuthenticator, IAuthenticator public const string AUTH_NAME = "snowflake_jwt"; // The logger. - private static readonly ILogger logger = - SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = + SFLoggerPair.GetLoggerPair(); // The RSA provider to use to sign the tokens private RSACryptoServiceProvider rsaProvider; @@ -58,7 +57,7 @@ async public Task AuthenticateAsync(CancellationToken cancellationToken) jwtToken = GenerateJwtToken(); // Send the http request with the generate token - logger.LogDebug("Send login request"); + s_loggerPair.LogDebug("Send login request"); await base.LoginAsync(cancellationToken).ConfigureAwait(false); } @@ -68,7 +67,7 @@ public void Authenticate() jwtToken = GenerateJwtToken(); // Send the http request with the generate token - logger.LogDebug("Send login request"); + s_loggerPair.LogDebug("Send login request"); base.Login(); } @@ -85,7 +84,7 @@ protected override void SetSpecializedAuthenticatorData(ref LoginRequestData dat /// The generated JWT token. private string GenerateJwtToken() { - logger.LogInformation("Key-pair Authentication"); + s_loggerPair.LogInformation("Key-pair Authentication"); bool hasPkPath = session.properties.TryGetValue(SFSessionProperty.PRIVATE_KEY_FILE, out var pkPath); diff --git a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs index c8ee881ce..e7ea5c034 100644 --- a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs @@ -4,7 +4,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { @@ -18,8 +17,8 @@ class OAuthAuthenticator : BaseAuthenticator, IAuthenticator public const string AUTH_NAME = "oauth"; // The logger. - private static readonly ILogger logger = - SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = + SFLoggerPair.GetLoggerPair(); /// /// Constructor for the oauth authenticator. diff --git a/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs b/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs index ec19475c6..21509cb60 100644 --- a/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs @@ -14,7 +14,6 @@ using System.Web; using System.Linq; using Snowflake.Data.Core.Tools; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Authenticator { @@ -24,7 +23,7 @@ namespace Snowflake.Data.Core.Authenticator class OktaAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "okta"; - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); internal const string RetryCountHeader = "RetryCount"; internal const string TimeoutElapsedHeader = "TimeoutElapsed"; @@ -50,19 +49,19 @@ internal OktaAuthenticator(SFSession session, string oktaUriString) : /// async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) { - s_logger.LogInformation("Okta Authentication"); + s_loggerPair.LogInformation("Okta Authentication"); - s_logger.LogDebug("step 1: Get SSO and token URL"); + s_loggerPair.LogDebug("step 1: Get SSO and token URL"); var authenticatorRestRequest = BuildAuthenticatorRestRequest(); var authenticatorResponse = await session.restRequester.PostAsync(authenticatorRestRequest, cancellationToken).ConfigureAwait(false); authenticatorResponse.FilterFailedResponse(); Uri ssoUrl = new Uri(authenticatorResponse.data.ssoUrl); Uri tokenUrl = new Uri(authenticatorResponse.data.tokenUrl); - s_logger.LogDebug("step 2: Verify URLs fetched from step 1"); - s_logger.LogDebug("Checking SSO Okta URL"); + s_loggerPair.LogDebug("step 2: Verify URLs fetched from step 1"); + s_loggerPair.LogDebug("Checking SSO Okta URL"); VerifyUrls(ssoUrl, _oktaUrl); - s_logger.LogDebug("Checking token URL"); + s_loggerPair.LogDebug("Checking token URL"); VerifyUrls(tokenUrl, _oktaUrl); int retryCount = 0; @@ -75,26 +74,26 @@ async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) { try { - s_logger.LogDebug("step 3: Get IdP one-time token"); + s_loggerPair.LogDebug("step 3: Get IdP one-time token"); IdpTokenRestRequest idpTokenRestRequest = BuildIdpTokenRestRequest(tokenUrl); var idpResponse = await session.restRequester.PostAsync(idpTokenRestRequest, cancellationToken).ConfigureAwait(false); string onetimeToken = idpResponse.SessionToken ?? idpResponse.CookieToken; - s_logger.LogDebug("step 4: Get SAML response from SSO"); + s_loggerPair.LogDebug("step 4: Get SAML response from SSO"); var samlRestRequest = BuildSamlRestRequest(ssoUrl, onetimeToken); samlRawResponse = await session.restRequester.GetAsync(samlRestRequest, cancellationToken).ConfigureAwait(false); _rawSamlTokenHtmlString = await samlRawResponse.Content.ReadAsStringAsync().ConfigureAwait(false); - s_logger.LogDebug("step 5: Verify postback URL in SAML response"); + s_loggerPair.LogDebug("step 5: Verify postback URL in SAML response"); if (!session._disableSamlUrlCheck) { VerifyPostbackUrl(); } else { - s_logger.LogDebug("The saml url check is disabled. Skipping step 5"); + s_loggerPair.LogDebug("The saml url check is disabled. Skipping step 5"); } - s_logger.LogDebug("step 6: Send SAML response to Snowflake to login"); + s_loggerPair.LogDebug("step 6: Send SAML response to Snowflake to login"); await LoginAsync(cancellationToken).ConfigureAwait(false); return; } @@ -116,19 +115,19 @@ async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) void IAuthenticator.Authenticate() { - s_logger.LogInformation("Okta Authentication"); + s_loggerPair.LogInformation("Okta Authentication"); - s_logger.LogDebug("step 1: Get SSO and token URL"); + s_loggerPair.LogDebug("step 1: Get SSO and token URL"); var authenticatorRestRequest = BuildAuthenticatorRestRequest(); var authenticatorResponse = session.restRequester.Post(authenticatorRestRequest); authenticatorResponse.FilterFailedResponse(); Uri ssoUrl = new Uri(authenticatorResponse.data.ssoUrl); Uri tokenUrl = new Uri(authenticatorResponse.data.tokenUrl); - s_logger.LogDebug("step 2: Verify URLs fetched from step 1"); - s_logger.LogDebug("Checking SSO Okta URL"); + s_loggerPair.LogDebug("step 2: Verify URLs fetched from step 1"); + s_loggerPair.LogDebug("Checking SSO Okta URL"); VerifyUrls(ssoUrl, _oktaUrl); - s_logger.LogDebug("Checking token URL"); + s_loggerPair.LogDebug("Checking token URL"); VerifyUrls(tokenUrl, _oktaUrl); int retryCount = 0; @@ -141,27 +140,27 @@ void IAuthenticator.Authenticate() { try { - s_logger.LogDebug("step 3: Get IdP one-time token"); + s_loggerPair.LogDebug("step 3: Get IdP one-time token"); IdpTokenRestRequest idpTokenRestRequest = BuildIdpTokenRestRequest(tokenUrl); var idpResponse = session.restRequester.Post(idpTokenRestRequest); string onetimeToken = idpResponse.SessionToken ?? idpResponse.CookieToken; - s_logger.LogDebug("step 4: Get SAML response from SSO"); + s_loggerPair.LogDebug("step 4: Get SAML response from SSO"); var samlRestRequest = BuildSamlRestRequest(ssoUrl, onetimeToken); samlRawResponse = session.restRequester.Get(samlRestRequest); _rawSamlTokenHtmlString = Task.Run(async () => await samlRawResponse.Content.ReadAsStringAsync().ConfigureAwait(false)).Result; - s_logger.LogDebug("step 5: Verify postback URL in SAML response"); + s_loggerPair.LogDebug("step 5: Verify postback URL in SAML response"); if (!session._disableSamlUrlCheck) { VerifyPostbackUrl(); } else { - s_logger.LogDebug("The saml url check is disabled. Skipping step 5"); + s_loggerPair.LogDebug("The saml url check is disabled. Skipping step 5"); } - s_logger.LogDebug("step 6: Send SAML response to Snowflake to login"); + s_loggerPair.LogDebug("step 6: Send SAML response to Snowflake to login"); Login(); return; } @@ -185,12 +184,12 @@ private void HandleAuthenticatorException(Exception ex, HttpResponseMessage saml { if (IsPostbackUrlNotFound(ex)) { - s_logger.LogDebug("Refreshing token for Okta re-authentication and starting from step 3 again"); + s_loggerPair.LogDebug("Refreshing token for Okta re-authentication and starting from step 3 again"); if (samlRawResponse is null) { var errorNullSamlResponse = "Failure getting SAML response from Okta SSO"; - s_logger.LogError(errorNullSamlResponse); + s_loggerPair.LogError(errorNullSamlResponse); throw new SnowflakeDbException(ex, SFError.IDP_SAML_POSTBACK_INVALID); } @@ -200,7 +199,7 @@ private void HandleAuthenticatorException(Exception ex, HttpResponseMessage saml } else { - s_logger.LogError("Failed to get the correct SAML response from Okta SSO", ex); + s_loggerPair.LogError("Failed to get the correct SAML response from Okta SSO", ex); throw ex; } } @@ -257,7 +256,7 @@ private void VerifyUrls(Uri tokenOrSsoUrl, Uri sessionUrl) { var e = new SnowflakeDbException( SFError.IDP_SSO_TOKEN_URL_MISMATCH, tokenOrSsoUrl.ToString(), _oktaUrl.ToString()); - s_logger.LogError("Different urls", e); + s_loggerPair.LogError("Different urls", e); throw e; } } @@ -276,7 +275,7 @@ private void VerifyPostbackUrl() postBackUrl = new Uri(HttpUtility.HtmlDecode(_rawSamlTokenHtmlString.Substring(startIndex, length))); } catch (Exception e) { - s_logger.LogError("Fail to extract SAML from html", e); + s_loggerPair.LogError("Fail to extract SAML from html", e); throw new SnowflakeDbException(e, SFError.IDP_SAML_POSTBACK_NOTFOUND); } @@ -289,7 +288,7 @@ private void VerifyPostbackUrl() SFError.IDP_SAML_POSTBACK_INVALID, postBackUrl.ToString(), sessionScheme + ":\\\\" + sessionHost); - s_logger.LogError("Different urls", e); + s_loggerPair.LogError("Different urls", e); throw e; } } @@ -325,7 +324,7 @@ private void ThrowRetryLimitException(int retryCount, int timeoutElapsed, Except } errorMessage += " while trying to authenticate through Okta"; - s_logger.LogError(errorMessage); + s_loggerPair.LogError(errorMessage); throw new SnowflakeDbException(lastRetryException, SFError.INTERNAL_ERROR, errorMessage); } } diff --git a/Snowflake.Data/Core/ChunkDownloaderFactory.cs b/Snowflake.Data/Core/ChunkDownloaderFactory.cs index 8836e142f..b0373bcc3 100755 --- a/Snowflake.Data/Core/ChunkDownloaderFactory.cs +++ b/Snowflake.Data/Core/ChunkDownloaderFactory.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -6,13 +6,12 @@ using System.Threading; using Snowflake.Data.Configuration; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { class ChunkDownloaderFactory { - private static ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); public static IChunkDownloader GetDownloader(QueryExecResponseData responseData, SFBaseResultSet resultSet, CancellationToken cancellationToken) @@ -20,7 +19,7 @@ public static IChunkDownloader GetDownloader(QueryExecResponseData responseData, switch (SFConfiguration.Instance().GetChunkDownloaderVersion()) { case 1: - s_logger.LogWarning("V1 version of ChunkDownloader is deprecated. Using the V3 version."); + s_loggerPair.LogWarning("V1 version of ChunkDownloader is deprecated. Using the V3 version."); return new SFBlockingChunkDownloaderV3(responseData.rowType.Count, responseData.chunks, responseData.qrmk, @@ -29,7 +28,7 @@ public static IChunkDownloader GetDownloader(QueryExecResponseData responseData, resultSet, responseData.queryResultFormat); case 2: - s_logger.LogWarning("V2 version of ChunkDownloader is deprecated. Using the V3 version."); + s_loggerPair.LogWarning("V2 version of ChunkDownloader is deprecated. Using the V3 version."); return new SFBlockingChunkDownloaderV3(responseData.rowType.Count, responseData.chunks, responseData.qrmk, diff --git a/Snowflake.Data/Core/ChunkParserFactory.cs b/Snowflake.Data/Core/ChunkParserFactory.cs index 8521ca84f..05cdedd03 100755 --- a/Snowflake.Data/Core/ChunkParserFactory.cs +++ b/Snowflake.Data/Core/ChunkParserFactory.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -6,13 +6,12 @@ using System.IO; using Snowflake.Data.Configuration; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { class ChunkParserFactory : IChunkParserFactory { - private static ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); public static IChunkParserFactory Instance = new ChunkParserFactory(); public IChunkParser GetParser(ResultFormat resultFormat, Stream stream) @@ -23,10 +22,10 @@ public IChunkParser GetParser(ResultFormat resultFormat, Stream stream) switch (SFConfiguration.Instance().GetChunkParserVersion()) { case 1: - s_logger.LogWarning("V1 version of ChunkParser is deprecated. Using the V3 version."); + s_loggerPair.LogWarning("V1 version of ChunkParser is deprecated. Using the V3 version."); return new ReusableChunkParser(stream); case 2: - s_logger.LogWarning("V2 version of ChunkParser is deprecated. Using the V3 version."); + s_loggerPair.LogWarning("V2 version of ChunkParser is deprecated. Using the V3 version."); return new ReusableChunkParser(stream); case 3: return new ReusableChunkParser(stream); diff --git a/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs b/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs index a8645390a..c7e67a92f 100644 --- a/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs +++ b/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs @@ -1,22 +1,21 @@ using System; using Snowflake.Data.Client; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Converter { public class StructuredTypesReadingHandler { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); public static SnowflakeDbException ToSnowflakeDbException(Exception exception, string context) { if (exception is StructuredTypesReadingException) { - s_logger.LogDebug("Exception caught when reading structured types", exception); + s_loggerPair.LogDebug("Exception caught when reading structured types", exception); return new SnowflakeDbException(SFError.STRUCTURED_TYPE_READ_DETAILED_ERROR, context, exception.Message); } - s_logger.LogDebug("Exception caught when reading structured types"); + s_loggerPair.LogDebug("Exception caught when reading structured types"); return new SnowflakeDbException(SFError.STRUCTURED_TYPE_READ_ERROR, context); } } diff --git a/Snowflake.Data/Core/FastParser.cs b/Snowflake.Data/Core/FastParser.cs index 2b9a0d470..cebd18f39 100644 --- a/Snowflake.Data/Core/FastParser.cs +++ b/Snowflake.Data/Core/FastParser.cs @@ -1,20 +1,19 @@ using System; using Snowflake.Data.Client; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { public class FastParser { - private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); public static Int64 FastParseInt64(byte[] s, int offset, int len) { if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - logger.LogError("A null buffer was passed to FastParseInt64", ex); + s_loggerPair.LogError("A null buffer was passed to FastParseInt64", ex); throw ex; } @@ -55,7 +54,7 @@ public static Int32 FastParseInt32(byte[] s, int offset, int len) if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - logger.LogError("A null buffer was passed to FastParseInt32", ex); + s_loggerPair.LogError("A null buffer was passed to FastParseInt32", ex); throw ex; } @@ -96,7 +95,7 @@ public static decimal FastParseDecimal(byte[] s, int offset, int len) if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - logger.LogError("A null buffer was passed to FastParseDecimal", ex); + s_loggerPair.LogError("A null buffer was passed to FastParseDecimal", ex); throw ex; } diff --git a/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs b/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs index 3e2194c19..6dc3bea48 100644 --- a/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs +++ b/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. */ @@ -6,7 +6,6 @@ using System; using Snowflake.Data.Log; using System.Security.Cryptography; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.FileTransfer { @@ -23,7 +22,7 @@ class EncryptionProvider /// /// The logger. /// - private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); /// /// Encrypt data and write to the outStream. @@ -61,7 +60,7 @@ public static StreamPair EncryptStream( { byte[] decodedMasterKey = Convert.FromBase64String(encryptionMaterial.queryStageMasterKey); int masterKeySize = decodedMasterKey.Length; - logger.LogDebug($"Master key size : {masterKeySize}"); + s_loggerPair.LogDebug($"Master key size : {masterKeySize}"); // Generate file key byte[] ivData = new byte[blockSize]; diff --git a/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs b/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs index e334d5894..82aa9e42e 100644 --- a/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs +++ b/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using Microsoft.Extensions.Logging; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.IO; using Org.BouncyCastle.Crypto.Parameters; @@ -16,7 +15,7 @@ internal class GcmEncryptionProvider private const int InitVectorSizeInBytes = 12; private const string AesGcmNoPaddingCipher = "AES/GCM/NoPadding"; - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private static readonly SecureRandom s_random = SecureRandom.GetInstance("SHA1PRNG"); @@ -57,7 +56,7 @@ public static Stream Encrypt( { byte[] decodedMasterKey = Convert.FromBase64String(encryptionMaterial.queryStageMasterKey); int masterKeySize = decodedMasterKey.Length; - s_logger.LogDebug($"Master key size : {masterKeySize}"); + s_loggerPair.LogDebug($"Master key size : {masterKeySize}"); var contentIV = new byte[InitVectorSizeInBytes]; var keyIV = new byte[InitVectorSizeInBytes]; diff --git a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs index 9b7d99973..f9b705d30 100644 --- a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs +++ b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 Snowflake Computing Inc. All rights reserved. */ @@ -14,7 +14,6 @@ using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -61,7 +60,7 @@ class SFFileTransferAgent /// /// The logger. /// - private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); /// /// Auto-detect keyword for source compression type auto detection. @@ -231,7 +230,7 @@ public void execute() } catch (Exception e) { - logger.LogError("Error while transferring file(s): " + e.Message); + s_loggerPair.LogError("Error while transferring file(s): " + e.Message); if (e is SnowflakeDbException snowflakeException) { if (snowflakeException.QueryId == null) @@ -347,19 +346,19 @@ private void upload() //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - logger.LogDebug("Start uploading large files"); + s_loggerPair.LogDebug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { UploadFilesInSequential(fileMetadata); } - logger.LogDebug("End uploading large files"); + s_loggerPair.LogDebug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - logger.LogDebug("Start uploading small files"); + s_loggerPair.LogDebug("Start uploading small files"); UploadFilesInParallel(SmallFilesMetas, TransferMetadata.parallel); - logger.LogDebug("End uploading small files"); + s_loggerPair.LogDebug("End uploading small files"); } } @@ -373,19 +372,19 @@ private async Task uploadAsync(CancellationToken cancellationToken) //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - logger.LogDebug("Start uploading large files"); + s_loggerPair.LogDebug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { await UploadFilesInSequentialAsync(fileMetadata, cancellationToken).ConfigureAwait(false); } - logger.LogDebug("End uploading large files"); + s_loggerPair.LogDebug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - logger.LogDebug("Start uploading small files"); + s_loggerPair.LogDebug("Start uploading small files"); await UploadFilesInParallelAsync(SmallFilesMetas, TransferMetadata.parallel, cancellationToken).ConfigureAwait(false); - logger.LogDebug("End uploading small files"); + s_loggerPair.LogDebug("End uploading small files"); } } @@ -400,18 +399,18 @@ private void download() //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - logger.LogDebug("Start uploading large files"); + s_loggerPair.LogDebug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { DownloadFilesInSequential(fileMetadata); } - logger.LogDebug("End uploading large files"); + s_loggerPair.LogDebug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - logger.LogDebug("Start uploading small files"); + s_loggerPair.LogDebug("Start uploading small files"); DownloadFilesInParallel(SmallFilesMetas, TransferMetadata.parallel); - logger.LogDebug("End uploading small files"); + s_loggerPair.LogDebug("End uploading small files"); } } @@ -425,18 +424,18 @@ private async Task downloadAsync(CancellationToken cancellationToken) //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - logger.LogDebug("Start uploading large files"); + s_loggerPair.LogDebug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { await DownloadFilesInSequentialAsync(fileMetadata, cancellationToken).ConfigureAwait(false); } - logger.LogDebug("End uploading large files"); + s_loggerPair.LogDebug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - logger.LogDebug("Start uploading small files"); + s_loggerPair.LogDebug("Start uploading small files"); await DownloadFilesInParallelAsync(SmallFilesMetas, TransferMetadata.parallel, cancellationToken).ConfigureAwait(false); - logger.LogDebug("End uploading small files"); + s_loggerPair.LogDebug("End uploading small files"); } } @@ -575,7 +574,7 @@ private void initFileMetadata( // Auto-detect source compression type // Will return NONE if no matching type is found compressionType = SFFileCompressionTypes.GuessCompressionType(file); - logger.LogDebug($"File compression detected as {compressionType.Name} for: {file}"); + s_loggerPair.LogDebug($"File compression detected as {compressionType.Name} for: {file}"); } else { @@ -717,7 +716,7 @@ private int GetFileTransferMaxBytesInMemory() } catch (Exception) { - logger.LogWarning("Default for FILE_TRANSFER_MEMORY_THRESHOLD used due to invalid session value."); + s_loggerPair.LogWarning("Default for FILE_TRANSFER_MEMORY_THRESHOLD used due to invalid session value."); return FileTransferConfiguration.DefaultMaxBytesInMemory; } } @@ -783,12 +782,12 @@ private List expandFileNames(string location) } } - if (logger.IsEnabled(LogLevel.Debug)) + if (s_loggerPair.IsDebugEnabled()) { - logger.LogDebug("Expand " + location + " into: "); + s_loggerPair.LogDebug("Expand " + location + " into: "); foreach (var filepath in filePaths) { - logger.LogDebug("\t" + filepath ); + s_loggerPair.LogDebug("\t" + filepath ); } } @@ -902,7 +901,7 @@ private void compressFileWithGzip(SFFileMetadata fileMetadata) } } - logger.LogDebug($"Compressed {fileToCompress.Name} to {fileMetadata.realSrcFilePath}"); + s_loggerPair.LogDebug($"Compressed {fileToCompress.Name} to {fileMetadata.realSrcFilePath}"); FileInfo destInfo = new FileInfo(fileMetadata.realSrcFilePath); fileMetadata.destFileSize = destInfo.Length; } @@ -1236,7 +1235,7 @@ private SFFileMetadata UploadSingleFile( } catch (Exception ex) { - logger.LogDebug("Unhandled exception while uploading file.", ex); + s_loggerPair.LogDebug("Unhandled exception while uploading file.", ex); throw; } finally @@ -1285,7 +1284,7 @@ private async Task UploadSingleFileAsync( } catch (Exception ex) { - logger.LogError("UploadSingleFileAsync encountered an error: " + ex.Message); + s_loggerPair.LogError("UploadSingleFileAsync encountered an error: " + ex.Message); throw; } finally @@ -1323,7 +1322,7 @@ private SFFileMetadata DownloadSingleFile( } catch (Exception ex) { - logger.LogError("DownloadSingleFile encountered an error: " + ex.Message); + s_loggerPair.LogError("DownloadSingleFile encountered an error: " + ex.Message); throw; } finally @@ -1361,7 +1360,7 @@ private async Task DownloadSingleFileAsync( } catch (Exception ex) { - logger.LogError("DownloadSingleFileAsync encountered an error: " + ex.Message); + s_loggerPair.LogError("DownloadSingleFileAsync encountered an error: " + ex.Message); throw; } finally diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs index 303086cfc..38e16b18f 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs @@ -12,7 +12,6 @@ using System.Net; using Google.Apis.Storage.v1; using Google.Cloud.Storage.V1; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.FileTransfer.StorageClient { @@ -43,7 +42,7 @@ class SFGCSClient : ISFRemoteStorageClient /// /// The logger. /// - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); /// /// The storage client. @@ -63,11 +62,11 @@ class SFGCSClient : ISFRemoteStorageClient /// The command stage info. public SFGCSClient(PutGetStageInfo stageInfo) { - s_logger.LogDebug("Setting up a new GCS client "); + s_loggerPair.LogDebug("Setting up a new GCS client "); if (stageInfo.stageCredentials.TryGetValue(GCS_ACCESS_TOKEN, out string accessToken)) { - s_logger.LogDebug("Constructing client using access token"); + s_loggerPair.LogDebug("Constructing client using access token"); AccessToken = accessToken; GoogleCredential creds = GoogleCredential.FromAccessToken(accessToken, null); var storageClientBuilder = new StorageClientBuilder @@ -79,7 +78,7 @@ public SFGCSClient(PutGetStageInfo stageInfo) } else { - s_logger.LogInformation("No access token received from GS, constructing anonymous client with no encryption support"); + s_loggerPair.LogInformation("No access token received from GS, constructing anonymous client with no encryption support"); var storageClientBuilder = new StorageClientBuilder { UnauthenticatedAccess = true @@ -476,7 +475,7 @@ private void HandleDownloadResponse(HttpWebResponse response, SFFileMetadata fil /// File Metadata private SFFileMetadata HandleFileHeaderErrForPresignedUrls(WebException ex, SFFileMetadata fileMetadata) { - s_logger.LogError("Failed to get file header for presigned url: " + ex.Message); + s_loggerPair.LogError("Failed to get file header for presigned url: " + ex.Message); HttpWebResponse response = (HttpWebResponse)ex.Response; if (response.StatusCode == HttpStatusCode.Unauthorized || @@ -502,7 +501,7 @@ private SFFileMetadata HandleFileHeaderErrForPresignedUrls(WebException ex, SFFi /// File Metadata private SFFileMetadata HandleFileHeaderErrForGeneratedUrls(WebException ex, SFFileMetadata fileMetadata) { - s_logger.LogError("Failed to get file header for non-presigned url: " + ex.Message); + s_loggerPair.LogError("Failed to get file header for non-presigned url: " + ex.Message); HttpWebResponse response = (HttpWebResponse)ex.Response; if (response.StatusCode == HttpStatusCode.Unauthorized) @@ -537,7 +536,7 @@ private SFFileMetadata HandleFileHeaderErrForGeneratedUrls(WebException ex, SFFi /// File Metadata private SFFileMetadata HandleUploadFileErr(WebException ex, SFFileMetadata fileMetadata) { - s_logger.LogError("Failed to upload file: " + ex.Message); + s_loggerPair.LogError("Failed to upload file: " + ex.Message); fileMetadata.lastError = ex; @@ -571,7 +570,7 @@ private SFFileMetadata HandleUploadFileErr(WebException ex, SFFileMetadata fileM /// File Metadata private SFFileMetadata HandleDownloadFileErr(WebException ex, SFFileMetadata fileMetadata) { - s_logger.LogError("Failed to download file: " + ex.Message); + s_loggerPair.LogError("Failed to download file: " + ex.Message); fileMetadata.lastError = ex; diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs index a4f055417..160c615fd 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs @@ -13,7 +13,6 @@ using System.Net; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.FileTransfer.StorageClient { @@ -73,7 +72,7 @@ internal class S3Metadata /// /// The logger. /// - private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); /// /// The underlying S3 client. @@ -90,7 +89,7 @@ public SFS3Client( int parallel, ProxyCredentials proxyCredentials) { - logger.LogDebug("Setting up a new AWS client "); + s_loggerPair.LogDebug("Setting up a new AWS client "); // Get the key id and secret key from the response stageInfo.stageCredentials.TryGetValue(AWS_KEY_ID, out string awsAccessKeyId); @@ -538,7 +537,7 @@ private GetObjectRequest GetGetObjectRequest(ref AmazonS3Client client, SFFileMe /// The file metadata. private void HandleFileHeaderErr(Exception ex, SFFileMetadata fileMetadata) { - logger.LogError("Failed to get file header: " + ex.Message); + s_loggerPair.LogError("Failed to get file header: " + ex.Message); switch (ex) { @@ -570,7 +569,7 @@ private void HandleFileHeaderErr(Exception ex, SFFileMetadata fileMetadata) /// The file metadata. private void HandleUploadFileErr(Exception ex, SFFileMetadata fileMetadata) { - logger.LogError("Failed to upload file: " + ex.Message); + s_loggerPair.LogError("Failed to upload file: " + ex.Message); switch (ex) { @@ -600,7 +599,7 @@ private void HandleUploadFileErr(Exception ex, SFFileMetadata fileMetadata) /// The file metadata. private void HandleDownloadFileErr(Exception ex, SFFileMetadata fileMetadata) { - logger.LogError("Failed to download file: " + ex.Message); + s_loggerPair.LogError("Failed to download file: " + ex.Message); switch (ex) { diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs index 1467c3a05..3e36a76b5 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs @@ -14,7 +14,6 @@ using System.Threading; using System.Threading.Tasks; using System.Net; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.FileTransfer.StorageClient { @@ -32,7 +31,7 @@ class SFSnowflakeAzureClient : ISFRemoteStorageClient /// /// The logger. /// - private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); /// /// The cloud blob client to use to upload and download data on Azure. @@ -45,7 +44,7 @@ class SFSnowflakeAzureClient : ISFRemoteStorageClient /// The command stage info. public SFSnowflakeAzureClient(PutGetStageInfo stageInfo) { - logger.LogDebug("Setting up a new Azure client "); + s_loggerPair.LogDebug("Setting up a new Azure client "); // Get the Azure SAS token and create the client if (stageInfo.stageCredentials.TryGetValue(AZURE_SAS_TOKEN, out string sasToken)) diff --git a/Snowflake.Data/Core/HttpUtil.cs b/Snowflake.Data/Core/HttpUtil.cs index 8b8758c07..4197d1b1b 100644 --- a/Snowflake.Data/Core/HttpUtil.cs +++ b/Snowflake.Data/Core/HttpUtil.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved. */ @@ -15,7 +15,6 @@ using System.Linq; using Snowflake.Data.Core.Authenticator; using static Snowflake.Data.Core.SFRestRequest; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -78,7 +77,7 @@ public sealed class HttpUtil static internal readonly int MAX_BACKOFF = 16; private static readonly int s_baseBackOffTime = 1; private static readonly int s_exponentialFactor = 2; - private static readonly Microsoft.Extensions.Logging.ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private static readonly List s_supportedEndpointsForRetryPolicy = new List { @@ -115,7 +114,7 @@ private HttpClient RegisterNewHttpClientIfNecessary(HttpClientConfig config, Del string name = config.ConfKey; if (!_HttpClients.ContainsKey(name)) { - logger.LogDebug("Http client not registered. Adding."); + s_loggerPair.LogDebug("Http client not registered. Adding."); var httpClient = new HttpClient( new RetryHandler(SetupCustomHttpHandler(config, customHandler), config.DisableRetry, config.ForceRetryOn404, config.MaxHttpRetries, config.IncludeRetryReason)) @@ -334,7 +333,7 @@ internal Uri Update(int retryReason = 0) } private class RetryHandler : DelegatingHandler { - static private ILogger logger = SFLoggerFactory.GetCustomLogger(); + static private SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private bool disableRetry; private bool forceRetryOn404; @@ -368,10 +367,10 @@ protected override async Task SendAsync(HttpRequestMessage TimeSpan httpTimeout = (TimeSpan)requestMessage.Properties[BaseRestRequest.HTTP_REQUEST_TIMEOUT_KEY]; TimeSpan restTimeout = (TimeSpan)requestMessage.Properties[BaseRestRequest.REST_REQUEST_TIMEOUT_KEY]; - if (logger.IsEnabled(LogLevel.Debug)) + if (s_loggerPair.IsDebugEnabled()) { - logger.LogDebug("Http request timeout : " + httpTimeout); - logger.LogDebug("Rest request timeout : " + restTimeout); + s_loggerPair.LogDebug("Http request timeout : " + httpTimeout); + s_loggerPair.LogDebug("Rest request timeout : " + restTimeout); } CancellationTokenSource childCts = null; @@ -402,12 +401,12 @@ protected override async Task SendAsync(HttpRequestMessage lastException = e; if (cancellationToken.IsCancellationRequested) { - logger.LogInformation("SF rest request timeout or explicit cancel called."); + s_loggerPair.LogInformation("SF rest request timeout or explicit cancel called."); cancellationToken.ThrowIfCancellationRequested(); } else if (childCts != null && childCts.Token.IsCancellationRequested) { - logger.LogWarning("Http request timeout. Retry the request"); + s_loggerPair.LogWarning("Http request timeout. Retry the request"); totalRetryTime += (int)httpTimeout.TotalSeconds; } else @@ -416,13 +415,13 @@ protected override async Task SendAsync(HttpRequestMessage if (innermostException is AuthenticationException) { - logger.LogError("Non-retryable error encountered: ", e); + s_loggerPair.LogError("Non-retryable error encountered: ", e); throw; } else { //TODO: Should probably check to see if the error is recoverable or transient. - logger.LogWarning("Error occurred during request, retrying...", e); + s_loggerPair.LogWarning("Error occurred during request, retrying...", e); } } } @@ -446,12 +445,12 @@ protected override async Task SendAsync(HttpRequestMessage if (response.IsSuccessStatusCode) { - logger.LogDebug($"Success Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + s_loggerPair.LogDebug($"Success Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); return response; } else { - logger.LogDebug($"Failed Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + s_loggerPair.LogDebug($"Failed Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); bool isRetryable = isRetryableHTTPCode((int)response.StatusCode, forceRetryOn404); if (!isRetryable || disableRetry) @@ -464,19 +463,19 @@ protected override async Task SendAsync(HttpRequestMessage } else { - logger.LogInformation("Response returned was null."); + s_loggerPair.LogInformation("Response returned was null."); } if (restTimeout.TotalSeconds > 0 && totalRetryTime >= restTimeout.TotalSeconds) { - logger.LogDebug($"stop retry as connection_timeout {restTimeout.TotalSeconds} sec. reached"); + s_loggerPair.LogDebug($"stop retry as connection_timeout {restTimeout.TotalSeconds} sec. reached"); if (response != null) { return response; } var errorMessage = $"http request failed and connection_timeout {restTimeout.TotalSeconds} sec. reached.\n"; errorMessage += $"Last exception encountered: {lastException}"; - logger.LogError(errorMessage); + s_loggerPair.LogError(errorMessage); throw new OperationCanceledException(errorMessage); } @@ -489,14 +488,14 @@ protected override async Task SendAsync(HttpRequestMessage retryCount++; if ((maxRetryCount > 0) && (retryCount > maxRetryCount)) { - logger.LogDebug($"stop retry as maxHttpRetries {maxRetryCount} reached"); + s_loggerPair.LogDebug($"stop retry as maxHttpRetries {maxRetryCount} reached"); if (response != null) { return response; } var errorMessage = $"http request failed and max retry {maxRetryCount} reached.\n"; errorMessage += $"Last exception encountered: {lastException}"; - logger.LogError(errorMessage); + s_loggerPair.LogError(errorMessage); throw new OperationCanceledException(errorMessage); } @@ -505,7 +504,7 @@ protected override async Task SendAsync(HttpRequestMessage requestMessage.RequestUri = updater.Update(errorReason); - logger.LogDebug($"Sleep {backOffInSec} seconds and then retry the request, retryCount: {retryCount}"); + s_loggerPair.LogDebug($"Sleep {backOffInSec} seconds and then retry the request, retryCount: {retryCount}"); await Task.Delay(TimeSpan.FromSeconds(backOffInSec), cancellationToken).ConfigureAwait(false); diff --git a/Snowflake.Data/Core/QueryContextCache.cs b/Snowflake.Data/Core/QueryContextCache.cs index e3fb53b24..8b14bca1a 100644 --- a/Snowflake.Data/Core/QueryContextCache.cs +++ b/Snowflake.Data/Core/QueryContextCache.cs @@ -3,7 +3,6 @@ using Newtonsoft.Json; using System.Linq; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -76,7 +75,7 @@ internal class QueryContextCache private Dictionary _priorityMap; // Map for priority and QCC private Dictionary _newPriorityMap; // Intermediate map for priority and QCC for current round of merging private SortedSet _cacheSet; // Order data as per priority - private ILogger _logger = SFLoggerFactory.GetCustomLogger(); + private SFLoggerPair _loggerPair = SFLoggerPair.GetLoggerPair(); public QueryContextCache(int capacity) { @@ -92,7 +91,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) { if (_idMap.ContainsKey(id)) { - _logger.LogDebug( + _loggerPair.LogDebug( $"Merge with existing id in cache = {id}, priority = {priority}"); // ID found in the cache QueryContextElement qce = _idMap[id]; @@ -125,7 +124,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) // new id if (_priorityMap.ContainsKey(priority)) { - _logger.LogDebug( + _loggerPair.LogDebug( $"Merge with existing priority in cache = {id}, priority = {priority}"); // Same priority with different id QueryContextElement qce = _priorityMap[priority]; @@ -137,7 +136,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) { // new priority // Add new element in the cache - _logger.LogDebug( + _loggerPair.LogDebug( $"Adding new QCC item with either id nor priority found in cache id = {id}, priority = {priority}"); QueryContextElement newQCE = new QueryContextElement(id, readTimestamp, priority, context); AddQCE(newQCE); @@ -148,7 +147,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) /** Sync the newPriorityMap with the priorityMap at the end of current round of merge */ public void SyncPriorityMap() { - _logger.LogDebug( + _loggerPair.LogDebug( $"syncPriorityMap called priorityMap size = {_priorityMap.Count}, newPrioirtyMap size = {_newPriorityMap.Count}"); foreach (KeyValuePair entry in _newPriorityMap) { @@ -164,7 +163,7 @@ public void SyncPriorityMap() */ public void CheckCacheCapacity() { - _logger.LogDebug( + _loggerPair.LogDebug( $"checkCacheCapacity() called. cacheSet size {_cacheSet.Count} cache capacity {_capacity}"); if (_cacheSet.Count > _capacity) { @@ -176,18 +175,18 @@ public void CheckCacheCapacity() } } - _logger.LogDebug( + _loggerPair.LogDebug( $"checkCacheCapacity() returns. cacheSet size {_cacheSet.Count} cache capacity {_capacity}"); } /** Clear the cache. */ public void ClearCache() { - _logger.LogDebug("clearCache() called"); + _loggerPair.LogDebug("clearCache() called"); _idMap.Clear(); _priorityMap.Clear(); _cacheSet.Clear(); - _logger.LogDebug($"clearCache() returns. Number of entries in cache now {_cacheSet.Count}"); + _loggerPair.LogDebug($"clearCache() returns. Number of entries in cache now {_cacheSet.Count}"); } public void SetCapacity(int cap) @@ -200,7 +199,7 @@ public void SetCapacity(int cap) if (_capacity == cap) return; - _logger.LogDebug($"set capacity from {_capacity} to {cap}"); + _loggerPair.LogDebug($"set capacity from {_capacity} to {cap}"); _capacity = cap; CheckCacheCapacity(); LogCacheEntries(); @@ -338,11 +337,11 @@ private void ReplaceQCE(QueryContextElement oldQCE, QueryContextElement newQCE) /** Debugging purpose, log the all entries in the cache. */ private void LogCacheEntries() { - if (_logger.IsEnabled(LogLevel.Debug)) + if (_loggerPair.IsDebugEnabled()) { foreach (QueryContextElement elem in _cacheSet) { - _logger.LogDebug($"Cache Entry: id: {elem.Id} readTimestamp: {elem.ReadTimestamp} priority: {elem.Priority}"); + _loggerPair.LogDebug($"Cache Entry: id: {elem.Id} readTimestamp: {elem.ReadTimestamp} priority: {elem.Priority}"); } } } diff --git a/Snowflake.Data/Core/QueryResultsAwaiter.cs b/Snowflake.Data/Core/QueryResultsAwaiter.cs index 7a31858f2..2021efdf7 100644 --- a/Snowflake.Data/Core/QueryResultsAwaiter.cs +++ b/Snowflake.Data/Core/QueryResultsAwaiter.cs @@ -8,7 +8,6 @@ using System; using System.Text.RegularExpressions; using Snowflake.Data.Client; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -37,7 +36,7 @@ internal QueryResultsRetryConfig(int asyncNoDataMaxRetry, int[] asyncRetryPatter internal class QueryResultsAwaiter { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private static readonly Regex UuidRegex = new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); @@ -65,7 +64,7 @@ internal QueryStatus GetQueryStatus(SnowflakeDbConnection connection, string que else { var errorMessage = $"The given query id {queryId} is not valid uuid"; - s_logger.LogError(errorMessage); + s_loggerPair.LogError(errorMessage); throw new Exception(errorMessage); } } @@ -80,7 +79,7 @@ internal async Task GetQueryStatusAsync(SnowflakeDbConnection conne else { var errorMessage = $"The given query id {queryId} is not valid uuid"; - s_logger.LogError(errorMessage); + s_loggerPair.LogError(errorMessage); throw new Exception(errorMessage); } } @@ -102,7 +101,7 @@ internal async Task RetryUntilQueryResultIsAvailable(SnowflakeDbConnection conne { if (cancellationToken.IsCancellationRequested) { - s_logger.LogDebug("Cancellation requested for getting results from query id"); + s_loggerPair.LogDebug("Cancellation requested for getting results from query id"); cancellationToken.ThrowIfCancellationRequested(); } @@ -132,7 +131,7 @@ internal async Task RetryUntilQueryResultIsAvailable(SnowflakeDbConnection conne if (noDataCounter > _queryResultsRetryConfig._asyncNoDataMaxRetry) { var errorMessage = "Max retry for no data is reached"; - s_logger.LogError(errorMessage); + s_loggerPair.LogError(errorMessage); throw new Exception(errorMessage); } } diff --git a/Snowflake.Data/Core/RestRequester.cs b/Snowflake.Data/Core/RestRequester.cs index aa10378c4..8cf898f7e 100644 --- a/Snowflake.Data/Core/RestRequester.cs +++ b/Snowflake.Data/Core/RestRequester.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -9,7 +9,6 @@ using System.Threading.Tasks; using Snowflake.Data.Client; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -40,7 +39,7 @@ internal interface IMockRestRequester : IRestRequester internal class RestRequester : IRestRequester { - private static ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); protected HttpClient _HttpClient; @@ -114,18 +113,18 @@ protected virtual async Task SendAsync(HttpRequestMessage m HttpResponseMessage response = null; try { - logger.LogDebug($"Executing: {sid} {message.Method} {message.RequestUri} HTTP/{message.Version}"); + s_loggerPair.LogDebug($"Executing: {sid} {message.Method} {message.RequestUri} HTTP/{message.Version}"); response = await _HttpClient .SendAsync(message, HttpCompletionOption.ResponseHeadersRead, linkedCts.Token) .ConfigureAwait(false); if (!response.IsSuccessStatusCode) { - logger.LogError($"Failed Response: {sid} {message.Method} {message.RequestUri} StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + s_loggerPair.LogError($"Failed Response: {sid} {message.Method} {message.RequestUri} StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); } else { - logger.LogDebug($"Succeeded Response: {sid} {message.Method} {message.RequestUri}"); + s_loggerPair.LogDebug($"Succeeded Response: {sid} {message.Method} {message.RequestUri}"); } response.EnsureSuccessStatusCode(); diff --git a/Snowflake.Data/Core/SFBindUploader.cs b/Snowflake.Data/Core/SFBindUploader.cs index b36d2ae6f..15263eca0 100644 --- a/Snowflake.Data/Core/SFBindUploader.cs +++ b/Snowflake.Data/Core/SFBindUploader.cs @@ -7,7 +7,6 @@ using System.Threading; using System.Threading.Tasks; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -36,7 +35,7 @@ class SFBindUploader private string requestId; - private ILogger logger = SFLoggerFactory.GetCustomLogger(); + private SFLoggerPair loggerPair = SFLoggerPair.GetLoggerPair(); private string stagePath; @@ -310,7 +309,7 @@ private void CreateStage() catch (Exception e) { session.SetArrayBindStageThreshold(0); - logger.LogError("Failed to create temporary stage for array binds.", e); + loggerPair.LogError("Failed to create temporary stage for array binds.", e); throw; } } @@ -334,7 +333,7 @@ internal async Task CreateStageAsync(CancellationToken cancellationToken) catch (Exception e) { session.SetArrayBindStageThreshold(0); - logger.LogError("Failed to create temporary stage for array binds.", e); + loggerPair.LogError("Failed to create temporary stage for array binds.", e); throw; } } diff --git a/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs b/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs index 741b1f90d..cd680fd96 100755 --- a/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs +++ b/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -17,13 +17,12 @@ using System.Diagnostics; using Newtonsoft.Json.Serialization; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { class SFBlockingChunkDownloaderV3 : IChunkDownloader { - static private ILogger logger = SFLoggerFactory.GetCustomLogger(); + static private SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private List chunkDatas = new List(); @@ -100,7 +99,7 @@ private int GetPrefetchThreads(SFBaseResultSet resultSet) public async Task GetNextChunkAsync() { - logger.LogInformation($"NextChunkToConsume: {nextChunkToConsumeIndex}, NextChunkToDownload: {nextChunkToDownloadIndex}"); + s_loggerPair.LogInformation($"NextChunkToConsume: {nextChunkToConsumeIndex}, NextChunkToDownload: {nextChunkToDownloadIndex}"); if (nextChunkToConsumeIndex < chunkInfos.Count) { Task chunk = taskQueues[nextChunkToConsumeIndex % prefetchSlot]; @@ -193,7 +192,7 @@ private async Task DownloadChunkAsync(DownloadContextV3 downloa { if ((maxRetry <= 0) || (retryCount < maxRetry)) { - logger.LogDebug($"Retry {retryCount}/{maxRetry} of parse stream to chunk error: " + e.Message); + s_loggerPair.LogDebug($"Retry {retryCount}/{maxRetry} of parse stream to chunk error: " + e.Message); retry = true; // reset the chunk before retry in case there could be garbage // data left from last attempt @@ -210,13 +209,13 @@ private async Task DownloadChunkAsync(DownloadContextV3 downloa else { //parse error - logger.LogError("Failed retries of parse stream to chunk error: " + e.Message); + s_loggerPair.LogError("Failed retries of parse stream to chunk error: " + e.Message); throw new Exception("Parse stream to chunk error: " + e.Message); } } } } while (retry); - logger.LogInformation($"Succeed downloading chunk #{chunk.ChunkIndex}"); + s_loggerPair.LogInformation($"Succeed downloading chunk #{chunk.ChunkIndex}"); return chunk; } diff --git a/Snowflake.Data/Core/SFMultiStatementsResultSet.cs b/Snowflake.Data/Core/SFMultiStatementsResultSet.cs index 71fc4dc2a..5e8946554 100644 --- a/Snowflake.Data/Core/SFMultiStatementsResultSet.cs +++ b/Snowflake.Data/Core/SFMultiStatementsResultSet.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2022 Snowflake Computing Inc. All rights reserved. */ @@ -8,7 +8,6 @@ using Snowflake.Data.Log; using Snowflake.Data.Client; using System.Collections.Generic; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -16,7 +15,7 @@ class SFMultiStatementsResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => curResultSet.ResultFormat; - private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private string[] resultIds; diff --git a/Snowflake.Data/Core/SFResultSet.cs b/Snowflake.Data/Core/SFResultSet.cs index 4694d2792..e6408c97b 100755 --- a/Snowflake.Data/Core/SFResultSet.cs +++ b/Snowflake.Data/Core/SFResultSet.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -9,7 +9,6 @@ using Snowflake.Data.Client; using System.Collections.Generic; using System.Diagnostics; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -17,7 +16,7 @@ class SFResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => ResultFormat.JSON; - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private readonly int _totalChunkCount; @@ -52,7 +51,7 @@ public SFResultSet(QueryExecResponseData responseData, SFStatement sfStatement, } catch(System.Exception ex) { - s_logger.LogError("Result set error queryId="+responseData.queryId, ex); + s_loggerPair.LogError("Result set error queryId="+responseData.queryId, ex); throw; } } @@ -101,7 +100,7 @@ public SFResultSet(PutGetResponseData responseData, SFStatement sfStatement, Can internal void ResetChunkInfo(BaseResultChunk nextChunk) { - s_logger.LogDebug($"Received chunk #{nextChunk.ChunkIndex + 1} of {_totalChunkCount}"); + s_loggerPair.LogDebug($"Received chunk #{nextChunk.ChunkIndex + 1} of {_totalChunkCount}"); _currentChunk.RowSet = null; _currentChunk = nextChunk; } @@ -117,7 +116,7 @@ internal override async Task NextAsync() { // GetNextChunk could be blocked if download result is not done yet. // So put this piece of code in a seperate task - s_logger.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_loggerPair.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); BaseResultChunk nextChunk = await _chunkDownloader.GetNextChunkAsync().ConfigureAwait(false); @@ -140,7 +139,7 @@ internal override bool Next() if (_chunkDownloader != null) { - s_logger.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_loggerPair.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); BaseResultChunk nextChunk = Task.Run(async() => await (_chunkDownloader.GetNextChunkAsync()).ConfigureAwait(false)).Result; diff --git a/Snowflake.Data/Core/SFResultSetMetaData.cs b/Snowflake.Data/Core/SFResultSetMetaData.cs index 83470eda8..fed09201a 100755 --- a/Snowflake.Data/Core/SFResultSetMetaData.cs +++ b/Snowflake.Data/Core/SFResultSetMetaData.cs @@ -7,13 +7,12 @@ using System.Data; using Snowflake.Data.Log; using Snowflake.Data.Client; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { class SFResultSetMetaData { - static private readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + static private readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private int columnCount; @@ -93,7 +92,7 @@ internal int GetColumnIndexByName(string targetColumnName) { if (String.Compare(rowType.name, targetColumnName, false) == 0 ) { - logger.LogInformation($"Found column name {targetColumnName} under index {indexCounter}"); + s_loggerPair.LogInformation($"Found column name {targetColumnName} under index {indexCounter}"); columnNameToIndexCache[targetColumnName] = indexCounter; return indexCounter; } diff --git a/Snowflake.Data/Core/SFStatement.cs b/Snowflake.Data/Core/SFStatement.cs index 08ea0a166..3d91bad84 100644 --- a/Snowflake.Data/Core/SFStatement.cs +++ b/Snowflake.Data/Core/SFStatement.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -11,7 +11,6 @@ using System.Threading; using System.Threading.Tasks; using System.Text; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -98,7 +97,7 @@ internal static bool IsAnError(QueryStatus status) class SFStatement { - static private ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + static private SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); internal SFSession SfSession { get; set; } @@ -169,7 +168,7 @@ private void AssignQueryRequestId() if (_requestId != null) { - s_logger.LogInformation("Another query is running."); + s_loggerPair.LogInformation("Another query is running."); throw new SnowflakeDbException(SFError.STATEMENT_ALREADY_RUNNING_QUERY); } @@ -341,7 +340,7 @@ private void registerQueryCancellationCallback(int timeout, CancellationToken ex catch (Exception ex) { // Prevent an unhandled exception from being thrown - s_logger.LogError("Unable to cancel query.", ex); + s_loggerPair.LogError("Unable to cancel query.", ex); } }); } @@ -387,7 +386,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti } catch (Exception e) { - s_logger.LogWarning("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); + s_loggerPair.LogWarning("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); } finally { @@ -425,7 +424,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti if (SessionExpired(response)) { - s_logger.LogInformation("Ping pong request failed with session expired, trying to renew the session."); + s_loggerPair.LogInformation("Ping pong request failed with session expired, trying to renew the session."); await SfSession.renewSessionAsync(cancellationToken).ConfigureAwait(false); } else @@ -439,7 +438,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti } catch { - s_logger.LogError("Query execution failed."); + s_loggerPair.LogError("Query execution failed."); throw; } finally @@ -485,7 +484,7 @@ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, string tri bindings, describeOnly); - s_logger.LogDebug("PUT/GET queryId: " + (response.data != null ? response.data.queryId : "Unknown")); + s_loggerPair.LogDebug("PUT/GET queryId: " + (response.data != null ? response.data.queryId : "Unknown")); SFFileTransferAgent fileTransferAgent = new SFFileTransferAgent(trimmedSql, SfSession, response.data, CancellationToken.None); @@ -501,13 +500,13 @@ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, string tri } catch (SnowflakeDbException ex) { - s_logger.LogError($"Query execution failed, QueryId: {ex.QueryId??"unavailable"}", ex); + s_loggerPair.LogError($"Query execution failed, QueryId: {ex.QueryId??"unavailable"}", ex); _lastQueryId = ex.QueryId ?? _lastQueryId; throw; } catch (Exception ex) { - s_logger.LogError("Query execution failed.", ex); + s_loggerPair.LogError("Query execution failed.", ex); throw new SnowflakeDbException(ex, SFError.INTERNAL_ERROR); } } @@ -539,7 +538,7 @@ private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dicti } catch (Exception e) { - s_logger.LogWarning("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); + s_loggerPair.LogWarning("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); } finally { @@ -559,7 +558,7 @@ private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dicti } catch (Exception ex) { - s_logger.LogError("Query execution failed.", ex); + s_loggerPair.LogError("Query execution failed.", ex); if (ex is SnowflakeDbException snowflakeDbException) { _lastQueryId = snowflakeDbException.QueryId ?? _lastQueryId; @@ -625,11 +624,11 @@ internal void Cancel() if (response.success) { - s_logger.LogInformation("Query cancellation succeed"); + s_loggerPair.LogInformation("Query cancellation succeed"); } else { - s_logger.LogWarning("Query cancellation failed."); + s_loggerPair.LogWarning("Query cancellation failed."); } CleanUpCancellationTokenSources(); } @@ -686,7 +685,7 @@ internal T ExecuteHelper( if (SessionExpired(response)) { - s_logger.LogInformation("Ping pong request failed with session expired, trying to renew the session."); + s_loggerPair.LogInformation("Ping pong request failed with session expired, trying to renew the session."); SfSession.renewSession(); } else @@ -710,7 +709,7 @@ internal T ExecuteHelper( } catch (Exception ex) { - s_logger.LogError("Query execution failed.", ex); + s_loggerPair.LogError("Query execution failed.", ex); throw; } finally @@ -773,7 +772,7 @@ internal async Task ExecuteAsyncHelper( if (SessionExpired(response)) { - s_logger.LogInformation("Ping pong request failed with session expired, trying to renew the session."); + s_loggerPair.LogInformation("Ping pong request failed with session expired, trying to renew the session."); await SfSession.renewSessionAsync(cancellationToken).ConfigureAwait(false); } else @@ -797,7 +796,7 @@ internal async Task ExecuteAsyncHelper( } catch (Exception ex) { - s_logger.LogError("Query execution failed.", ex); + s_loggerPair.LogError("Query execution failed.", ex); throw; } finally @@ -874,7 +873,7 @@ internal QueryStatus GetQueryStatus(string queryId) } catch { - s_logger.LogError("Query execution failed."); + s_loggerPair.LogError("Query execution failed."); throw; } finally @@ -929,7 +928,7 @@ internal async Task GetQueryStatusAsync(string queryId, Cancellatio } catch { - s_logger.LogError("Query execution failed."); + s_loggerPair.LogError("Query execution failed."); throw; } finally @@ -992,7 +991,7 @@ internal static string TrimSql(string originalSql) var trimmedQuery = builder.ToString(); trimmedQuery = trimmedQuery.Trim(); - s_logger.LogDebug("Trimmed query : " + trimmedQuery); + s_loggerPair.LogDebug("Trimmed query : " + trimmedQuery); return trimmedQuery; } diff --git a/Snowflake.Data/Core/Session/ConnectionPoolManager.cs b/Snowflake.Data/Core/Session/ConnectionPoolManager.cs index 067a4636a..de4e6fd88 100644 --- a/Snowflake.Data/Core/Session/ConnectionPoolManager.cs +++ b/Snowflake.Data/Core/Session/ConnectionPoolManager.cs @@ -11,13 +11,12 @@ using Snowflake.Data.Client; using Snowflake.Data.Core.Tools; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Session { internal sealed class ConnectionPoolManager : IConnectionManager { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private static readonly Object s_poolsLock = new Object(); private static readonly Exception s_operationNotAvailable = new Exception("You cannot change connection pool parameters for all the pools. Instead you can change it on a particular pool"); private readonly Dictionary _pools; @@ -32,31 +31,31 @@ internal ConnectionPoolManager() public SFSession GetSession(string connectionString, SecureString password) { - s_logger.LogDebug($"ConnectionPoolManager::GetSession"); + s_loggerPair.LogDebug($"ConnectionPoolManager::GetSession"); return GetPool(connectionString, password).GetSession(); } public Task GetSessionAsync(string connectionString, SecureString password, CancellationToken cancellationToken) { - s_logger.LogDebug($"ConnectionPoolManager::GetSessionAsync"); + s_loggerPair.LogDebug($"ConnectionPoolManager::GetSessionAsync"); return GetPool(connectionString, password).GetSessionAsync(cancellationToken); } public bool AddSession(SFSession session) { - s_logger.LogDebug("ConnectionPoolManager::AddSession"); + s_loggerPair.LogDebug("ConnectionPoolManager::AddSession"); return GetPool(session.ConnectionString, session.Password).AddSession(session, true); } public void ReleaseBusySession(SFSession session) { - s_logger.LogDebug("ConnectionPoolManager::ReleaseBusySession"); + s_loggerPair.LogDebug("ConnectionPoolManager::ReleaseBusySession"); GetPool(session.ConnectionString, session.Password).ReleaseBusySession(session); } public void ClearAllPools() { - s_logger.LogDebug("ConnectionPoolManager::ClearAllPools"); + s_loggerPair.LogDebug("ConnectionPoolManager::ClearAllPools"); foreach (var sessionPool in _pools.Values) { sessionPool.DestroyPool(); @@ -71,7 +70,7 @@ public void SetMaxPoolSize(int maxPoolSize) public int GetMaxPoolSize() { - s_logger.LogDebug("ConnectionPoolManager::GetMaxPoolSize"); + s_loggerPair.LogDebug("ConnectionPoolManager::GetMaxPoolSize"); var values = _pools.Values.Select(it => it.GetMaxPoolSize()).Distinct().ToList(); switch (values.Count) { @@ -91,7 +90,7 @@ public void SetTimeout(long connectionTimeout) public long GetTimeout() { - s_logger.LogDebug("ConnectionPoolManager::GetTimeout"); + s_loggerPair.LogDebug("ConnectionPoolManager::GetTimeout"); var values = _pools.Values.Select(it => it.GetTimeout()).Distinct().ToList(); switch (values.Count) { @@ -106,7 +105,7 @@ public long GetTimeout() public int GetCurrentPoolSize() { - s_logger.LogDebug("ConnectionPoolManager::GetCurrentPoolSize"); + s_loggerPair.LogDebug("ConnectionPoolManager::GetCurrentPoolSize"); return _pools.Values.Select(it => it.GetCurrentPoolSize()).Sum(); } @@ -117,13 +116,13 @@ public bool SetPooling(bool poolingEnabled) public bool GetPooling() { - s_logger.LogDebug("ConnectionPoolManager::GetPooling"); + s_loggerPair.LogDebug("ConnectionPoolManager::GetPooling"); return true; // in new pool pooling is always enabled by default, disabling only by connection string parameter } public SessionPool GetPool(string connectionString, SecureString password) { - s_logger.LogDebug("ConnectionPoolManager::GetPool with connection string and secure password"); + s_loggerPair.LogDebug("ConnectionPoolManager::GetPool with connection string and secure password"); var poolKey = GetPoolKey(connectionString, password); if (_pools.TryGetValue(poolKey, out var item)) @@ -139,7 +138,7 @@ public SessionPool GetPool(string connectionString, SecureString password) poolCreatedWhileWaitingOnLock.ValidateSecurePassword(password); return poolCreatedWhileWaitingOnLock; } - s_logger.LogInformation($"Creating new pool"); + s_loggerPair.LogInformation($"Creating new pool"); var pool = SessionPool.CreateSessionPool(connectionString, password); _pools.Add(poolKey, pool); return pool; @@ -148,7 +147,7 @@ public SessionPool GetPool(string connectionString, SecureString password) public SessionPool GetPool(string connectionString) { - s_logger.LogDebug("ConnectionPoolManager::GetPool with connection string"); + s_loggerPair.LogDebug("ConnectionPoolManager::GetPool with connection string"); return GetPool(connectionString, null); } diff --git a/Snowflake.Data/Core/Session/SFSession.cs b/Snowflake.Data/Core/Session/SFSession.cs index 89643e306..aa8085f95 100755 --- a/Snowflake.Data/Core/Session/SFSession.cs +++ b/Snowflake.Data/Core/Session/SFSession.cs @@ -16,7 +16,6 @@ using System.Text.RegularExpressions; using Snowflake.Data.Core.Session; using Snowflake.Data.Core.Tools; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -24,7 +23,7 @@ public class SFSession { public const int SF_SESSION_EXPIRED_CODE = 390112; - private static readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private static readonly Regex APPLICATION_REGEX = new Regex(@"^[A-Za-z]([A-Za-z0-9.\-_]){1,50}$"); @@ -115,9 +114,9 @@ internal void ProcessLoginResponse(LoginResponse authnResponse) UpdateSessionParameterMap(authnResponse.data.nameValueParameter); if (_disableQueryContextCache) { - logger.LogDebug("Query context cache disabled."); + s_loggerPair.LogDebug("Query context cache disabled."); } - logger.LogDebug($"Session opened: {sessionId}"); + s_loggerPair.LogDebug($"Session opened: {sessionId}"); _startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } else @@ -128,7 +127,7 @@ internal void ProcessLoginResponse(LoginResponse authnResponse) authnResponse.message, ""); - logger.LogError("Authentication failed", e); + s_loggerPair.LogError("Authentication failed", e); throw e; } } @@ -194,12 +193,12 @@ internal SFSession( } catch (SnowflakeDbException e) { - logger.LogError("Unable to initialize session ", e); + s_loggerPair.LogError("Unable to initialize session ", e); throw; } catch (Exception e) { - logger.LogError("Unable to initialize session ", e); + s_loggerPair.LogError("Unable to initialize session ", e); throw new SnowflakeDbException(e, SnowflakeDbException.CONNECTION_FAILURE_SSTATE, SFError.INVALID_CONNECTION_STRING, @@ -252,7 +251,7 @@ internal Uri BuildUri(string path, Dictionary queryParams = null internal virtual void Open() { - logger.LogDebug("Open Session"); + s_loggerPair.LogDebug("Open Session"); if (authenticator == null) { @@ -264,7 +263,7 @@ internal virtual void Open() internal virtual async Task OpenAsync(CancellationToken cancellationToken) { - logger.LogDebug("Open Session Async"); + s_loggerPair.LogDebug("Open Session Async"); if (authenticator == null) { @@ -278,7 +277,7 @@ internal void close() { // Nothing to do if the session is not open if (!IsEstablished()) return; - logger.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + s_loggerPair.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); PostCloseSession(closeSessionRequest, restRequester); @@ -289,7 +288,7 @@ internal void CloseNonBlocking() { // Nothing to do if the session is not open if (!IsEstablished()) return; - logger.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + s_loggerPair.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); Task.Run(() => PostCloseSession(closeSessionRequest, restRequester)); @@ -300,19 +299,19 @@ internal async Task CloseAsync(CancellationToken cancellationToken) { // Nothing to do if the session is not open if (!IsEstablished()) return; - logger.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + s_loggerPair.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); - logger.LogDebug($"Closing session async"); + s_loggerPair.LogDebug($"Closing session async"); var response = await restRequester.PostAsync(closeSessionRequest, cancellationToken).ConfigureAwait(false); if (!response.success) { - logger.LogError($"Failed to close session {sessionId}, error ignored. Code: {response.code} Message: {response.message}"); + s_loggerPair.LogError($"Failed to close session {sessionId}, error ignored. Code: {response.code} Message: {response.message}"); } - logger.LogDebug($"Session closed: {sessionId}"); + s_loggerPair.LogDebug($"Session closed: {sessionId}"); sessionToken = null; } @@ -320,18 +319,18 @@ private static void PostCloseSession(SFRestRequest closeSessionRequest, IRestReq { try { - logger.LogDebug($"Closing session"); + s_loggerPair.LogDebug($"Closing session"); var response = restRequester.Post(closeSessionRequest); if (!response.success) { - logger.LogError($"Failed to close session: {closeSessionRequest.sid}, error ignored. Code: {response.code} Message: {response.message}"); + s_loggerPair.LogError($"Failed to close session: {closeSessionRequest.sid}, error ignored. Code: {response.code} Message: {response.message}"); } - logger.LogDebug($"Session closed: {closeSessionRequest.sid}"); + s_loggerPair.LogDebug($"Session closed: {closeSessionRequest.sid}"); } catch (Exception) { - logger.LogError($"Failed to close session: {closeSessionRequest.sid}, because of exception."); + s_loggerPair.LogError($"Failed to close session: {closeSessionRequest.sid}, because of exception."); throw; } } @@ -355,13 +354,13 @@ private SFRestRequest PrepareCloseSessionRequest() internal void renewSession() { - logger.LogInformation("Renew the session."); + s_loggerPair.LogInformation("Renew the session."); var response = restRequester.Post(getRenewSessionRequest()); if (!response.success) { SnowflakeDbException e = new SnowflakeDbException("", response.code, response.message, sessionId); - logger.LogError($"Renew session (ID: {sessionId}) failed", e); + s_loggerPair.LogError($"Renew session (ID: {sessionId}) failed", e); throw e; } else @@ -373,7 +372,7 @@ internal void renewSession() internal async Task renewSessionAsync(CancellationToken cancellationToken) { - logger.LogInformation("Renew the session."); + s_loggerPair.LogInformation("Renew the session."); var response = await restRequester.PostAsync( getRenewSessionRequest(), @@ -383,7 +382,7 @@ await restRequester.PostAsync( { SnowflakeDbException e = new SnowflakeDbException("", response.code, response.message, sessionId); - logger.LogError($"Renew session (ID: {sessionId}) failed", e); + s_loggerPair.LogError($"Renew session (ID: {sessionId}) failed", e); throw e; } else @@ -431,7 +430,7 @@ internal SFRestRequest BuildTimeoutRestRequest(Uri uri, Object body) internal void UpdateSessionParameterMap(List parameterList) { - logger.LogDebug("Update parameter map"); + s_loggerPair.LogDebug("Update parameter map"); // with HTAP parameter removal parameters might not returned // query response if (parameterList is null) @@ -579,7 +578,7 @@ public void SetArrayBindStageThreshold(int arrayBindStageThreshold) internal void heartbeat() { - logger.LogDebug("heartbeat"); + s_loggerPair.LogDebug("heartbeat"); bool retry = false; if (IsEstablished()) @@ -600,16 +599,16 @@ internal void heartbeat() }; var response = restRequester.Post(heartBeatSessionRequest); - logger.LogDebug("heartbeat response=" + response); + s_loggerPair.LogDebug("heartbeat response=" + response); if (response.success) { - logger.LogDebug("SFSession::heartbeat success, session token did not expire."); + s_loggerPair.LogDebug("SFSession::heartbeat success, session token did not expire."); } else { if (response.code == SF_SESSION_EXPIRED_CODE) { - logger.LogDebug($"SFSession ::heartbeat Session ID: {sessionId} session token expired and retry heartbeat"); + s_loggerPair.LogDebug($"SFSession ::heartbeat Session ID: {sessionId} session token expired and retry heartbeat"); try { renewSession(); @@ -622,12 +621,12 @@ internal void heartbeat() // the heart beat, it's possible that the session get // closed when sending renew request and caused exception // thrown from renewSession(), simply ignore that - logger.LogError($"renew session (ID: {sessionId}) failed.", ex); + s_loggerPair.LogError($"renew session (ID: {sessionId}) failed.", ex); } } else { - logger.LogError($"heartbeat failed for session ID: {sessionId}."); + s_loggerPair.LogError($"heartbeat failed for session ID: {sessionId}."); } } retry = false; diff --git a/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs b/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs index d23b2e39b..f9b08eb86 100644 --- a/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs +++ b/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs @@ -5,7 +5,6 @@ using Snowflake.Data.Core.Session; using Snowflake.Data.Core.Tools; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -22,7 +21,7 @@ internal class SFSessionHttpClientProperties public const bool DefaultPoolingEnabled = true; public const int DefaultMaxHttpRetries = 7; public static readonly TimeSpan DefaultRetryTimeout = TimeSpan.FromSeconds(300); - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); internal bool validateDefaultParameters; internal bool clientSessionKeepAlive; @@ -69,11 +68,11 @@ private void DisablePoolingIfNotExplicitlyEnabled(SFSessionProperties properties if (!properties.IsPoolingEnabledValueProvided && _poolingEnabled) { _poolingEnabled = false; - s_logger.LogInformation($"Disabling connection pooling for {authenticationDescription} authentication"); + s_loggerPair.LogInformation($"Disabling connection pooling for {authenticationDescription} authentication"); } else if (properties.IsPoolingEnabledValueProvided && _poolingEnabled) { - s_logger.LogWarning($"Connection pooling is enabled for {authenticationDescription} authentication which is not recommended"); + s_loggerPair.LogWarning($"Connection pooling is enabled for {authenticationDescription} authentication which is not recommended"); } } @@ -102,16 +101,16 @@ private void ValidateConnectionTimeout() { if (TimeoutHelper.IsZeroLength(connectionTimeout)) { - s_logger.LogWarning("Connection timeout provided is 0. Timeout will be infinite"); + s_loggerPair.LogWarning("Connection timeout provided is 0. Timeout will be infinite"); connectionTimeout = TimeoutHelper.Infinity(); } else if (TimeoutHelper.IsInfinite(connectionTimeout)) { - s_logger.LogWarning("Connection timeout provided is negative. Timeout will be infinite."); + s_loggerPair.LogWarning("Connection timeout provided is negative. Timeout will be infinite."); } if (!TimeoutHelper.IsInfinite(connectionTimeout) && connectionTimeout < DefaultRetryTimeout) { - s_logger.LogWarning($"Connection timeout provided is less than recommended minimum value of {DefaultRetryTimeout}"); + s_loggerPair.LogWarning($"Connection timeout provided is less than recommended minimum value of {DefaultRetryTimeout}"); } } @@ -119,17 +118,17 @@ private void ValidateRetryTimeout() { if (retryTimeout.TotalMilliseconds > 0 && retryTimeout < DefaultRetryTimeout) { - s_logger.LogWarning($"Max retry timeout provided is less than the allowed minimum value of {DefaultRetryTimeout}"); + s_loggerPair.LogWarning($"Max retry timeout provided is less than the allowed minimum value of {DefaultRetryTimeout}"); retryTimeout = DefaultRetryTimeout; } else if (TimeoutHelper.IsZeroLength(retryTimeout)) { - s_logger.LogWarning($"Max retry timeout provided is 0. Timeout will be infinite"); + s_loggerPair.LogWarning($"Max retry timeout provided is 0. Timeout will be infinite"); retryTimeout = TimeoutHelper.Infinity(); } else if (TimeoutHelper.IsInfinite(retryTimeout)) { - s_logger.LogWarning($"Max retry timeout provided is negative. Timeout will be infinite"); + s_loggerPair.LogWarning($"Max retry timeout provided is negative. Timeout will be infinite"); } } @@ -137,7 +136,7 @@ private void ShortenConnectionTimeoutByRetryTimeout() { if (!TimeoutHelper.IsInfinite(retryTimeout) && retryTimeout < connectionTimeout) { - s_logger.LogWarning($"Connection timeout greater than retry timeout. Setting connection time same as retry timeout"); + s_loggerPair.LogWarning($"Connection timeout greater than retry timeout. Setting connection time same as retry timeout"); connectionTimeout = retryTimeout; } } @@ -146,13 +145,13 @@ private void ValidateHttpRetries() { if (maxHttpRetries > 0 && maxHttpRetries < DefaultMaxHttpRetries) { - s_logger.LogWarning($"Max retry count provided is less than the allowed minimum value of {DefaultMaxHttpRetries}"); + s_loggerPair.LogWarning($"Max retry count provided is less than the allowed minimum value of {DefaultMaxHttpRetries}"); maxHttpRetries = DefaultMaxHttpRetries; } else if (maxHttpRetries == 0) { - s_logger.LogWarning($"Max retry count provided is 0. Retry count will be infinite"); + s_loggerPair.LogWarning($"Max retry count provided is 0. Retry count will be infinite"); } } @@ -172,7 +171,7 @@ private void ValidateWaitingForSessionIdleTimeout() } if (TimeoutHelper.IsZeroLength(_waitingForSessionIdleTimeout)) { - s_logger.LogWarning("Waiting for idle session timeout is 0. There will be no waiting for idle session"); + s_loggerPair.LogWarning("Waiting for idle session timeout is 0. There will be no waiting for idle session"); } } diff --git a/Snowflake.Data/Core/Session/SFSessionProperty.cs b/Snowflake.Data/Core/Session/SFSessionProperty.cs index 98e844599..42f518aeb 100644 --- a/Snowflake.Data/Core/Session/SFSessionProperty.cs +++ b/Snowflake.Data/Core/Session/SFSessionProperty.cs @@ -14,7 +14,6 @@ using System.Text; using System.Text.RegularExpressions; using Snowflake.Data.Core.Tools; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core { @@ -127,7 +126,7 @@ class SFSessionPropertyAttr : Attribute class SFSessionProperties : Dictionary { - private static ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); internal string ConnectionStringWithoutSecrets { get; set; } @@ -172,7 +171,7 @@ public override bool Equals(object obj) } catch (InvalidCastException) { - logger.LogWarning("Invalid casting to SFSessionProperties"); + s_loggerPair.LogWarning("Invalid casting to SFSessionProperties"); return false; } } @@ -184,7 +183,7 @@ public override int GetHashCode() internal static SFSessionProperties ParseConnectionString(string connectionString, SecureString password) { - logger.LogInformation("Start parsing connection string."); + s_loggerPair.LogInformation("Start parsing connection string."); var builder = new DbConnectionStringBuilder(); try { @@ -192,7 +191,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin } catch (ArgumentException e) { - logger.LogWarning("Invalid connectionString", e); + s_loggerPair.LogWarning("Invalid connectionString", e); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_STRING, e.Message); @@ -216,7 +215,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin } catch (ArgumentException) { - logger.LogDebug($"Property {keys[i]} not found ignored."); + s_loggerPair.LogDebug($"Property {keys[i]} not found ignored."); } } @@ -232,7 +231,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin catch (Exception e) { // The useProxy setting is not a valid boolean value - logger.LogError("Unable to connect", e); + s_loggerPair.LogError("Unable to connect", e); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_STRING, e.Message); @@ -274,15 +273,15 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin if (!allowUnderscoresInHost && compliantAccountName.Contains('_')) { compliantAccountName = compliantAccountName.Replace('_', '-'); - logger.LogInformation($"Replacing _ with - in the account name. Old: {properties[SFSessionProperty.ACCOUNT]}, new: {compliantAccountName}."); + s_loggerPair.LogInformation($"Replacing _ with - in the account name. Old: {properties[SFSessionProperty.ACCOUNT]}, new: {compliantAccountName}."); } var hostName = $"{compliantAccountName}.snowflakecomputing.com"; // Remove in case it's here but empty properties.Remove(SFSessionProperty.HOST); properties.Add(SFSessionProperty.HOST, hostName); - logger.LogInformation($"Compose host name: {hostName}"); + s_loggerPair.LogInformation($"Compose host name: {hostName}"); } - logger.LogInformation(ResolveConnectionAreaMessage(properties[SFSessionProperty.HOST])); + s_loggerPair.LogInformation(ResolveConnectionAreaMessage(properties[SFSessionProperty.HOST])); // Trim the account name to remove the region and cloud platform if any were provided // because the login request data does not expect region and cloud information to be @@ -313,7 +312,7 @@ private static void ValidateAuthenticator(SFSessionProperties properties) if (!knownAuthenticators.Contains(authenticator) && !(authenticator.Contains(OktaAuthenticator.AUTH_NAME) && authenticator.StartsWith("https://"))) { var error = $"Unknown authenticator: {authenticator}"; - logger.LogError(error); + s_loggerPair.LogError(error); throw new SnowflakeDbException(SFError.UNKNOWN_AUTHENTICATOR, authenticator); } } @@ -406,7 +405,7 @@ private static void ValidateAccountDomain(SFSessionProperties properties) return; if (IsAccountRegexMatched(account)) return; - logger.LogError($"Invalid account {account}"); + s_loggerPair.LogError($"Invalid account {account}"); throw new SnowflakeDbException( new Exception("Invalid account"), SFError.INVALID_CONNECTION_PARAMETER_VALUE, @@ -428,14 +427,14 @@ private static void CheckSessionProperties(SFSessionProperties properties) !properties.ContainsKey(sessionProperty)) { SnowflakeDbException e = new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY, sessionProperty); - logger.LogError("Missing connection property", e); + s_loggerPair.LogError("Missing connection property", e); throw e; } if (IsRequired(sessionProperty, properties) && string.IsNullOrEmpty(properties[sessionProperty])) { SnowflakeDbException e = new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY, sessionProperty); - logger.LogError("Empty connection property", e); + s_loggerPair.LogError("Empty connection property", e); throw e; } @@ -443,7 +442,7 @@ private static void CheckSessionProperties(SFSessionProperties properties) string defaultVal = sessionProperty.GetAttribute().defaultValue; if (defaultVal != null && !properties.ContainsKey(sessionProperty)) { - logger.LogDebug($"Session property {sessionProperty} set to default value: {defaultVal}"); + s_loggerPair.LogDebug($"Session property {sessionProperty} set to default value: {defaultVal}"); properties.Add(sessionProperty, defaultVal); } } @@ -464,13 +463,13 @@ private static void ValidateFileTransferMaxBytesInMemoryProperty(SFSessionProper } catch (Exception e) { - logger.LogError($"Value for parameter {propertyName} could not be parsed"); + s_loggerPair.LogError($"Value for parameter {propertyName} could not be parsed"); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_PARAMETER_VALUE, maxBytesInMemoryString, propertyName); } if (maxBytesInMemory <= 0) { - logger.LogError($"Value for parameter {propertyName} should be greater than 0"); + s_loggerPair.LogError($"Value for parameter {propertyName} should be greater than 0"); throw new SnowflakeDbException( new Exception($"Value for parameter {propertyName} should be greater than 0"), SFError.INVALID_CONNECTION_PARAMETER_VALUE, maxBytesInMemoryString, propertyName); @@ -530,7 +529,7 @@ private static bool ParseAllowUnderscoresInHost(SFSessionProperties properties) } catch (Exception e) { - logger.LogWarning("Unable to parse property 'allowUnderscoresInHost'", e); + s_loggerPair.LogWarning("Unable to parse property 'allowUnderscoresInHost'", e); } return allowUnderscoresInHost; diff --git a/Snowflake.Data/Core/Session/SessionPool.cs b/Snowflake.Data/Core/Session/SessionPool.cs index 080f9ca1b..43d427668 100644 --- a/Snowflake.Data/Core/Session/SessionPool.cs +++ b/Snowflake.Data/Core/Session/SessionPool.cs @@ -11,13 +11,12 @@ using Snowflake.Data.Client; using Snowflake.Data.Core.Tools; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Session { sealed class SessionPool : IDisposable { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private readonly object _sessionPoolLock = new object(); private static ISessionFactory s_sessionFactory = new SessionFactory(); @@ -64,9 +63,9 @@ private SessionPool(string connectionString, SecureString password, ConnectionPo internal static SessionPool CreateSessionPool(string connectionString, SecureString password) { - s_logger.LogDebug("Creating a connection pool"); + s_loggerPair.LogDebug("Creating a connection pool"); var extracted = ExtractConfig(connectionString, password); - s_logger.LogDebug("Creating a connection pool identified by: " + extracted.Item2); + s_loggerPair.LogDebug("Creating a connection pool identified by: " + extracted.Item2); return new SessionPool(connectionString, password, extracted.Item1, extracted.Item2); } @@ -89,7 +88,7 @@ internal static ISessionFactory SessionFactory private void CleanExpiredSessions() { - s_logger.LogDebug("SessionPool::CleanExpiredSessions" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::CleanExpiredSessions" + PoolIdentification()); lock (_sessionPoolLock) { var timeNow = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); @@ -116,7 +115,7 @@ internal static Tuple ExtractConfig(string connect } catch (Exception exception) { - s_logger.LogError("Failed to extract pool configuration", exception); + s_loggerPair.LogError("Failed to extract pool configuration", exception); throw; } } @@ -126,7 +125,7 @@ internal void ValidateSecurePassword(SecureString password) if (!ExtractPassword(Password).Equals(ExtractPassword(password))) { var errorMessage = "Could not get a pool because of password mismatch"; - s_logger.LogError(errorMessage + PoolIdentification()); + s_loggerPair.LogError(errorMessage + PoolIdentification()); throw new Exception(errorMessage); } } @@ -136,7 +135,7 @@ private string ExtractPassword(SecureString password) => internal SFSession GetSession(string connStr, SecureString password) { - s_logger.LogDebug("SessionPool::GetSession" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::GetSession" + PoolIdentification()); if (!GetPooling()) return NewNonPoolingSession(connStr, password); var sessionOrCreateTokens = GetIdleSession(connStr); @@ -151,7 +150,7 @@ internal SFSession GetSession(string connStr, SecureString password) internal async Task GetSessionAsync(string connStr, SecureString password, CancellationToken cancellationToken) { - s_logger.LogDebug("SessionPool::GetSessionAsync" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::GetSessionAsync" + PoolIdentification()); if (!GetPooling()) return await NewNonPoolingSessionAsync(connStr, password, cancellationToken).ConfigureAwait(false); var sessionOrCreateTokens = GetIdleSession(connStr); @@ -182,7 +181,7 @@ private void WarnAboutOverridenConfig() { if (IsConfigOverridden() && GetPooling() && IsMultiplePoolsVersion()) { - s_logger.LogWarning("Providing a connection from a pool for which technical configuration has been overriden by the user"); + s_loggerPair.LogWarning("Providing a connection from a pool for which technical configuration has been overriden by the user"); } } @@ -200,22 +199,22 @@ internal void SetSessionPoolEventHandler(ISessionPoolEventHandler sessionPoolEve private SessionOrCreationTokens GetIdleSession(string connStr) { - s_logger.LogDebug("SessionPool::GetIdleSession" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::GetIdleSession" + PoolIdentification()); lock (_sessionPoolLock) { if (_waitingForIdleSessionQueue.IsAnyoneWaiting()) { - s_logger.LogDebug("SessionPool::GetIdleSession - someone is already waiting for a session, request is going to be queued" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::GetIdleSession - someone is already waiting for a session, request is going to be queued" + PoolIdentification()); } else { var session = ExtractIdleSession(connStr); if (session != null) { - s_logger.LogDebug("SessionPool::GetIdleSession - no thread was waiting for a session, an idle session was retrieved from the pool" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::GetIdleSession - no thread was waiting for a session, an idle session was retrieved from the pool" + PoolIdentification()); return new SessionOrCreationTokens(session); } - s_logger.LogDebug("SessionPool::GetIdleSession - no thread was waiting for a session, but could not find any idle session available in the pool" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::GetIdleSession - no thread was waiting for a session, but could not find any idle session available in the pool" + PoolIdentification()); var sessionsCount = AllowedNumberOfNewSessionCreations(1); if (sessionsCount > 0) { @@ -245,7 +244,7 @@ private int AllowedNumberOfNewSessionCreations(int atLeastCount) if (!IsMultiplePoolsVersion()) { if (atLeastCount > 0) - s_logger.LogDebug($"SessionPool - creating of new sessions is not limited"); + s_loggerPair.LogDebug($"SessionPool - creating of new sessions is not limited"); return atLeastCount; // we are either in old pool or there is no pooling } var currentSize = GetCurrentPoolSize(); @@ -254,10 +253,10 @@ private int AllowedNumberOfNewSessionCreations(int atLeastCount) var maxSessionsToCreate = _poolConfig.MaxPoolSize - currentSize; var sessionsNeeded = Math.Max(_poolConfig.MinPoolSize - currentSize, atLeastCount); var sessionsToCreate = Math.Min(sessionsNeeded, maxSessionsToCreate); - s_logger.LogDebug($"SessionPool - allowed to create {sessionsToCreate} sessions, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); + s_loggerPair.LogDebug($"SessionPool - allowed to create {sessionsToCreate} sessions, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); return sessionsToCreate; } - s_logger.LogDebug($"SessionPool - not allowed to create a session, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); + s_loggerPair.LogDebug($"SessionPool - not allowed to create a session, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); return 0; } @@ -267,7 +266,7 @@ private SFSession WaitForSession(string connStr) { if (TimeoutHelper.IsInfinite(_poolConfig.WaitingForIdleSessionTimeout)) throw new Exception("WaitingForIdleSessionTimeout cannot be infinite"); - s_logger.LogInformation($"SessionPool::WaitForSession for {(long) _poolConfig.WaitingForIdleSessionTimeout.TotalMilliseconds} ms timeout" + PoolIdentification()); + s_loggerPair.LogInformation($"SessionPool::WaitForSession for {(long) _poolConfig.WaitingForIdleSessionTimeout.TotalMilliseconds} ms timeout" + PoolIdentification()); _sessionPoolEventHandler.OnWaitingForSessionStarted(this); var beforeWaitingTimeMillis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); long nowTimeMillis = beforeWaitingTimeMillis; @@ -278,25 +277,25 @@ private SFSession WaitForSession(string connStr) var successful = _waitingForIdleSessionQueue.Wait((int) timeoutLeftMillis, CancellationToken.None); if (successful) { - s_logger.LogDebug($"SessionPool::WaitForSession - woken with a session granted" + PoolIdentification()); + s_loggerPair.LogDebug($"SessionPool::WaitForSession - woken with a session granted" + PoolIdentification()); _sessionPoolEventHandler.OnWaitingForSessionSuccessful(this); lock (_sessionPoolLock) { var session = ExtractIdleSession(connStr); if (session != null) { - s_logger.LogDebug("SessionPool::WaitForSession - provided an idle session" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::WaitForSession - provided an idle session" + PoolIdentification()); return session; } } } else { - s_logger.LogDebug("SessionPool::WaitForSession - woken without a session granted" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::WaitForSession - woken without a session granted" + PoolIdentification()); } nowTimeMillis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } - s_logger.LogInformation("SessionPool::WaitForSession - could not find any idle session available withing a given timeout" + PoolIdentification()); + s_loggerPair.LogInformation("SessionPool::WaitForSession - could not find any idle session available withing a given timeout" + PoolIdentification()); throw WaitingFailedException(); } @@ -318,7 +317,7 @@ private SFSession ExtractIdleSession(string connStr) } else { - s_logger.LogDebug($"reuse pooled session with sid {session.sessionId}" + PoolIdentification()); + s_loggerPair.LogDebug($"reuse pooled session with sid {session.sessionId}" + PoolIdentification()); _busySessionsCounter.Increase(); return session; } @@ -332,19 +331,19 @@ private SFSession NewNonPoolingSession(String connectionString, SecureString pas private SFSession NewSession(String connectionString, SecureString password, SessionCreationToken sessionCreationToken) { - s_logger.LogDebug("SessionPool::NewSession" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::NewSession" + PoolIdentification()); try { var session = s_sessionFactory.NewSession(connectionString, password); session.Open(); - s_logger.LogDebug("SessionPool::NewSession - opened" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::NewSession - opened" + PoolIdentification()); if (GetPooling() && !_underDestruction) { lock (_sessionPoolLock) { _sessionCreationTokenCounter.RemoveToken(sessionCreationToken); _busySessionsCounter.Increase(); - s_logger.LogDebug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); + s_loggerPair.LogDebug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); } } _sessionPoolEventHandler.OnNewSessionCreated(this); @@ -359,7 +358,7 @@ private SFSession NewSession(String connectionString, SecureString password, Ses { lock (_sessionPoolLock) { - s_logger.LogDebug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); + s_loggerPair.LogDebug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); } } if (e is SnowflakeDbException) @@ -380,7 +379,7 @@ private Task NewNonPoolingSessionAsync( private Task NewSessionAsync(String connectionString, SecureString password, SessionCreationToken sessionCreationToken, CancellationToken cancellationToken) { - s_logger.LogDebug("SessionPool::NewSessionAsync" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::NewSessionAsync" + PoolIdentification()); var session = s_sessionFactory.NewSession(connectionString, password); return session .OpenAsync(cancellationToken) @@ -393,7 +392,7 @@ private Task NewSessionAsync(String connectionString, SecureString pa { lock (_sessionPoolLock) { - s_logger.LogDebug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); + s_loggerPair.LogDebug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); } } } @@ -415,7 +414,7 @@ private Task NewSessionAsync(String connectionString, SecureString pa { _sessionCreationTokenCounter.RemoveToken(sessionCreationToken); _busySessionsCounter.Increase(); - s_logger.LogDebug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); + s_loggerPair.LogDebug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); } } @@ -428,19 +427,19 @@ private Task NewSessionAsync(String connectionString, SecureString pa internal void ReleaseBusySession(SFSession session) { - s_logger.LogDebug("SessionPool::ReleaseBusySession" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::ReleaseBusySession" + PoolIdentification()); SessionPoolState poolState; lock (_sessionPoolLock) { _busySessionsCounter.Decrease(); poolState = GetCurrentState(); } - s_logger.LogDebug($"After releasing a busy session from the pool {poolState}" + PoolIdentification()); + s_loggerPair.LogDebug($"After releasing a busy session from the pool {poolState}" + PoolIdentification()); } internal bool AddSession(SFSession session, bool ensureMinPoolSize) { - s_logger.LogDebug("SessionPool::AddSession" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::AddSession" + PoolIdentification()); if (!GetPooling() || _underDestruction) return false; @@ -449,7 +448,7 @@ internal bool AddSession(SFSession session, bool ensureMinPoolSize) session.SessionPropertiesChanged && _poolConfig.ChangedSession == ChangedSessionBehavior.Destroy) { - s_logger.LogDebug($"Session returning to pool was changed. Destroying the session: {session.sessionId}."); + s_loggerPair.LogDebug($"Session returning to pool was changed. Destroying the session: {session.sessionId}."); session.SetPooling(false); } @@ -482,7 +481,7 @@ private Tuple> ReturnSessionToPool(SFSession se ? RegisterSessionCreationsWhenReturningSessionToPool() : SessionOrCreationTokens.s_emptySessionCreationTokenList; var poolState = GetCurrentState(); - s_logger.LogDebug($"Could not return session to pool {poolState}" + PoolIdentification()); + s_loggerPair.LogDebug($"Could not return session to pool {poolState}" + PoolIdentification()); return Tuple.Create(false, sessionCreationTokens); } } @@ -497,13 +496,13 @@ private Tuple> ReturnSessionToPool(SFSession se ? RegisterSessionCreationsWhenReturningSessionToPool() : SessionOrCreationTokens.s_emptySessionCreationTokenList; var poolState = GetCurrentState(); - s_logger.LogDebug($"Could not return session to pool {poolState}" + PoolIdentification()); + s_loggerPair.LogDebug($"Could not return session to pool {poolState}" + PoolIdentification()); return Tuple.Create(false, sessionCreationTokens); } var poolStateBeforeReturningToPool = GetCurrentState(); if (poolStateBeforeReturningToPool.Count() >= _poolConfig.MaxPoolSize) { - s_logger.LogWarning($"Pool is full - unable to add session with sid {session.sessionId} {poolStateBeforeReturningToPool}"); + s_loggerPair.LogWarning($"Pool is full - unable to add session with sid {session.sessionId} {poolStateBeforeReturningToPool}"); return Tuple.Create(false, SessionOrCreationTokens.s_emptySessionCreationTokenList); } _idleSessions.Add(session); @@ -512,14 +511,14 @@ private Tuple> ReturnSessionToPool(SFSession se ? RegisterSessionCreationsWhenReturningSessionToPool() : SessionOrCreationTokens.s_emptySessionCreationTokenList; var poolStateAfterReturningToPool = GetCurrentState(); - s_logger.LogDebug($"returned session with sid {session.sessionId} to pool {poolStateAfterReturningToPool}" + PoolIdentification()); + s_loggerPair.LogDebug($"returned session with sid {session.sessionId} to pool {poolStateAfterReturningToPool}" + PoolIdentification()); return Tuple.Create(true, sessionCreationTokensAfterReturningToPool); } } internal void DestroyPool() { - s_logger.LogDebug("SessionPool::DestroyPool" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::DestroyPool" + PoolIdentification()); lock (_sessionPoolLock) { _underDestruction = true; @@ -532,7 +531,7 @@ internal void DestroyPool() internal void DestroyPoolAsync() { - s_logger.LogDebug("SessionPool::DestroyPoolAsync" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::DestroyPoolAsync" + PoolIdentification()); lock (_sessionPoolLock) { _underDestruction = true; @@ -545,7 +544,7 @@ internal void DestroyPoolAsync() internal void ClearSessions() { - s_logger.LogDebug($"SessionPool::ClearSessions" + PoolIdentification()); + s_loggerPair.LogDebug($"SessionPool::ClearSessions" + PoolIdentification()); lock (_sessionPoolLock) { _busySessionsCounter.Reset(); @@ -556,7 +555,7 @@ internal void ClearSessions() internal void ClearIdleSessions() { - s_logger.LogDebug("SessionPool::ClearIdleSessions" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::ClearIdleSessions" + PoolIdentification()); lock (_sessionPoolLock) { foreach (SFSession session in _idleSessions) @@ -569,7 +568,7 @@ internal void ClearIdleSessions() internal async void ClearIdleSessionsAsync() { - s_logger.LogDebug("SessionPool::ClearIdleSessionsAsync" + PoolIdentification()); + s_loggerPair.LogDebug("SessionPool::ClearIdleSessionsAsync" + PoolIdentification()); IEnumerable idleSessionsCopy; lock (_sessionPoolLock) { @@ -584,7 +583,7 @@ internal async void ClearIdleSessionsAsync() public void SetMaxPoolSize(int size) { - s_logger.LogDebug($"SessionPool::SetMaxPoolSize({size})" + PoolIdentification()); + s_loggerPair.LogDebug($"SessionPool::SetMaxPoolSize({size})" + PoolIdentification()); _poolConfig.MaxPoolSize = size; _configOverriden = true; } @@ -615,7 +614,7 @@ public long GetConnectionTimeout() public void SetTimeout(long seconds) { - s_logger.LogDebug($"SessionPool::SetTimeout({seconds})" + PoolIdentification()); + s_loggerPair.LogDebug($"SessionPool::SetTimeout({seconds})" + PoolIdentification()); var timeout = seconds < 0 ? TimeoutHelper.Infinity() : TimeSpan.FromSeconds(seconds); _poolConfig.ExpirationTimeout = timeout; _configOverriden = true; @@ -644,7 +643,7 @@ public SessionPoolState GetCurrentState() public bool SetPooling(bool isEnable) { - s_logger.LogInformation($"SessionPool::SetPooling({isEnable})" + PoolIdentification()); + s_loggerPair.LogInformation($"SessionPool::SetPooling({isEnable})" + PoolIdentification()); if (_poolConfig.PoolingEnabled == isEnable) return false; _poolConfig.PoolingEnabled = isEnable; diff --git a/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs b/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs index 0d4e393cc..6d77a512a 100644 --- a/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs +++ b/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs @@ -3,13 +3,12 @@ using System.Text.RegularExpressions; using Snowflake.Data.Core.Tools; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Session { internal class SessionPropertiesWithDefaultValuesExtractor { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private static readonly Regex s_timeoutFormatRegex = new Regex(@"^(-)?[0-9]{1,10}[mM]?[sS]?$"); private readonly SFSessionProperties _propertiesDictionary; @@ -72,7 +71,7 @@ public T ExtractPropertyWithDefaultValue( var valueString = _propertiesDictionary[property]; if (string.IsNullOrEmpty(valueString)) { - s_logger.LogWarning($"Parameter {property} not defined. Using a default value: {defaultValue}"); + s_loggerPair.LogWarning($"Parameter {property} not defined. Using a default value: {defaultValue}"); return defaultValue; } if (!preExtractValidation(valueString)) @@ -88,10 +87,10 @@ public T ExtractPropertyWithDefaultValue( { if (_failOnWrongValue) { - s_logger.LogError($"Invalid value of parameter {property}. Error: {e}"); + s_loggerPair.LogError($"Invalid value of parameter {property}. Error: {e}"); throw new Exception($"Invalid value of parameter {property}", e); } - s_logger.LogWarning($"Invalid value of parameter {property}. Using a default a default value: {defaultValue}"); + s_loggerPair.LogWarning($"Invalid value of parameter {property}. Using a default a default value: {defaultValue}"); return defaultValue; } if (!postExtractValidation(value)) @@ -108,10 +107,10 @@ private TResult handleFailedValidation( { if (_failOnWrongValue) { - s_logger.LogError($"Invalid value of parameter {property}: {value}"); + s_loggerPair.LogError($"Invalid value of parameter {property}: {value}"); throw new Exception($"Invalid value of parameter {property}"); } - s_logger.LogWarning($"Invalid value of parameter {property}. Using a default value: {defaultValue}"); + s_loggerPair.LogWarning($"Invalid value of parameter {property}. Using a default value: {defaultValue}"); return defaultValue; } diff --git a/Snowflake.Data/Core/TomlConnectionBuilder.cs b/Snowflake.Data/Core/TomlConnectionBuilder.cs index 5bbe0c2d6..f8bdaead9 100644 --- a/Snowflake.Data/Core/TomlConnectionBuilder.cs +++ b/Snowflake.Data/Core/TomlConnectionBuilder.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Security; using System.Text; -using Microsoft.Extensions.Logging; using Mono.Unix; using Mono.Unix.Native; using Snowflake.Data.Client; @@ -28,7 +27,7 @@ internal class TomlConnectionBuilder internal const string SnowflakeDefaultConnectionName = "SNOWFLAKE_DEFAULT_CONNECTION_NAME"; internal const string SnowflakeHome = "SNOWFLAKE_HOME"; - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); private readonly Dictionary _tomlToNetPropertiesMapper = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { @@ -54,7 +53,7 @@ public string GetConnectionStringFromToml(string connectionName = null) { var tomlPath = ResolveConnectionTomlFile(); var connectionToml = GetTomlTableFromConfig(tomlPath, connectionName); - s_logger.LogInformation($"Reading connection parameters from file using key: {connectionName} and path: {tomlPath}"); + s_loggerPair.LogInformation($"Reading connection parameters from file using key: {connectionName} and path: {tomlPath}"); return connectionToml == null ? string.Empty : GetConnectionStringFromTomlTable(connectionToml); } @@ -87,7 +86,7 @@ private void AppendTokenFromFileIfNotGivenExplicitly(TomlTable connectionToml, b return; } - s_logger.LogInformation($"Trying to load token from file {tokenFilePathValue}"); + s_loggerPair.LogInformation($"Trying to load token from file {tokenFilePathValue}"); var token = LoadTokenFromFile(tokenFilePathValue); if (!string.IsNullOrEmpty(token)) { @@ -95,7 +94,7 @@ private void AppendTokenFromFileIfNotGivenExplicitly(TomlTable connectionToml, b } else { - s_logger.LogWarning("The token has empty value"); + s_loggerPair.LogWarning("The token has empty value"); } } @@ -110,13 +109,13 @@ private string LoadTokenFromFile(string tokenFilePathValue) { if (!_fileOperations.Exists(tokenFilePathValue)) { - s_logger.LogInformation($"Specified token file {tokenFilePathValue} does not exists."); + s_loggerPair.LogInformation($"Specified token file {tokenFilePathValue} does not exists."); throw new SnowflakeDbException(SFError.INVALID_CONNECTION_PARAMETER_VALUE, tokenFilePathValue, "token_file_path"); } tokenFile = tokenFilePathValue; } - s_logger.LogInformation($"Read token from file path: {tokenFile}"); + s_loggerPair.LogInformation($"Read token from file path: {tokenFile}"); return _fileOperations.Exists(tokenFile) ? _fileOperations.ReadAllText(tokenFile, ValidateFilePermissions) : null; } diff --git a/Snowflake.Data/Core/Tools/Diagnostics.cs b/Snowflake.Data/Core/Tools/Diagnostics.cs index f6faa39de..f6117d0bc 100644 --- a/Snowflake.Data/Core/Tools/Diagnostics.cs +++ b/Snowflake.Data/Core/Tools/Diagnostics.cs @@ -4,16 +4,15 @@ using System.Runtime.InteropServices; using System.Text; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Tools { internal class Diagnostics { private const int PadRight = -25; - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); - public static void LogDiagnostics() => s_logger.LogInformation(GetDiagnosticInfo()); + public static void LogDiagnostics() => s_loggerPair.LogInformation(GetDiagnosticInfo()); private static string GetDiagnosticInfo() { @@ -40,7 +39,7 @@ private static string GetDiagnosticInfo() catch (Exception exception) { var errorMessage = $"Error caught while collecting diagnostic info: {exception.Message}"; - s_logger.LogError(errorMessage, exception); + s_loggerPair.LogError(errorMessage, exception); info.AppendLine(errorMessage); } return info.ToString(); diff --git a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs index da501edb7..f5c6a536e 100644 --- a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs +++ b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs @@ -5,14 +5,13 @@ using System; using System.IO; using Snowflake.Data.Log; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Tools { internal class EnvironmentOperations { public static readonly EnvironmentOperations Instance = new EnvironmentOperations(); - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); public virtual string GetEnvironmentVariable(string variable) { @@ -30,7 +29,7 @@ public virtual string GetExecutionDirectory() var directoryName = string.IsNullOrEmpty(executablePath) ? null : Path.GetDirectoryName(executablePath); if (string.IsNullOrEmpty(directoryName)) { - s_logger.LogWarning("Unable to determine execution directory"); + s_loggerPair.LogWarning("Unable to determine execution directory"); return null; } return directoryName; diff --git a/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs b/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs index d22380c9d..3e9b28598 100644 --- a/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs +++ b/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs @@ -4,13 +4,12 @@ using Snowflake.Data.Log; using System; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Core.Tools { internal class HomeDirectoryProvider { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); public static string HomeDirectory(EnvironmentOperations _environmentOperations) { try @@ -24,7 +23,7 @@ public static string HomeDirectory(EnvironmentOperations _environmentOperations) } catch (Exception e) { - s_logger.LogError($"Error while trying to retrieve the home directory: {e}"); + s_loggerPair.LogError($"Error while trying to retrieve the home directory: {e}"); return null; } } diff --git a/Snowflake.Data/Logger/SFAppenderImpl.cs b/Snowflake.Data/Logger/SFAppenderImpl.cs index 9b44285f3..38ee5089b 100644 --- a/Snowflake.Data/Logger/SFAppenderImpl.cs +++ b/Snowflake.Data/Logger/SFAppenderImpl.cs @@ -58,6 +58,7 @@ public SFRollingFileAppender() { } public void Append(string logLevel, string message, Type type, Exception ex = null) { + var formattedMessage = _patternLayout.Format(logLevel, message, type); try { if (LogFileIsTooLarge()) @@ -65,19 +66,22 @@ public void Append(string logLevel, string message, Type type, Exception ex = nu RollLogFile(); } - var formattedMessage = _patternLayout.Format(logLevel, message, type); - using (var writer = new StreamWriter(_logFilePath, true)) + using (FileStream fs = new FileStream(_logFilePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) { - writer.Write(formattedMessage); - if (ex != null) + using (var writer = new StreamWriter(fs)) { - writer.WriteLine(ex.Message); + writer.Write(formattedMessage); + if (ex != null) + { + writer.WriteLine(ex.Message); + } } } } catch (Exception logEx) { - Console.WriteLine($"Failed to log message: {logEx.Message}"); + Console.WriteLine($"Unable to log the following message:\n{formattedMessage}" + + $"Due to the error: {logEx.Message}\n"); } } @@ -90,8 +94,7 @@ public void ActivateOptions() } if (!File.Exists(_logFilePath)) { - var file = File.Create(_logFilePath); - file.Close(); + File.Create(_logFilePath).Dispose(); } } diff --git a/Snowflake.Data/Logger/SFLoggerPair.cs b/Snowflake.Data/Logger/SFLoggerPair.cs index a0f49e497..ef9f5d02a 100644 --- a/Snowflake.Data/Logger/SFLoggerPair.cs +++ b/Snowflake.Data/Logger/SFLoggerPair.cs @@ -3,46 +3,54 @@ */ using Microsoft.Extensions.Logging; -using Snowflake.Data.Log; using System; -public class SFLoggerPair +namespace Snowflake.Data.Log { - private static SFLogger s_snowflakeLogger; - private static ILogger s_customLogger; - - SFLoggerPair(SFLogger snowflakLogger, ILogger customLogger) - { - s_snowflakeLogger = snowflakLogger; - s_customLogger = customLogger; - } - - internal static SFLoggerPair GetLoggerPair() - { - return new SFLoggerPair(SFLoggerFactory.GetSFLogger(), SFLoggerFactory.GetCustomLogger()); - } - - internal void LogDebug(string message, Exception ex = null) - { - s_snowflakeLogger.Debug(message, ex); - s_customLogger.LogDebug(message, ex); - } - - internal void LogInformation(string message, Exception ex = null) - { - s_snowflakeLogger.Information(message, ex); - s_customLogger.LogInformation(message, ex); - } - - internal void LogWarning(string message, Exception ex = null) - { - s_snowflakeLogger.Warning(message, ex); - s_customLogger.LogWarning(message, ex); - } - - internal void LogError(string message, Exception ex = null) + public class SFLoggerPair { - s_snowflakeLogger.Error(message, ex); - s_customLogger.LogError(message, ex); + private static SFLogger s_snowflakeLogger; + private static ILogger s_customLogger; + + SFLoggerPair(SFLogger snowflakLogger, ILogger customLogger) + { + s_snowflakeLogger = snowflakLogger; + s_customLogger = customLogger; + } + + internal static SFLoggerPair GetLoggerPair() + { + return new SFLoggerPair(SFLoggerFactory.GetSFLogger(), SFLoggerFactory.GetCustomLogger()); + } + + internal void LogDebug(string message, Exception ex = null) + { + s_snowflakeLogger.Debug(message, ex); + s_customLogger.LogDebug(message, ex); + } + + internal void LogInformation(string message, Exception ex = null) + { + s_snowflakeLogger.Information(message, ex); + s_customLogger.LogInformation(message, ex); + } + + internal void LogWarning(string message, Exception ex = null) + { + s_snowflakeLogger.Warning(message, ex); + s_customLogger.LogWarning(message, ex); + } + + internal void LogError(string message, Exception ex = null) + { + s_snowflakeLogger.Error(message, ex); + s_customLogger.LogError(message, ex); + } + + internal bool IsDebugEnabled() + { + return s_snowflakeLogger.IsDebugEnabled() || + s_customLogger.IsEnabled(LogLevel.Debug); + } } } From 7e8af5c984fd14e062ab45806d2ea777ce44ced4 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Wed, 4 Dec 2024 23:35:41 -0800 Subject: [PATCH 18/35] Fix format error with bracket --- Snowflake.Data/Logger/SFLoggerPair.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Snowflake.Data/Logger/SFLoggerPair.cs b/Snowflake.Data/Logger/SFLoggerPair.cs index ef9f5d02a..f8c64c0b3 100644 --- a/Snowflake.Data/Logger/SFLoggerPair.cs +++ b/Snowflake.Data/Logger/SFLoggerPair.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging; using System; +using System.Text; namespace Snowflake.Data.Log { @@ -26,7 +27,7 @@ internal static SFLoggerPair GetLoggerPair() internal void LogDebug(string message, Exception ex = null) { s_snowflakeLogger.Debug(message, ex); - s_customLogger.LogDebug(message, ex); + s_customLogger.LogDebug(FormatBrackets(message), ex); } internal void LogInformation(string message, Exception ex = null) @@ -52,5 +53,11 @@ internal bool IsDebugEnabled() return s_snowflakeLogger.IsDebugEnabled() || s_customLogger.IsEnabled(LogLevel.Debug); } + + private string FormatBrackets(string message) + { + var sb = new StringBuilder(message).Replace("{", "{{").Replace("}", "}}"); + return sb.ToString(); + } } } From d6090aaa369bc0c1035f8f810817cb98b6b40862 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 14:38:47 -0800 Subject: [PATCH 19/35] Move masking secrets --- Snowflake.Data/Logger/SFLoggerImpl.cs | 5 ----- Snowflake.Data/Logger/SFLoggerPair.cs | 4 ++++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Snowflake.Data/Logger/SFLoggerImpl.cs b/Snowflake.Data/Logger/SFLoggerImpl.cs index 5fa4b0431..91f934fb5 100644 --- a/Snowflake.Data/Logger/SFLoggerImpl.cs +++ b/Snowflake.Data/Logger/SFLoggerImpl.cs @@ -127,7 +127,6 @@ public void Debug(string msg, Exception ex = null) { if (IsDebugEnabled()) { - msg = SecretDetector.MaskSecrets(msg).maskedText; Log(LoggingEvent.DEBUG.ToString(), msg, ex); } } @@ -136,7 +135,6 @@ public void Information(string msg, Exception ex = null) { if (IsInformationEnabled()) { - msg = SecretDetector.MaskSecrets(msg).maskedText; Log(LoggingEvent.INFO.ToString(), msg, ex); } } @@ -145,7 +143,6 @@ public void Warning(string msg, Exception ex = null) { if (IsWarningEnabled()) { - msg = SecretDetector.MaskSecrets(msg).maskedText; Log(LoggingEvent.WARN.ToString(), msg, ex); } } @@ -155,7 +152,6 @@ public void Error(string msg, Exception ex = null) { if (IsErrorEnabled()) { - msg = SecretDetector.MaskSecrets(msg).maskedText; Log(LoggingEvent.ERROR.ToString(), msg, ex); } } @@ -164,7 +160,6 @@ public void Fatal(string msg, Exception ex = null) { if (IsFatalEnabled()) { - msg = SecretDetector.MaskSecrets(msg).maskedText; Log(LoggingEvent.FATAL.ToString(), msg, ex); } } diff --git a/Snowflake.Data/Logger/SFLoggerPair.cs b/Snowflake.Data/Logger/SFLoggerPair.cs index f8c64c0b3..4ada281ac 100644 --- a/Snowflake.Data/Logger/SFLoggerPair.cs +++ b/Snowflake.Data/Logger/SFLoggerPair.cs @@ -26,24 +26,28 @@ internal static SFLoggerPair GetLoggerPair() internal void LogDebug(string message, Exception ex = null) { + message = SecretDetector.MaskSecrets(message).maskedText; s_snowflakeLogger.Debug(message, ex); s_customLogger.LogDebug(FormatBrackets(message), ex); } internal void LogInformation(string message, Exception ex = null) { + message = SecretDetector.MaskSecrets(message).maskedText; s_snowflakeLogger.Information(message, ex); s_customLogger.LogInformation(message, ex); } internal void LogWarning(string message, Exception ex = null) { + message = SecretDetector.MaskSecrets(message).maskedText; s_snowflakeLogger.Warning(message, ex); s_customLogger.LogWarning(message, ex); } internal void LogError(string message, Exception ex = null) { + message = SecretDetector.MaskSecrets(message).maskedText; s_snowflakeLogger.Error(message, ex); s_customLogger.LogError(message, ex); } From a7535dca05824d56f1b2976c4f522cbd240b8156 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 14:39:58 -0800 Subject: [PATCH 20/35] Fix typo --- Snowflake.Data/Logger/SFLoggerPair.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Snowflake.Data/Logger/SFLoggerPair.cs b/Snowflake.Data/Logger/SFLoggerPair.cs index 4ada281ac..8aafde022 100644 --- a/Snowflake.Data/Logger/SFLoggerPair.cs +++ b/Snowflake.Data/Logger/SFLoggerPair.cs @@ -13,9 +13,9 @@ public class SFLoggerPair private static SFLogger s_snowflakeLogger; private static ILogger s_customLogger; - SFLoggerPair(SFLogger snowflakLogger, ILogger customLogger) + SFLoggerPair(SFLogger snowflakeLogger, ILogger customLogger) { - s_snowflakeLogger = snowflakLogger; + s_snowflakeLogger = snowflakeLogger; s_customLogger = customLogger; } From 26a5d537b4e3b422c350fda70b60a8721fc96665 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 15:38:40 -0800 Subject: [PATCH 21/35] Refactor SFLoggerPair --- .../UnitTests/Logger/EasyLoggerManagerTest.cs | 24 +-- .../UnitTests/Logger/SFLoggerPairTest.cs | 140 ++++++++++++++++++ .../UnitTests/Logger/SFLoggerTest.cs | 14 +- Snowflake.Data/Client/SnowflakeDbCommand.cs | 32 ++-- .../Client/SnowflakeDbConnection.cs | 46 +++--- .../Client/SnowflakeDbConnectionPool.cs | 36 ++--- .../Client/SnowflakeDbDataReader.cs | 2 +- .../Client/SnowflakeDbTransaction.cs | 12 +- .../Configuration/EasyLoggingConfigFinder.cs | 6 +- .../Configuration/EasyLoggingConfigParser.cs | 2 +- Snowflake.Data/Core/ArrowResultSet.cs | 10 +- .../Core/Authenticator/BasicAuthenticator.cs | 2 +- .../ExternalBrowserAuthenticator.cs | 32 ++-- .../Core/Authenticator/IAuthenticator.cs | 12 +- .../Authenticator/KeyPairAuthenticator.cs | 10 +- .../Core/Authenticator/OAuthAuthenticator.cs | 4 +- .../Core/Authenticator/OktaAuthenticator.cs | 56 +++---- Snowflake.Data/Core/ChunkDownloaderFactory.cs | 6 +- Snowflake.Data/Core/ChunkParserFactory.cs | 6 +- .../StructuredTypesReadingHandler.cs | 6 +- Snowflake.Data/Core/FastParser.cs | 8 +- .../Core/FileTransfer/EncryptionProvider.cs | 4 +- .../FileTransfer/GcmEncryptionProvider.cs | 4 +- .../Core/FileTransfer/SFFileTransferAgent.cs | 56 +++---- .../FileTransfer/StorageClient/SFGCSClient.cs | 16 +- .../FileTransfer/StorageClient/SFS3Client.cs | 10 +- .../StorageClient/SFSnowflakeAzureClient.cs | 4 +- Snowflake.Data/Core/HttpUtil.cs | 36 ++--- Snowflake.Data/Core/QueryContextCache.cs | 24 +-- Snowflake.Data/Core/QueryResultsAwaiter.cs | 10 +- Snowflake.Data/Core/RestRequester.cs | 8 +- Snowflake.Data/Core/SFBindUploader.cs | 6 +- .../Core/SFBlockingChunkDownloaderV3.cs | 10 +- .../Core/SFMultiStatementsResultSet.cs | 2 +- Snowflake.Data/Core/SFResultSet.cs | 10 +- Snowflake.Data/Core/SFResultSetMetaData.cs | 4 +- Snowflake.Data/Core/SFStatement.cs | 40 ++--- .../Core/Session/ConnectionPoolManager.cs | 26 ++-- .../Core/Session/EasyLoggingStarter.cs | 16 +- Snowflake.Data/Core/Session/SFSession.cs | 58 ++++---- .../Session/SFSessionHttpClientProperties.cs | 26 ++-- .../Core/Session/SFSessionProperty.cs | 34 ++--- Snowflake.Data/Core/Session/SessionPool.cs | 90 +++++------ ...ionPropertiesWithDefaultValuesExtractor.cs | 12 +- Snowflake.Data/Core/TomlConnectionBuilder.cs | 12 +- Snowflake.Data/Core/Tools/Diagnostics.cs | 6 +- .../Core/Tools/EnvironmentOperations.cs | 4 +- .../Core/Tools/HomeDirectoryProvider.cs | 4 +- Snowflake.Data/Logger/SFLogger.cs | 10 +- Snowflake.Data/Logger/SFLoggerEmptyImpl.cs | 8 +- Snowflake.Data/Logger/SFLoggerFactory.cs | 5 + Snowflake.Data/Logger/SFLoggerImpl.cs | 16 +- Snowflake.Data/Logger/SFLoggerPair.cs | 75 ++++++++-- 53 files changed, 652 insertions(+), 460 deletions(-) create mode 100644 Snowflake.Data.Tests/UnitTests/Logger/SFLoggerPairTest.cs diff --git a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs index 57d0cb1a6..b3aaab92e 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/EasyLoggerManagerTest.cs @@ -56,8 +56,8 @@ public void TestThatChangesLogLevel() // assert Assert.IsFalse(logger.IsDebugEnabled()); - Assert.IsFalse(logger.IsInformationEnabled()); - Assert.IsFalse(logger.IsWarningEnabled()); + Assert.IsFalse(logger.IsInfoEnabled()); + Assert.IsFalse(logger.IsWarnEnabled()); Assert.IsFalse(logger.IsErrorEnabled()); Assert.IsFalse(logger.IsFatalEnabled()); @@ -66,8 +66,8 @@ public void TestThatChangesLogLevel() // assert Assert.IsFalse(logger.IsDebugEnabled()); - Assert.IsFalse(logger.IsInformationEnabled()); - Assert.IsFalse(logger.IsWarningEnabled()); + Assert.IsFalse(logger.IsInfoEnabled()); + Assert.IsFalse(logger.IsWarnEnabled()); Assert.IsFalse(logger.IsErrorEnabled()); Assert.IsTrue(logger.IsFatalEnabled()); @@ -76,8 +76,8 @@ public void TestThatChangesLogLevel() // assert Assert.IsFalse(logger.IsDebugEnabled()); - Assert.IsFalse(logger.IsInformationEnabled()); - Assert.IsFalse(logger.IsWarningEnabled()); + Assert.IsFalse(logger.IsInfoEnabled()); + Assert.IsFalse(logger.IsWarnEnabled()); Assert.IsTrue(logger.IsErrorEnabled()); Assert.IsTrue(logger.IsFatalEnabled()); @@ -86,8 +86,8 @@ public void TestThatChangesLogLevel() // assert Assert.IsFalse(logger.IsDebugEnabled()); - Assert.IsFalse(logger.IsInformationEnabled()); - Assert.IsTrue(logger.IsWarningEnabled()); + Assert.IsFalse(logger.IsInfoEnabled()); + Assert.IsTrue(logger.IsWarnEnabled()); Assert.IsTrue(logger.IsErrorEnabled()); Assert.IsTrue(logger.IsFatalEnabled()); @@ -96,8 +96,8 @@ public void TestThatChangesLogLevel() // assert Assert.IsTrue(logger.IsDebugEnabled()); - Assert.IsTrue(logger.IsInformationEnabled()); - Assert.IsTrue(logger.IsWarningEnabled()); + Assert.IsTrue(logger.IsInfoEnabled()); + Assert.IsTrue(logger.IsWarnEnabled()); Assert.IsTrue(logger.IsErrorEnabled()); Assert.IsTrue(logger.IsFatalEnabled()); } @@ -111,8 +111,8 @@ public void TestThatLogsToProperFileWithProperLogLevelOnly() // act logger.Debug(DebugMessage); - logger.Information(InfoMessage); - logger.Warning(WarnMessage); + logger.Info(InfoMessage); + logger.Warn(WarnMessage); logger.Error(ErrorMessage); logger.Fatal(FatalMessage); diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerPairTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerPairTest.cs new file mode 100644 index 000000000..f577a640e --- /dev/null +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerPairTest.cs @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. + */ + +using NUnit.Framework; +using Snowflake.Data.Configuration; +using Snowflake.Data.Log; +using System; + +namespace Snowflake.Data.Tests.UnitTests +{ + [TestFixture, NonParallelizable] + class SFLoggerPairTest + { + SFLogger _loggerPair; + + [OneTimeSetUp] + public static void BeforeAll() + { + // Log level defaults to Warn on net6.0 builds in github actions + // Set the root level to Debug + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Debug, "STDOUT"); + } + + [OneTimeTearDown] + public static void AfterAll() + { + EasyLoggerManager.Instance.ReconfigureEasyLogging(EasyLoggingLogLevel.Warn, "STDOUT"); + } + + [SetUp] + public void BeforeTest() + { + _loggerPair = SFLoggerFactory.GetLogger(); + } + + [TearDown] + public void AfterTest() + { + // Return to default setting + SFLoggerFactory.EnableSFLogger(); + } + + [Test] + public void TestUsingSFLogger() + { + SFLoggerFactory.EnableSFLogger(); + _loggerPair = SFLoggerFactory.GetLogger(); + Assert.IsInstanceOf(_loggerPair); + } + + [Test] + public void TestIsDebugEnabled( + [Values(false, true)] bool isEnabled) + { + _loggerPair = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _loggerPair.IsDebugEnabled()); + _loggerPair.Debug("debug log message", new Exception("test exception")); + } + + [Test] + public void TestIsInfoEnabled( + [Values(false, true)] bool isEnabled) + { + _loggerPair = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _loggerPair.IsInfoEnabled()); + _loggerPair.Info("info log message", new Exception("test exception")); + } + + [Test] + public void TestIsWarnEnabled( + [Values(false, true)] bool isEnabled) + { + _loggerPair = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _loggerPair.IsWarnEnabled()); + _loggerPair.Warn("warn log message", new Exception("test exception")); + } + + [Test] + public void TestIsErrorEnabled( + [Values(false, true)] bool isEnabled) + { + _loggerPair = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _loggerPair.IsErrorEnabled()); + _loggerPair.Error("error log message", new Exception("test exception")); + } + + [Test] + public void TestIsFatalEnabled( + [Values(false, true)] bool isEnabled) + { + _loggerPair = GetLogger(isEnabled); + + Assert.AreEqual(isEnabled, _loggerPair.IsFatalEnabled()); + _loggerPair.Fatal("fatal log message", new Exception("test exception")); + } + + [Test] + public void TestGetAppenders() + { + Assert.Throws(() => _loggerPair.GetAppenders()); + } + + [Test] + public void TestAddAppender() + { + Assert.Throws(() => _loggerPair.AddAppender(new SFConsoleAppender())); + } + + [Test] + public void TestRemoveAppender() + { + Assert.Throws(() => _loggerPair.RemoveAppender(new SFConsoleAppender())); + } + + [Test] + public void TestSetLevel() + { + Assert.Throws(() => _loggerPair.SetLevel(LoggingEvent.DEBUG)); + } + + private SFLogger GetLogger(bool isEnabled) + { + if (isEnabled) + { + SFLoggerFactory.EnableSFLogger(); + } + else + { + SFLoggerFactory.DisableSFLogger(); + } + + return SFLoggerFactory.GetLogger(); + } + } +} diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs index c217dfeba..9910484e1 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs @@ -39,7 +39,7 @@ public void AfterTest() public void TestUsingSFLogger() { SFLoggerFactory.EnableSFLogger(); - _logger = SFLoggerFactory.GetSFLogger(); + _logger = SFLoggerFactory.GetSFLogger(); Assert.IsInstanceOf(_logger); } @@ -47,7 +47,7 @@ public void TestUsingSFLogger() public void TestUsingEmptyLogger() { SFLoggerFactory.DisableSFLogger(); - _logger = SFLoggerFactory.GetSFLogger(); + _logger = SFLoggerFactory.GetSFLogger(); Assert.IsInstanceOf(_logger); } @@ -67,8 +67,8 @@ public void TestIsInfoEnabled( { _logger = GetLogger(isEnabled); - Assert.AreEqual(isEnabled, _logger.IsInformationEnabled()); - _logger.Information("info log message", new Exception("test exception")); + Assert.AreEqual(isEnabled, _logger.IsInfoEnabled()); + _logger.Info("info log message", new Exception("test exception")); } [Test] @@ -77,8 +77,8 @@ public void TestIsWarnEnabled( { _logger = GetLogger(isEnabled); - Assert.AreEqual(isEnabled, _logger.IsWarningEnabled()); - _logger.Warning("warn log message", new Exception("test exception")); + Assert.AreEqual(isEnabled, _logger.IsWarnEnabled()); + _logger.Warn("warn log message", new Exception("test exception")); } [Test] @@ -180,7 +180,7 @@ private SFLogger GetLogger(bool isEnabled) SFLoggerFactory.DisableSFLogger(); } - return SFLoggerFactory.GetSFLogger(false); + return SFLoggerFactory.GetSFLogger(false); } } } diff --git a/Snowflake.Data/Client/SnowflakeDbCommand.cs b/Snowflake.Data/Client/SnowflakeDbCommand.cs index 22a4e53ed..b470f1601 100755 --- a/Snowflake.Data/Client/SnowflakeDbCommand.cs +++ b/Snowflake.Data/Client/SnowflakeDbCommand.cs @@ -22,13 +22,13 @@ public class SnowflakeDbCommand : DbCommand private SnowflakeDbParameterCollection parameterCollection; - private SFLoggerPair _loggerPair = SFLoggerPair.GetLoggerPair(); + private SFLogger _logger = SFLoggerFactory.GetLogger(); private readonly QueryResultsAwaiter _queryResultsAwaiter = QueryResultsAwaiter.Instance; public SnowflakeDbCommand() { - _loggerPair.LogDebug("Constructing SnowflakeDbCommand class"); + _logger.Debug("Constructing SnowflakeDbCommand class"); // by default, no query timeout this.CommandTimeout = 0; parameterCollection = new SnowflakeDbParameterCollection(); @@ -165,7 +165,7 @@ public override void Cancel() public override int ExecuteNonQuery() { - _loggerPair.LogDebug($"ExecuteNonQuery"); + _logger.Debug($"ExecuteNonQuery"); SFBaseResultSet resultSet = ExecuteInternal(); long total = 0; do @@ -190,7 +190,7 @@ public override int ExecuteNonQuery() public override async Task ExecuteNonQueryAsync(CancellationToken cancellationToken) { - _loggerPair.LogDebug($"ExecuteNonQueryAsync"); + _logger.Debug($"ExecuteNonQueryAsync"); cancellationToken.ThrowIfCancellationRequested(); var resultSet = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -217,7 +217,7 @@ public override async Task ExecuteNonQueryAsync(CancellationToken cancellat public override object ExecuteScalar() { - _loggerPair.LogDebug($"ExecuteScalar"); + _logger.Debug($"ExecuteScalar"); SFBaseResultSet resultSet = ExecuteInternal(); if(resultSet.Next()) @@ -228,7 +228,7 @@ public override object ExecuteScalar() public override async Task ExecuteScalarAsync(CancellationToken cancellationToken) { - _loggerPair.LogDebug($"ExecuteScalarAsync"); + _logger.Debug($"ExecuteScalarAsync"); cancellationToken.ThrowIfCancellationRequested(); var result = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -263,14 +263,14 @@ protected override DbParameter CreateDbParameter() protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) { - _loggerPair.LogDebug($"ExecuteDbDataReader"); + _logger.Debug($"ExecuteDbDataReader"); SFBaseResultSet resultSet = ExecuteInternal(); return new SnowflakeDbDataReader(this, resultSet); } protected override async Task ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) { - _loggerPair.LogDebug($"ExecuteDbDataReaderAsync"); + _logger.Debug($"ExecuteDbDataReaderAsync"); try { var result = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -278,7 +278,7 @@ protected override async Task ExecuteDbDataReaderAsync(CommandBeha } catch (Exception ex) { - _loggerPair.LogError("The command failed to execute.", ex); + _logger.Error("The command failed to execute.", ex); throw; } } @@ -290,7 +290,7 @@ protected override async Task ExecuteDbDataReaderAsync(CommandBeha /// The query id. public string ExecuteInAsyncMode() { - _loggerPair.LogDebug($"ExecuteInAsyncMode"); + _logger.Debug($"ExecuteInAsyncMode"); SFBaseResultSet resultSet = ExecuteInternal(asyncExec: true); return resultSet.queryId; } @@ -303,7 +303,7 @@ public string ExecuteInAsyncMode() /// The query id. public async Task ExecuteAsyncInAsyncMode(CancellationToken cancellationToken) { - _loggerPair.LogDebug($"ExecuteAsyncInAsyncMode"); + _logger.Debug($"ExecuteAsyncInAsyncMode"); var resultSet = await ExecuteInternalAsync(cancellationToken, asyncExec: true).ConfigureAwait(false); return resultSet.queryId; } @@ -315,7 +315,7 @@ public async Task ExecuteAsyncInAsyncMode(CancellationToken cancellation /// The query status. public QueryStatus GetQueryStatus(string queryId) { - _loggerPair.LogDebug($"GetQueryStatus"); + _logger.Debug($"GetQueryStatus"); return _queryResultsAwaiter.GetQueryStatus(connection, queryId); } @@ -327,7 +327,7 @@ public QueryStatus GetQueryStatus(string queryId) /// The query status. public async Task GetQueryStatusAsync(string queryId, CancellationToken cancellationToken) { - _loggerPair.LogDebug($"GetQueryStatusAsync"); + _logger.Debug($"GetQueryStatusAsync"); return await _queryResultsAwaiter.GetQueryStatusAsync(connection, queryId, cancellationToken); } @@ -338,7 +338,7 @@ public async Task GetQueryStatusAsync(string queryId, CancellationT /// The query results. public DbDataReader GetResultsFromQueryId(string queryId) { - _loggerPair.LogDebug($"GetResultsFromQueryId"); + _logger.Debug($"GetResultsFromQueryId"); Task task = _queryResultsAwaiter.RetryUntilQueryResultIsAvailable(connection, queryId, CancellationToken.None, false); task.Wait(); @@ -356,7 +356,7 @@ public DbDataReader GetResultsFromQueryId(string queryId) /// The query results. public async Task GetResultsFromQueryIdAsync(string queryId, CancellationToken cancellationToken) { - _loggerPair.LogDebug($"GetResultsFromQueryIdAsync"); + _logger.Debug($"GetResultsFromQueryIdAsync"); await _queryResultsAwaiter.RetryUntilQueryResultIsAvailable(connection, queryId, cancellationToken, true); @@ -464,7 +464,7 @@ private void CheckIfCommandTextIsSet() if (string.IsNullOrEmpty(CommandText)) { var errorMessage = "Unable to execute command due to command text not being set"; - _loggerPair.LogError(errorMessage); + _logger.Error(errorMessage); throw new Exception(errorMessage); } } diff --git a/Snowflake.Data/Client/SnowflakeDbConnection.cs b/Snowflake.Data/Client/SnowflakeDbConnection.cs index 205308eda..baf71a6b7 100755 --- a/Snowflake.Data/Client/SnowflakeDbConnection.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnection.cs @@ -16,7 +16,7 @@ namespace Snowflake.Data.Client [System.ComponentModel.DesignerCategory("Code")] public class SnowflakeDbConnection : DbConnection { - private SFLoggerPair _loggerPair = SFLoggerPair.GetLoggerPair(); + private SFLogger _logger = SFLoggerFactory.GetLogger(); internal SFSession SfSession { get; set; } @@ -120,7 +120,7 @@ public void PreventPooling() throw new Exception("Session not yet created for this connection. Unable to prevent the session from pooling"); } SfSession.SetPooling(false); - _loggerPair.LogDebug($"Session {SfSession.sessionId} marked not to be pooled any more"); + _logger.Debug($"Session {SfSession.sessionId} marked not to be pooled any more"); } internal bool HasActiveExplicitTransaction() => ExplicitTransaction != null && ExplicitTransaction.IsActive; @@ -138,7 +138,7 @@ private bool TryToReturnSessionToPool() var sessionReturnedToPool = SnowflakeDbConnectionPool.AddSession(SfSession); if (sessionReturnedToPool) { - _loggerPair.LogDebug($"Session pooled: {SfSession.sessionId}"); + _logger.Debug($"Session pooled: {SfSession.sessionId}"); } return sessionReturnedToPool; } @@ -149,13 +149,13 @@ private TransactionRollbackStatus TerminateTransactionForDirtyConnectionReturnin return TransactionRollbackStatus.Success; try { - _loggerPair.LogDebug("Closing dirty connection: an active transaction exists in session: " + SfSession.sessionId); + _logger.Debug("Closing dirty connection: an active transaction exists in session: " + SfSession.sessionId); using (IDbCommand command = CreateCommand()) { command.CommandText = "ROLLBACK"; command.ExecuteNonQuery(); // error to indicate a problem within application code that a connection was closed while still having a pending transaction - _loggerPair.LogError("Closing dirty connection: rollback transaction in session " + SfSession.sessionId + " succeeded."); + _logger.Error("Closing dirty connection: rollback transaction in session " + SfSession.sessionId + " succeeded."); ExplicitTransaction = null; return TransactionRollbackStatus.Success; } @@ -163,14 +163,14 @@ private TransactionRollbackStatus TerminateTransactionForDirtyConnectionReturnin catch (Exception exception) { // error to indicate a problem with rollback of an active transaction and inability to return dirty connection to the pool - _loggerPair.LogError("Closing dirty connection: rollback transaction in session: " + SfSession.sessionId + " failed, exception: " + exception.Message); + _logger.Error("Closing dirty connection: rollback transaction in session: " + SfSession.sessionId + " failed, exception: " + exception.Message); return TransactionRollbackStatus.Failure; // connection won't be pooled } } public override void ChangeDatabase(string databaseName) { - _loggerPair.LogDebug($"ChangeDatabase to:{databaseName}"); + _logger.Debug($"ChangeDatabase to:{databaseName}"); string alterDbCommand = $"use database {databaseName}"; @@ -183,7 +183,7 @@ public override void ChangeDatabase(string databaseName) public override void Close() { - _loggerPair.LogDebug("Close Connection."); + _logger.Debug("Close Connection."); if (IsNonClosedWithSession()) { var returnedToPool = TryToReturnSessionToPool(); @@ -207,7 +207,7 @@ public override async Task CloseAsync() public virtual async Task CloseAsync(CancellationToken cancellationToken) { - _loggerPair.LogDebug("Close Connection."); + _logger.Debug("Close Connection."); TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); if (cancellationToken.IsCancellationRequested) @@ -232,18 +232,18 @@ await SfSession.CloseAsync(cancellationToken).ContinueWith( if (previousTask.IsFaulted) { // Exception from SfSession.CloseAsync - _loggerPair.LogError("Error closing the session", previousTask.Exception); + _logger.Error("Error closing the session", previousTask.Exception); taskCompletionSource.SetException(previousTask.Exception); } else if (previousTask.IsCanceled) { _connectionState = ConnectionState.Closed; - _loggerPair.LogDebug("Session close canceled"); + _logger.Debug("Session close canceled"); taskCompletionSource.SetCanceled(); } else { - _loggerPair.LogDebug("Session closed successfully"); + _logger.Debug("Session closed successfully"); _connectionState = ConnectionState.Closed; taskCompletionSource.SetResult(null); } @@ -252,7 +252,7 @@ await SfSession.CloseAsync(cancellationToken).ContinueWith( } else { - _loggerPair.LogDebug("Session not opened. Nothing to do."); + _logger.Debug("Session not opened. Nothing to do."); taskCompletionSource.SetResult(null); } } @@ -267,10 +267,10 @@ protected virtual bool CanReuseSession(TransactionRollbackStatus transactionRoll public override void Open() { - _loggerPair.LogDebug("Open Connection."); + _logger.Debug("Open Connection."); if (_connectionState != ConnectionState.Closed) { - _loggerPair.LogDebug($"Open with a connection already opened: {_connectionState}"); + _logger.Debug($"Open with a connection already opened: {_connectionState}"); return; } try @@ -280,14 +280,14 @@ public override void Open() SfSession = SnowflakeDbConnectionPool.GetSession(ConnectionString, Password); if (SfSession == null) throw new SnowflakeDbException(SFError.INTERNAL_ERROR, "Could not open session"); - _loggerPair.LogDebug($"Connection open with pooled session: {SfSession.sessionId}"); + _logger.Debug($"Connection open with pooled session: {SfSession.sessionId}"); OnSessionEstablished(); } catch (Exception e) { // Otherwise when Dispose() is called, the close request would timeout. _connectionState = ConnectionState.Closed; - _loggerPair.LogError("Unable to connect: ", e); + _logger.Error("Unable to connect: ", e); if (e is SnowflakeDbException) { throw; @@ -310,10 +310,10 @@ internal void FillConnectionStringFromTomlConfigIfNotSet() public override Task OpenAsync(CancellationToken cancellationToken) { - _loggerPair.LogDebug("Open Connection Async."); + _logger.Debug("Open Connection Async."); if (_connectionState != ConnectionState.Closed) { - _loggerPair.LogDebug($"Open with a connection already opened: {_connectionState}"); + _logger.Debug($"Open with a connection already opened: {_connectionState}"); return Task.CompletedTask; } registerConnectionCancellationCallback(cancellationToken); @@ -328,7 +328,7 @@ public override Task OpenAsync(CancellationToken cancellationToken) // Exception from SfSession.OpenAsync Exception sfSessionEx = previousTask.Exception; _connectionState = ConnectionState.Closed; - _loggerPair.LogError("Unable to connect", sfSessionEx); + _logger.Error("Unable to connect", sfSessionEx); throw new SnowflakeDbException( sfSessionEx, SnowflakeDbException.CONNECTION_FAILURE_SSTATE, @@ -338,14 +338,14 @@ public override Task OpenAsync(CancellationToken cancellationToken) else if (previousTask.IsCanceled) { _connectionState = ConnectionState.Closed; - _loggerPair.LogDebug("Connection canceled"); + _logger.Debug("Connection canceled"); throw new TaskCanceledException("Connecting was cancelled"); } else { // Only continue if the session was opened successfully SfSession = previousTask.Result; - _loggerPair.LogDebug($"Connection open with pooled session: {SfSession.sessionId}"); + _logger.Debug($"Connection open with pooled session: {SfSession.sessionId}"); OnSessionEstablished(); } }, TaskContinuationOptions.None); // this continuation should be executed always (even if the whole operation was canceled) because it sets the proper state of the connection @@ -409,7 +409,7 @@ protected override void Dispose(bool disposing) catch (Exception ex) { // Prevent an exception from being thrown when disposing of this object - _loggerPair.LogError("Unable to close connection", ex); + _logger.Error("Unable to close connection", ex); } } else diff --git a/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs b/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs index ee33b276e..a3bea367b 100644 --- a/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs @@ -15,7 +15,7 @@ namespace Snowflake.Data.Client { public class SnowflakeDbConnectionPool { - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private static readonly Object s_connectionManagerInstanceLock = new Object(); private static IConnectionManager s_connectionManager; internal const ConnectionPoolType DefaultConnectionPoolType = ConnectionPoolType.MultipleConnectionPool; @@ -33,91 +33,91 @@ private static IConnectionManager ConnectionManager internal static SFSession GetSession(string connectionString, SecureString password) { - s_loggerPair.LogDebug($"SnowflakeDbConnectionPool::GetSession"); + s_logger.Debug($"SnowflakeDbConnectionPool::GetSession"); return ConnectionManager.GetSession(connectionString, password); } internal static Task GetSessionAsync(string connectionString, SecureString password, CancellationToken cancellationToken) { - s_loggerPair.LogDebug($"SnowflakeDbConnectionPool::GetSessionAsync"); + s_logger.Debug($"SnowflakeDbConnectionPool::GetSessionAsync"); return ConnectionManager.GetSessionAsync(connectionString, password, cancellationToken); } public static SnowflakeDbSessionPool GetPool(string connectionString, SecureString password) { - s_loggerPair.LogDebug($"SnowflakeDbConnectionPool::GetPool"); + s_logger.Debug($"SnowflakeDbConnectionPool::GetPool"); return new SnowflakeDbSessionPool(ConnectionManager.GetPool(connectionString, password)); } public static SnowflakeDbSessionPool GetPool(string connectionString) { - s_loggerPair.LogDebug($"SnowflakeDbConnectionPool::GetPool"); + s_logger.Debug($"SnowflakeDbConnectionPool::GetPool"); return new SnowflakeDbSessionPool(ConnectionManager.GetPool(connectionString)); } internal static SessionPool GetPoolInternal(string connectionString) { - s_loggerPair.LogDebug($"SnowflakeDbConnectionPool::GetPoolInternal"); + s_logger.Debug($"SnowflakeDbConnectionPool::GetPoolInternal"); return ConnectionManager.GetPool(connectionString); } internal static bool AddSession(SFSession session) { - s_loggerPair.LogDebug("SnowflakeDbConnectionPool::AddSession"); + s_logger.Debug("SnowflakeDbConnectionPool::AddSession"); return ConnectionManager.AddSession(session); } internal static void ReleaseBusySession(SFSession session) { - s_loggerPair.LogDebug("SnowflakeDbConnectionPool::ReleaseBusySession"); + s_logger.Debug("SnowflakeDbConnectionPool::ReleaseBusySession"); ConnectionManager.ReleaseBusySession(session); } public static void ClearAllPools() { - s_loggerPair.LogDebug("SnowflakeDbConnectionPool::ClearAllPools"); + s_logger.Debug("SnowflakeDbConnectionPool::ClearAllPools"); ConnectionManager.ClearAllPools(); } public static void SetMaxPoolSize(int maxPoolSize) { - s_loggerPair.LogDebug("SnowflakeDbConnectionPool::SetMaxPoolSize"); + s_logger.Debug("SnowflakeDbConnectionPool::SetMaxPoolSize"); ConnectionManager.SetMaxPoolSize(maxPoolSize); } public static int GetMaxPoolSize() { - s_loggerPair.LogDebug("SnowflakeDbConnectionPool::GetMaxPoolSize"); + s_logger.Debug("SnowflakeDbConnectionPool::GetMaxPoolSize"); return ConnectionManager.GetMaxPoolSize(); } public static void SetTimeout(long connectionTimeout) { - s_loggerPair.LogDebug("SnowflakeDbConnectionPool::SetTimeout"); + s_logger.Debug("SnowflakeDbConnectionPool::SetTimeout"); ConnectionManager.SetTimeout(connectionTimeout); } public static long GetTimeout() { - s_loggerPair.LogDebug("SnowflakeDbConnectionPool::GetTimeout"); + s_logger.Debug("SnowflakeDbConnectionPool::GetTimeout"); return ConnectionManager.GetTimeout(); } public static int GetCurrentPoolSize() { - s_loggerPair.LogDebug("SnowflakeDbConnectionPool::GetCurrentPoolSize"); + s_logger.Debug("SnowflakeDbConnectionPool::GetCurrentPoolSize"); return ConnectionManager.GetCurrentPoolSize(); } public static bool SetPooling(bool isEnable) { - s_loggerPair.LogDebug("SnowflakeDbConnectionPool::SetPooling"); + s_logger.Debug("SnowflakeDbConnectionPool::SetPooling"); return ConnectionManager.SetPooling(isEnable); } public static bool GetPooling() { - s_loggerPair.LogDebug("SnowflakeDbConnectionPool::GetPooling"); + s_logger.Debug("SnowflakeDbConnectionPool::GetPooling"); return ConnectionManager.GetPooling(); } @@ -137,12 +137,12 @@ private static void SetConnectionPoolVersion(ConnectionPoolType requestedPoolTyp if (requestedPoolType == ConnectionPoolType.MultipleConnectionPool) { s_connectionManager = new ConnectionPoolManager(); - s_loggerPair.LogInformation("SnowflakeDbConnectionPool - multiple connection pools enabled"); + s_logger.Info("SnowflakeDbConnectionPool - multiple connection pools enabled"); } if (requestedPoolType == ConnectionPoolType.SingleConnectionCache) { s_connectionManager = new ConnectionCacheManager(); - s_loggerPair.LogWarning("SnowflakeDbConnectionPool - connection cache enabled"); + s_logger.Warn("SnowflakeDbConnectionPool - connection cache enabled"); } } } diff --git a/Snowflake.Data/Client/SnowflakeDbDataReader.cs b/Snowflake.Data/Client/SnowflakeDbDataReader.cs index 5e0bd6de7..24166da9c 100755 --- a/Snowflake.Data/Client/SnowflakeDbDataReader.cs +++ b/Snowflake.Data/Client/SnowflakeDbDataReader.cs @@ -18,7 +18,7 @@ namespace Snowflake.Data.Client { public class SnowflakeDbDataReader : DbDataReader { - static private readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + static private readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private SnowflakeDbCommand dbCommand; diff --git a/Snowflake.Data/Client/SnowflakeDbTransaction.cs b/Snowflake.Data/Client/SnowflakeDbTransaction.cs index 53815c61b..eda989864 100755 --- a/Snowflake.Data/Client/SnowflakeDbTransaction.cs +++ b/Snowflake.Data/Client/SnowflakeDbTransaction.cs @@ -12,7 +12,7 @@ namespace Snowflake.Data.Client { public class SnowflakeDbTransaction : DbTransaction { - private SFLoggerPair _loggerPair = SFLoggerPair.GetLoggerPair(); + private SFLogger _logger = SFLoggerFactory.GetLogger(); private IsolationLevel isolationLevel; @@ -25,19 +25,19 @@ public class SnowflakeDbTransaction : DbTransaction public SnowflakeDbTransaction(IsolationLevel isolationLevel, SnowflakeDbConnection connection) { - _loggerPair.LogDebug("Begin transaction."); + _logger.Debug("Begin transaction."); if (isolationLevel != IsolationLevel.ReadCommitted) { throw new SnowflakeDbException(SFError.UNSUPPORTED_FEATURE); } if (connection == null) { - _loggerPair.LogError("Transaction cannot be started for an unknown connection"); + _logger.Error("Transaction cannot be started for an unknown connection"); throw new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY); } if (!connection.IsOpen()) { - _loggerPair.LogError("Transaction cannot be started for a closed connection"); + _logger.Error("Transaction cannot be started for a closed connection"); throw new SnowflakeDbException(SFError.UNSUPPORTED_FEATURE); } @@ -71,7 +71,7 @@ protected override DbConnection DbConnection public override void Commit() { - _loggerPair.LogDebug("Commit transaction."); + _logger.Debug("Commit transaction."); if (!isCommittedOrRollbacked) { using (IDbCommand command = connection.CreateCommand()) @@ -85,7 +85,7 @@ public override void Commit() public override void Rollback() { - _loggerPair.LogDebug("Rollback transaction."); + _logger.Debug("Rollback transaction."); if (!isCommittedOrRollbacked) { using (IDbCommand command = connection.CreateCommand()) diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs b/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs index a53300bb9..d42c2573a 100644 --- a/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs +++ b/Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs @@ -62,7 +62,7 @@ private string GetFilePathFromInputParameter(string filePath, string inputDescri { return null; } - s_logger.Information($"Using config file specified from {inputDescription}: {filePath}"); + s_logger.Info($"Using config file specified from {inputDescription}: {filePath}"); return filePath; } @@ -77,7 +77,7 @@ private string SearchForConfigInDirectory(Func directoryProvider, string var directory = directoryProvider.Invoke(); if (string.IsNullOrEmpty(directory)) { - s_logger.Warning($"The {directoryDescription} directory could not be determined and will be skipped"); + s_logger.Warn($"The {directoryDescription} directory could not be determined and will be skipped"); return null; } @@ -95,7 +95,7 @@ private string OnlyIfFileExists(string filePath, string directoryDescription) { if (_fileOperations.Exists(filePath)) { - s_logger.Information($"Using config file specified from {directoryDescription} directory: {filePath}"); + s_logger.Info($"Using config file specified from {directoryDescription} directory: {filePath}"); return filePath; } return null; diff --git a/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs b/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs index 5989ac27b..48b244b57 100644 --- a/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs +++ b/Snowflake.Data/Configuration/EasyLoggingConfigParser.cs @@ -79,7 +79,7 @@ private void CheckForUnknownFields(string fileContent) .Cast() .Where(property => !knownProperties.Contains(property.Name, StringComparer.OrdinalIgnoreCase)) .ToList() - .ForEach(unknownKey => s_logger.Warning($"Unknown field from config: {unknownKey.Name}")); + .ForEach(unknownKey => s_logger.Warn($"Unknown field from config: {unknownKey.Name}")); } } } diff --git a/Snowflake.Data/Core/ArrowResultSet.cs b/Snowflake.Data/Core/ArrowResultSet.cs index 45fe60e16..e27246a0b 100644 --- a/Snowflake.Data/Core/ArrowResultSet.cs +++ b/Snowflake.Data/Core/ArrowResultSet.cs @@ -17,7 +17,7 @@ class ArrowResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => ResultFormat.ARROW; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private readonly int _totalChunkCount; private BaseResultChunk _currentChunk; @@ -49,7 +49,7 @@ public ArrowResultSet(QueryExecResponseData responseData, SFStatement sfStatemen } catch(Exception ex) { - s_loggerPair.LogError("Result set error queryId="+responseData.queryId, ex); + s_logger.Error("Result set error queryId="+responseData.queryId, ex); throw; } } @@ -86,7 +86,7 @@ internal override async Task NextAsync() if (_totalChunkCount > 0) { - s_loggerPair.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_logger.Debug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); _currentChunk = await _chunkDownloader.GetNextChunkAsync().ConfigureAwait(false); @@ -105,7 +105,7 @@ internal override bool Next() if (_totalChunkCount > 0) { - s_loggerPair.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_logger.Debug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); _currentChunk = Task.Run(async() => await (_chunkDownloader.GetNextChunkAsync()).ConfigureAwait(false)).Result; @@ -149,7 +149,7 @@ internal override bool Rewind() if (_currentChunk.ChunkIndex > 0) { - s_loggerPair.LogWarning("Unable to rewind to the previous chunk"); + s_logger.Warn("Unable to rewind to the previous chunk"); } return false; diff --git a/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs b/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs index e8e717ee6..9ce868dd7 100644 --- a/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs @@ -11,7 +11,7 @@ namespace Snowflake.Data.Core.Authenticator class BasicAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "snowflake"; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); internal BasicAuthenticator(SFSession session) : base(session, AUTH_NAME) { diff --git a/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs b/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs index c01ffb1e4..a1f352f8b 100644 --- a/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs @@ -22,7 +22,7 @@ namespace Snowflake.Data.Core.Authenticator class ExternalBrowserAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "externalbrowser"; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private static readonly string TOKEN_REQUEST_PREFIX = "?token="; private static readonly byte[] SUCCESS_RESPONSE = System.Text.Encoding.UTF8.GetBytes( "" + @@ -47,14 +47,14 @@ internal ExternalBrowserAuthenticator(SFSession session) : base(session, AUTH_NA /// async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) { - s_loggerPair.LogInformation("External Browser Authentication"); + s_logger.Info("External Browser Authentication"); int localPort = GetRandomUnusedPort(); using (var httpListener = GetHttpListener(localPort)) { httpListener.Start(); - s_loggerPair.LogDebug("Get IdpUrl and ProofKey"); + s_logger.Debug("Get IdpUrl and ProofKey"); string loginUrl; if (session._disableConsoleLogin) { @@ -75,37 +75,37 @@ await session.restRequester.PostAsync( loginUrl = GetLoginUrl(_proofKey, localPort); } - s_loggerPair.LogDebug("Open browser"); + s_logger.Debug("Open browser"); StartBrowser(loginUrl); - s_loggerPair.LogDebug("Get the redirect SAML request"); + s_logger.Debug("Get the redirect SAML request"); _successEvent = new ManualResetEvent(false); httpListener.BeginGetContext(GetContextCallback, httpListener); var timeoutInSec = int.Parse(session.properties[SFSessionProperty.BROWSER_RESPONSE_TIMEOUT]); if (!_successEvent.WaitOne(timeoutInSec * 1000)) { - s_loggerPair.LogWarning("Browser response timeout"); + s_logger.Warn("Browser response timeout"); throw new SnowflakeDbException(SFError.BROWSER_RESPONSE_TIMEOUT, timeoutInSec); } httpListener.Stop(); } - s_loggerPair.LogDebug("Send login request"); + s_logger.Debug("Send login request"); await base.LoginAsync(cancellationToken).ConfigureAwait(false); } /// void IAuthenticator.Authenticate() { - s_loggerPair.LogInformation("External Browser Authentication"); + s_logger.Info("External Browser Authentication"); int localPort = GetRandomUnusedPort(); using (var httpListener = GetHttpListener(localPort)) { httpListener.Start(); - s_loggerPair.LogDebug("Get IdpUrl and ProofKey"); + s_logger.Debug("Get IdpUrl and ProofKey"); string loginUrl; if (session._disableConsoleLogin) { @@ -122,23 +122,23 @@ void IAuthenticator.Authenticate() loginUrl = GetLoginUrl(_proofKey, localPort); } - s_loggerPair.LogDebug("Open browser"); + s_logger.Debug("Open browser"); StartBrowser(loginUrl); - s_loggerPair.LogDebug("Get the redirect SAML request"); + s_logger.Debug("Get the redirect SAML request"); _successEvent = new ManualResetEvent(false); httpListener.BeginGetContext(GetContextCallback, httpListener); var timeoutInSec = int.Parse(session.properties[SFSessionProperty.BROWSER_RESPONSE_TIMEOUT]); if (!_successEvent.WaitOne(timeoutInSec * 1000)) { - s_loggerPair.LogWarning("Browser response timeout"); + s_logger.Warn("Browser response timeout"); throw new SnowflakeDbException(SFError.BROWSER_RESPONSE_TIMEOUT, timeoutInSec); } httpListener.Stop(); } - s_loggerPair.LogDebug("Send login request"); + s_logger.Debug("Send login request"); base.Login(); } @@ -163,7 +163,7 @@ private void GetContextCallback(IAsyncResult result) catch { // Ignore the exception as it does not affect the overall authentication flow - s_loggerPair.LogWarning("External browser response not sent out"); + s_logger.Warn("External browser response not sent out"); } } @@ -193,13 +193,13 @@ private static void StartBrowser(string url) Match m = Regex.Match(url, regexStr, RegexOptions.IgnoreCase); if (!m.Success) { - s_loggerPair.LogError("Failed to start browser. Invalid url."); + s_logger.Error("Failed to start browser. Invalid url."); throw new SnowflakeDbException(SFError.INVALID_BROWSER_URL); } if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) { - s_loggerPair.LogError("Failed to start browser. Invalid url."); + s_logger.Error("Failed to start browser. Invalid url."); throw new SnowflakeDbException(SFError.INVALID_BROWSER_URL); } diff --git a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs index 52e3f42cd..5a1ad6f3a 100644 --- a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs @@ -45,8 +45,8 @@ internal enum SFAuthenticatorType internal abstract class BaseAuthenticator { // The logger. - private static readonly SFLoggerPair s_loggerPair = - SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = + SFLoggerFactory.GetLogger(); // The name of the authenticator. private string authName; @@ -134,7 +134,7 @@ private SFRestRequest BuildLoginRequest() /// internal class AuthenticatorFactory { - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); /// /// Generate the authenticator given the session /// @@ -164,7 +164,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) var error = new SnowflakeDbException( SFError.INVALID_CONNECTION_STRING, new object[] { invalidStringDetail }); - s_loggerPair.LogError(error.Message, error); + s_logger.Error(error.Message, error); throw error; } @@ -181,7 +181,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) var error = new SnowflakeDbException( SFError.INVALID_CONNECTION_STRING, new object[] { invalidStringDetail }); - s_loggerPair.LogError(error.Message, error); + s_logger.Error(error.Message, error); throw error; } @@ -192,7 +192,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) { return new OktaAuthenticator(session, type); } - s_loggerPair.LogError($"Unknown authenticator {type}"); + s_logger.Error($"Unknown authenticator {type}"); throw new SnowflakeDbException(SFError.UNKNOWN_AUTHENTICATOR, type); } } diff --git a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs index d32a9d7b1..0439deb10 100644 --- a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs @@ -32,8 +32,8 @@ class KeyPairAuthenticator : BaseAuthenticator, IAuthenticator public const string AUTH_NAME = "snowflake_jwt"; // The logger. - private static readonly SFLoggerPair s_loggerPair = - SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = + SFLoggerFactory.GetLogger(); // The RSA provider to use to sign the tokens private RSACryptoServiceProvider rsaProvider; @@ -57,7 +57,7 @@ async public Task AuthenticateAsync(CancellationToken cancellationToken) jwtToken = GenerateJwtToken(); // Send the http request with the generate token - s_loggerPair.LogDebug("Send login request"); + s_logger.Debug("Send login request"); await base.LoginAsync(cancellationToken).ConfigureAwait(false); } @@ -67,7 +67,7 @@ public void Authenticate() jwtToken = GenerateJwtToken(); // Send the http request with the generate token - s_loggerPair.LogDebug("Send login request"); + s_logger.Debug("Send login request"); base.Login(); } @@ -84,7 +84,7 @@ protected override void SetSpecializedAuthenticatorData(ref LoginRequestData dat /// The generated JWT token. private string GenerateJwtToken() { - s_loggerPair.LogInformation("Key-pair Authentication"); + s_logger.Info("Key-pair Authentication"); bool hasPkPath = session.properties.TryGetValue(SFSessionProperty.PRIVATE_KEY_FILE, out var pkPath); diff --git a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs index e7ea5c034..4b94c82e1 100644 --- a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs @@ -17,8 +17,8 @@ class OAuthAuthenticator : BaseAuthenticator, IAuthenticator public const string AUTH_NAME = "oauth"; // The logger. - private static readonly SFLoggerPair s_loggerPair = - SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = + SFLoggerFactory.GetLogger(); /// /// Constructor for the oauth authenticator. diff --git a/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs b/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs index 21509cb60..7c364d3c5 100644 --- a/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs @@ -23,7 +23,7 @@ namespace Snowflake.Data.Core.Authenticator class OktaAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "okta"; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); internal const string RetryCountHeader = "RetryCount"; internal const string TimeoutElapsedHeader = "TimeoutElapsed"; @@ -49,19 +49,19 @@ internal OktaAuthenticator(SFSession session, string oktaUriString) : /// async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) { - s_loggerPair.LogInformation("Okta Authentication"); + s_logger.Info("Okta Authentication"); - s_loggerPair.LogDebug("step 1: Get SSO and token URL"); + s_logger.Debug("step 1: Get SSO and token URL"); var authenticatorRestRequest = BuildAuthenticatorRestRequest(); var authenticatorResponse = await session.restRequester.PostAsync(authenticatorRestRequest, cancellationToken).ConfigureAwait(false); authenticatorResponse.FilterFailedResponse(); Uri ssoUrl = new Uri(authenticatorResponse.data.ssoUrl); Uri tokenUrl = new Uri(authenticatorResponse.data.tokenUrl); - s_loggerPair.LogDebug("step 2: Verify URLs fetched from step 1"); - s_loggerPair.LogDebug("Checking SSO Okta URL"); + s_logger.Debug("step 2: Verify URLs fetched from step 1"); + s_logger.Debug("Checking SSO Okta URL"); VerifyUrls(ssoUrl, _oktaUrl); - s_loggerPair.LogDebug("Checking token URL"); + s_logger.Debug("Checking token URL"); VerifyUrls(tokenUrl, _oktaUrl); int retryCount = 0; @@ -74,26 +74,26 @@ async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) { try { - s_loggerPair.LogDebug("step 3: Get IdP one-time token"); + s_logger.Debug("step 3: Get IdP one-time token"); IdpTokenRestRequest idpTokenRestRequest = BuildIdpTokenRestRequest(tokenUrl); var idpResponse = await session.restRequester.PostAsync(idpTokenRestRequest, cancellationToken).ConfigureAwait(false); string onetimeToken = idpResponse.SessionToken ?? idpResponse.CookieToken; - s_loggerPair.LogDebug("step 4: Get SAML response from SSO"); + s_logger.Debug("step 4: Get SAML response from SSO"); var samlRestRequest = BuildSamlRestRequest(ssoUrl, onetimeToken); samlRawResponse = await session.restRequester.GetAsync(samlRestRequest, cancellationToken).ConfigureAwait(false); _rawSamlTokenHtmlString = await samlRawResponse.Content.ReadAsStringAsync().ConfigureAwait(false); - s_loggerPair.LogDebug("step 5: Verify postback URL in SAML response"); + s_logger.Debug("step 5: Verify postback URL in SAML response"); if (!session._disableSamlUrlCheck) { VerifyPostbackUrl(); } else { - s_loggerPair.LogDebug("The saml url check is disabled. Skipping step 5"); + s_logger.Debug("The saml url check is disabled. Skipping step 5"); } - s_loggerPair.LogDebug("step 6: Send SAML response to Snowflake to login"); + s_logger.Debug("step 6: Send SAML response to Snowflake to login"); await LoginAsync(cancellationToken).ConfigureAwait(false); return; } @@ -115,19 +115,19 @@ async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) void IAuthenticator.Authenticate() { - s_loggerPair.LogInformation("Okta Authentication"); + s_logger.Info("Okta Authentication"); - s_loggerPair.LogDebug("step 1: Get SSO and token URL"); + s_logger.Debug("step 1: Get SSO and token URL"); var authenticatorRestRequest = BuildAuthenticatorRestRequest(); var authenticatorResponse = session.restRequester.Post(authenticatorRestRequest); authenticatorResponse.FilterFailedResponse(); Uri ssoUrl = new Uri(authenticatorResponse.data.ssoUrl); Uri tokenUrl = new Uri(authenticatorResponse.data.tokenUrl); - s_loggerPair.LogDebug("step 2: Verify URLs fetched from step 1"); - s_loggerPair.LogDebug("Checking SSO Okta URL"); + s_logger.Debug("step 2: Verify URLs fetched from step 1"); + s_logger.Debug("Checking SSO Okta URL"); VerifyUrls(ssoUrl, _oktaUrl); - s_loggerPair.LogDebug("Checking token URL"); + s_logger.Debug("Checking token URL"); VerifyUrls(tokenUrl, _oktaUrl); int retryCount = 0; @@ -140,27 +140,27 @@ void IAuthenticator.Authenticate() { try { - s_loggerPair.LogDebug("step 3: Get IdP one-time token"); + s_logger.Debug("step 3: Get IdP one-time token"); IdpTokenRestRequest idpTokenRestRequest = BuildIdpTokenRestRequest(tokenUrl); var idpResponse = session.restRequester.Post(idpTokenRestRequest); string onetimeToken = idpResponse.SessionToken ?? idpResponse.CookieToken; - s_loggerPair.LogDebug("step 4: Get SAML response from SSO"); + s_logger.Debug("step 4: Get SAML response from SSO"); var samlRestRequest = BuildSamlRestRequest(ssoUrl, onetimeToken); samlRawResponse = session.restRequester.Get(samlRestRequest); _rawSamlTokenHtmlString = Task.Run(async () => await samlRawResponse.Content.ReadAsStringAsync().ConfigureAwait(false)).Result; - s_loggerPair.LogDebug("step 5: Verify postback URL in SAML response"); + s_logger.Debug("step 5: Verify postback URL in SAML response"); if (!session._disableSamlUrlCheck) { VerifyPostbackUrl(); } else { - s_loggerPair.LogDebug("The saml url check is disabled. Skipping step 5"); + s_logger.Debug("The saml url check is disabled. Skipping step 5"); } - s_loggerPair.LogDebug("step 6: Send SAML response to Snowflake to login"); + s_logger.Debug("step 6: Send SAML response to Snowflake to login"); Login(); return; } @@ -184,12 +184,12 @@ private void HandleAuthenticatorException(Exception ex, HttpResponseMessage saml { if (IsPostbackUrlNotFound(ex)) { - s_loggerPair.LogDebug("Refreshing token for Okta re-authentication and starting from step 3 again"); + s_logger.Debug("Refreshing token for Okta re-authentication and starting from step 3 again"); if (samlRawResponse is null) { var errorNullSamlResponse = "Failure getting SAML response from Okta SSO"; - s_loggerPair.LogError(errorNullSamlResponse); + s_logger.Error(errorNullSamlResponse); throw new SnowflakeDbException(ex, SFError.IDP_SAML_POSTBACK_INVALID); } @@ -199,7 +199,7 @@ private void HandleAuthenticatorException(Exception ex, HttpResponseMessage saml } else { - s_loggerPair.LogError("Failed to get the correct SAML response from Okta SSO", ex); + s_logger.Error("Failed to get the correct SAML response from Okta SSO", ex); throw ex; } } @@ -256,7 +256,7 @@ private void VerifyUrls(Uri tokenOrSsoUrl, Uri sessionUrl) { var e = new SnowflakeDbException( SFError.IDP_SSO_TOKEN_URL_MISMATCH, tokenOrSsoUrl.ToString(), _oktaUrl.ToString()); - s_loggerPair.LogError("Different urls", e); + s_logger.Error("Different urls", e); throw e; } } @@ -275,7 +275,7 @@ private void VerifyPostbackUrl() postBackUrl = new Uri(HttpUtility.HtmlDecode(_rawSamlTokenHtmlString.Substring(startIndex, length))); } catch (Exception e) { - s_loggerPair.LogError("Fail to extract SAML from html", e); + s_logger.Error("Fail to extract SAML from html", e); throw new SnowflakeDbException(e, SFError.IDP_SAML_POSTBACK_NOTFOUND); } @@ -288,7 +288,7 @@ private void VerifyPostbackUrl() SFError.IDP_SAML_POSTBACK_INVALID, postBackUrl.ToString(), sessionScheme + ":\\\\" + sessionHost); - s_loggerPair.LogError("Different urls", e); + s_logger.Error("Different urls", e); throw e; } } @@ -324,7 +324,7 @@ private void ThrowRetryLimitException(int retryCount, int timeoutElapsed, Except } errorMessage += " while trying to authenticate through Okta"; - s_loggerPair.LogError(errorMessage); + s_logger.Error(errorMessage); throw new SnowflakeDbException(lastRetryException, SFError.INTERNAL_ERROR, errorMessage); } } diff --git a/Snowflake.Data/Core/ChunkDownloaderFactory.cs b/Snowflake.Data/Core/ChunkDownloaderFactory.cs index b0373bcc3..48f888a4c 100755 --- a/Snowflake.Data/Core/ChunkDownloaderFactory.cs +++ b/Snowflake.Data/Core/ChunkDownloaderFactory.cs @@ -11,7 +11,7 @@ namespace Snowflake.Data.Core { class ChunkDownloaderFactory { - private static SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static SFLogger s_logger = SFLoggerFactory.GetLogger(); public static IChunkDownloader GetDownloader(QueryExecResponseData responseData, SFBaseResultSet resultSet, CancellationToken cancellationToken) @@ -19,7 +19,7 @@ public static IChunkDownloader GetDownloader(QueryExecResponseData responseData, switch (SFConfiguration.Instance().GetChunkDownloaderVersion()) { case 1: - s_loggerPair.LogWarning("V1 version of ChunkDownloader is deprecated. Using the V3 version."); + s_logger.Warn("V1 version of ChunkDownloader is deprecated. Using the V3 version."); return new SFBlockingChunkDownloaderV3(responseData.rowType.Count, responseData.chunks, responseData.qrmk, @@ -28,7 +28,7 @@ public static IChunkDownloader GetDownloader(QueryExecResponseData responseData, resultSet, responseData.queryResultFormat); case 2: - s_loggerPair.LogWarning("V2 version of ChunkDownloader is deprecated. Using the V3 version."); + s_logger.Warn("V2 version of ChunkDownloader is deprecated. Using the V3 version."); return new SFBlockingChunkDownloaderV3(responseData.rowType.Count, responseData.chunks, responseData.qrmk, diff --git a/Snowflake.Data/Core/ChunkParserFactory.cs b/Snowflake.Data/Core/ChunkParserFactory.cs index 05cdedd03..be4435ffa 100755 --- a/Snowflake.Data/Core/ChunkParserFactory.cs +++ b/Snowflake.Data/Core/ChunkParserFactory.cs @@ -11,7 +11,7 @@ namespace Snowflake.Data.Core { class ChunkParserFactory : IChunkParserFactory { - private static SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static SFLogger s_logger = SFLoggerFactory.GetLogger(); public static IChunkParserFactory Instance = new ChunkParserFactory(); public IChunkParser GetParser(ResultFormat resultFormat, Stream stream) @@ -22,10 +22,10 @@ public IChunkParser GetParser(ResultFormat resultFormat, Stream stream) switch (SFConfiguration.Instance().GetChunkParserVersion()) { case 1: - s_loggerPair.LogWarning("V1 version of ChunkParser is deprecated. Using the V3 version."); + s_logger.Warn("V1 version of ChunkParser is deprecated. Using the V3 version."); return new ReusableChunkParser(stream); case 2: - s_loggerPair.LogWarning("V2 version of ChunkParser is deprecated. Using the V3 version."); + s_logger.Warn("V2 version of ChunkParser is deprecated. Using the V3 version."); return new ReusableChunkParser(stream); case 3: return new ReusableChunkParser(stream); diff --git a/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs b/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs index c7e67a92f..ce46332c9 100644 --- a/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs +++ b/Snowflake.Data/Core/Converter/StructuredTypesReadingHandler.cs @@ -6,16 +6,16 @@ namespace Snowflake.Data.Core.Converter { public class StructuredTypesReadingHandler { - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); public static SnowflakeDbException ToSnowflakeDbException(Exception exception, string context) { if (exception is StructuredTypesReadingException) { - s_loggerPair.LogDebug("Exception caught when reading structured types", exception); + s_logger.Debug("Exception caught when reading structured types", exception); return new SnowflakeDbException(SFError.STRUCTURED_TYPE_READ_DETAILED_ERROR, context, exception.Message); } - s_loggerPair.LogDebug("Exception caught when reading structured types"); + s_logger.Debug("Exception caught when reading structured types"); return new SnowflakeDbException(SFError.STRUCTURED_TYPE_READ_ERROR, context); } } diff --git a/Snowflake.Data/Core/FastParser.cs b/Snowflake.Data/Core/FastParser.cs index cebd18f39..1f5b997b3 100644 --- a/Snowflake.Data/Core/FastParser.cs +++ b/Snowflake.Data/Core/FastParser.cs @@ -6,14 +6,14 @@ namespace Snowflake.Data.Core { public class FastParser { - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); public static Int64 FastParseInt64(byte[] s, int offset, int len) { if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - s_loggerPair.LogError("A null buffer was passed to FastParseInt64", ex); + s_logger.Error("A null buffer was passed to FastParseInt64", ex); throw ex; } @@ -54,7 +54,7 @@ public static Int32 FastParseInt32(byte[] s, int offset, int len) if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - s_loggerPair.LogError("A null buffer was passed to FastParseInt32", ex); + s_logger.Error("A null buffer was passed to FastParseInt32", ex); throw ex; } @@ -95,7 +95,7 @@ public static decimal FastParseDecimal(byte[] s, int offset, int len) if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - s_loggerPair.LogError("A null buffer was passed to FastParseDecimal", ex); + s_logger.Error("A null buffer was passed to FastParseDecimal", ex); throw ex; } diff --git a/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs b/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs index 6dc3bea48..6f02f8943 100644 --- a/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs +++ b/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs @@ -22,7 +22,7 @@ class EncryptionProvider /// /// The logger. /// - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); /// /// Encrypt data and write to the outStream. @@ -60,7 +60,7 @@ public static StreamPair EncryptStream( { byte[] decodedMasterKey = Convert.FromBase64String(encryptionMaterial.queryStageMasterKey); int masterKeySize = decodedMasterKey.Length; - s_loggerPair.LogDebug($"Master key size : {masterKeySize}"); + s_logger.Debug($"Master key size : {masterKeySize}"); // Generate file key byte[] ivData = new byte[blockSize]; diff --git a/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs b/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs index 82aa9e42e..b7ad2cda0 100644 --- a/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs +++ b/Snowflake.Data/Core/FileTransfer/GcmEncryptionProvider.cs @@ -15,7 +15,7 @@ internal class GcmEncryptionProvider private const int InitVectorSizeInBytes = 12; private const string AesGcmNoPaddingCipher = "AES/GCM/NoPadding"; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private static readonly SecureRandom s_random = SecureRandom.GetInstance("SHA1PRNG"); @@ -56,7 +56,7 @@ public static Stream Encrypt( { byte[] decodedMasterKey = Convert.FromBase64String(encryptionMaterial.queryStageMasterKey); int masterKeySize = decodedMasterKey.Length; - s_loggerPair.LogDebug($"Master key size : {masterKeySize}"); + s_logger.Debug($"Master key size : {masterKeySize}"); var contentIV = new byte[InitVectorSizeInBytes]; var keyIV = new byte[InitVectorSizeInBytes]; diff --git a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs index f9b705d30..6c6cbc6fd 100644 --- a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs +++ b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs @@ -60,7 +60,7 @@ class SFFileTransferAgent /// /// The logger. /// - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); /// /// Auto-detect keyword for source compression type auto detection. @@ -230,7 +230,7 @@ public void execute() } catch (Exception e) { - s_loggerPair.LogError("Error while transferring file(s): " + e.Message); + s_logger.Error("Error while transferring file(s): " + e.Message); if (e is SnowflakeDbException snowflakeException) { if (snowflakeException.QueryId == null) @@ -346,19 +346,19 @@ private void upload() //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - s_loggerPair.LogDebug("Start uploading large files"); + s_logger.Debug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { UploadFilesInSequential(fileMetadata); } - s_loggerPair.LogDebug("End uploading large files"); + s_logger.Debug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - s_loggerPair.LogDebug("Start uploading small files"); + s_logger.Debug("Start uploading small files"); UploadFilesInParallel(SmallFilesMetas, TransferMetadata.parallel); - s_loggerPair.LogDebug("End uploading small files"); + s_logger.Debug("End uploading small files"); } } @@ -372,19 +372,19 @@ private async Task uploadAsync(CancellationToken cancellationToken) //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - s_loggerPair.LogDebug("Start uploading large files"); + s_logger.Debug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { await UploadFilesInSequentialAsync(fileMetadata, cancellationToken).ConfigureAwait(false); } - s_loggerPair.LogDebug("End uploading large files"); + s_logger.Debug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - s_loggerPair.LogDebug("Start uploading small files"); + s_logger.Debug("Start uploading small files"); await UploadFilesInParallelAsync(SmallFilesMetas, TransferMetadata.parallel, cancellationToken).ConfigureAwait(false); - s_loggerPair.LogDebug("End uploading small files"); + s_logger.Debug("End uploading small files"); } } @@ -399,18 +399,18 @@ private void download() //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - s_loggerPair.LogDebug("Start uploading large files"); + s_logger.Debug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { DownloadFilesInSequential(fileMetadata); } - s_loggerPair.LogDebug("End uploading large files"); + s_logger.Debug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - s_loggerPair.LogDebug("Start uploading small files"); + s_logger.Debug("Start uploading small files"); DownloadFilesInParallel(SmallFilesMetas, TransferMetadata.parallel); - s_loggerPair.LogDebug("End uploading small files"); + s_logger.Debug("End uploading small files"); } } @@ -424,18 +424,18 @@ private async Task downloadAsync(CancellationToken cancellationToken) //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - s_loggerPair.LogDebug("Start uploading large files"); + s_logger.Debug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { await DownloadFilesInSequentialAsync(fileMetadata, cancellationToken).ConfigureAwait(false); } - s_loggerPair.LogDebug("End uploading large files"); + s_logger.Debug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - s_loggerPair.LogDebug("Start uploading small files"); + s_logger.Debug("Start uploading small files"); await DownloadFilesInParallelAsync(SmallFilesMetas, TransferMetadata.parallel, cancellationToken).ConfigureAwait(false); - s_loggerPair.LogDebug("End uploading small files"); + s_logger.Debug("End uploading small files"); } } @@ -574,7 +574,7 @@ private void initFileMetadata( // Auto-detect source compression type // Will return NONE if no matching type is found compressionType = SFFileCompressionTypes.GuessCompressionType(file); - s_loggerPair.LogDebug($"File compression detected as {compressionType.Name} for: {file}"); + s_logger.Debug($"File compression detected as {compressionType.Name} for: {file}"); } else { @@ -716,7 +716,7 @@ private int GetFileTransferMaxBytesInMemory() } catch (Exception) { - s_loggerPair.LogWarning("Default for FILE_TRANSFER_MEMORY_THRESHOLD used due to invalid session value."); + s_logger.Warn("Default for FILE_TRANSFER_MEMORY_THRESHOLD used due to invalid session value."); return FileTransferConfiguration.DefaultMaxBytesInMemory; } } @@ -782,12 +782,12 @@ private List expandFileNames(string location) } } - if (s_loggerPair.IsDebugEnabled()) + if (s_logger.IsDebugEnabled()) { - s_loggerPair.LogDebug("Expand " + location + " into: "); + s_logger.Debug("Expand " + location + " into: "); foreach (var filepath in filePaths) { - s_loggerPair.LogDebug("\t" + filepath ); + s_logger.Debug("\t" + filepath ); } } @@ -901,7 +901,7 @@ private void compressFileWithGzip(SFFileMetadata fileMetadata) } } - s_loggerPair.LogDebug($"Compressed {fileToCompress.Name} to {fileMetadata.realSrcFilePath}"); + s_logger.Debug($"Compressed {fileToCompress.Name} to {fileMetadata.realSrcFilePath}"); FileInfo destInfo = new FileInfo(fileMetadata.realSrcFilePath); fileMetadata.destFileSize = destInfo.Length; } @@ -1235,7 +1235,7 @@ private SFFileMetadata UploadSingleFile( } catch (Exception ex) { - s_loggerPair.LogDebug("Unhandled exception while uploading file.", ex); + s_logger.Debug("Unhandled exception while uploading file.", ex); throw; } finally @@ -1284,7 +1284,7 @@ private async Task UploadSingleFileAsync( } catch (Exception ex) { - s_loggerPair.LogError("UploadSingleFileAsync encountered an error: " + ex.Message); + s_logger.Error("UploadSingleFileAsync encountered an error: " + ex.Message); throw; } finally @@ -1322,7 +1322,7 @@ private SFFileMetadata DownloadSingleFile( } catch (Exception ex) { - s_loggerPair.LogError("DownloadSingleFile encountered an error: " + ex.Message); + s_logger.Error("DownloadSingleFile encountered an error: " + ex.Message); throw; } finally @@ -1360,7 +1360,7 @@ private async Task DownloadSingleFileAsync( } catch (Exception ex) { - s_loggerPair.LogError("DownloadSingleFileAsync encountered an error: " + ex.Message); + s_logger.Error("DownloadSingleFileAsync encountered an error: " + ex.Message); throw; } finally diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs index 38e16b18f..d0a9f1ac6 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs @@ -42,7 +42,7 @@ class SFGCSClient : ISFRemoteStorageClient /// /// The logger. /// - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); /// /// The storage client. @@ -62,11 +62,11 @@ class SFGCSClient : ISFRemoteStorageClient /// The command stage info. public SFGCSClient(PutGetStageInfo stageInfo) { - s_loggerPair.LogDebug("Setting up a new GCS client "); + s_logger.Debug("Setting up a new GCS client "); if (stageInfo.stageCredentials.TryGetValue(GCS_ACCESS_TOKEN, out string accessToken)) { - s_loggerPair.LogDebug("Constructing client using access token"); + s_logger.Debug("Constructing client using access token"); AccessToken = accessToken; GoogleCredential creds = GoogleCredential.FromAccessToken(accessToken, null); var storageClientBuilder = new StorageClientBuilder @@ -78,7 +78,7 @@ public SFGCSClient(PutGetStageInfo stageInfo) } else { - s_loggerPair.LogInformation("No access token received from GS, constructing anonymous client with no encryption support"); + s_logger.Info("No access token received from GS, constructing anonymous client with no encryption support"); var storageClientBuilder = new StorageClientBuilder { UnauthenticatedAccess = true @@ -475,7 +475,7 @@ private void HandleDownloadResponse(HttpWebResponse response, SFFileMetadata fil /// File Metadata private SFFileMetadata HandleFileHeaderErrForPresignedUrls(WebException ex, SFFileMetadata fileMetadata) { - s_loggerPair.LogError("Failed to get file header for presigned url: " + ex.Message); + s_logger.Error("Failed to get file header for presigned url: " + ex.Message); HttpWebResponse response = (HttpWebResponse)ex.Response; if (response.StatusCode == HttpStatusCode.Unauthorized || @@ -501,7 +501,7 @@ private SFFileMetadata HandleFileHeaderErrForPresignedUrls(WebException ex, SFFi /// File Metadata private SFFileMetadata HandleFileHeaderErrForGeneratedUrls(WebException ex, SFFileMetadata fileMetadata) { - s_loggerPair.LogError("Failed to get file header for non-presigned url: " + ex.Message); + s_logger.Error("Failed to get file header for non-presigned url: " + ex.Message); HttpWebResponse response = (HttpWebResponse)ex.Response; if (response.StatusCode == HttpStatusCode.Unauthorized) @@ -536,7 +536,7 @@ private SFFileMetadata HandleFileHeaderErrForGeneratedUrls(WebException ex, SFFi /// File Metadata private SFFileMetadata HandleUploadFileErr(WebException ex, SFFileMetadata fileMetadata) { - s_loggerPair.LogError("Failed to upload file: " + ex.Message); + s_logger.Error("Failed to upload file: " + ex.Message); fileMetadata.lastError = ex; @@ -570,7 +570,7 @@ private SFFileMetadata HandleUploadFileErr(WebException ex, SFFileMetadata fileM /// File Metadata private SFFileMetadata HandleDownloadFileErr(WebException ex, SFFileMetadata fileMetadata) { - s_loggerPair.LogError("Failed to download file: " + ex.Message); + s_logger.Error("Failed to download file: " + ex.Message); fileMetadata.lastError = ex; diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs index 160c615fd..025dbac15 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs @@ -72,7 +72,7 @@ internal class S3Metadata /// /// The logger. /// - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); /// /// The underlying S3 client. @@ -89,7 +89,7 @@ public SFS3Client( int parallel, ProxyCredentials proxyCredentials) { - s_loggerPair.LogDebug("Setting up a new AWS client "); + s_logger.Debug("Setting up a new AWS client "); // Get the key id and secret key from the response stageInfo.stageCredentials.TryGetValue(AWS_KEY_ID, out string awsAccessKeyId); @@ -537,7 +537,7 @@ private GetObjectRequest GetGetObjectRequest(ref AmazonS3Client client, SFFileMe /// The file metadata. private void HandleFileHeaderErr(Exception ex, SFFileMetadata fileMetadata) { - s_loggerPair.LogError("Failed to get file header: " + ex.Message); + s_logger.Error("Failed to get file header: " + ex.Message); switch (ex) { @@ -569,7 +569,7 @@ private void HandleFileHeaderErr(Exception ex, SFFileMetadata fileMetadata) /// The file metadata. private void HandleUploadFileErr(Exception ex, SFFileMetadata fileMetadata) { - s_loggerPair.LogError("Failed to upload file: " + ex.Message); + s_logger.Error("Failed to upload file: " + ex.Message); switch (ex) { @@ -599,7 +599,7 @@ private void HandleUploadFileErr(Exception ex, SFFileMetadata fileMetadata) /// The file metadata. private void HandleDownloadFileErr(Exception ex, SFFileMetadata fileMetadata) { - s_loggerPair.LogError("Failed to download file: " + ex.Message); + s_logger.Error("Failed to download file: " + ex.Message); switch (ex) { diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs index 3e36a76b5..1175ff3cd 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs @@ -31,7 +31,7 @@ class SFSnowflakeAzureClient : ISFRemoteStorageClient /// /// The logger. /// - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); /// /// The cloud blob client to use to upload and download data on Azure. @@ -44,7 +44,7 @@ class SFSnowflakeAzureClient : ISFRemoteStorageClient /// The command stage info. public SFSnowflakeAzureClient(PutGetStageInfo stageInfo) { - s_loggerPair.LogDebug("Setting up a new Azure client "); + s_logger.Debug("Setting up a new Azure client "); // Get the Azure SAS token and create the client if (stageInfo.stageCredentials.TryGetValue(AZURE_SAS_TOKEN, out string sasToken)) diff --git a/Snowflake.Data/Core/HttpUtil.cs b/Snowflake.Data/Core/HttpUtil.cs index 4197d1b1b..d352dd0d3 100644 --- a/Snowflake.Data/Core/HttpUtil.cs +++ b/Snowflake.Data/Core/HttpUtil.cs @@ -77,7 +77,7 @@ public sealed class HttpUtil static internal readonly int MAX_BACKOFF = 16; private static readonly int s_baseBackOffTime = 1; private static readonly int s_exponentialFactor = 2; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private static readonly List s_supportedEndpointsForRetryPolicy = new List { @@ -114,7 +114,7 @@ private HttpClient RegisterNewHttpClientIfNecessary(HttpClientConfig config, Del string name = config.ConfKey; if (!_HttpClients.ContainsKey(name)) { - s_loggerPair.LogDebug("Http client not registered. Adding."); + s_logger.Debug("Http client not registered. Adding."); var httpClient = new HttpClient( new RetryHandler(SetupCustomHttpHandler(config, customHandler), config.DisableRetry, config.ForceRetryOn404, config.MaxHttpRetries, config.IncludeRetryReason)) @@ -333,7 +333,7 @@ internal Uri Update(int retryReason = 0) } private class RetryHandler : DelegatingHandler { - static private SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + static private SFLogger s_logger = SFLoggerFactory.GetLogger(); private bool disableRetry; private bool forceRetryOn404; @@ -367,10 +367,10 @@ protected override async Task SendAsync(HttpRequestMessage TimeSpan httpTimeout = (TimeSpan)requestMessage.Properties[BaseRestRequest.HTTP_REQUEST_TIMEOUT_KEY]; TimeSpan restTimeout = (TimeSpan)requestMessage.Properties[BaseRestRequest.REST_REQUEST_TIMEOUT_KEY]; - if (s_loggerPair.IsDebugEnabled()) + if (s_logger.IsDebugEnabled()) { - s_loggerPair.LogDebug("Http request timeout : " + httpTimeout); - s_loggerPair.LogDebug("Rest request timeout : " + restTimeout); + s_logger.Debug("Http request timeout : " + httpTimeout); + s_logger.Debug("Rest request timeout : " + restTimeout); } CancellationTokenSource childCts = null; @@ -401,12 +401,12 @@ protected override async Task SendAsync(HttpRequestMessage lastException = e; if (cancellationToken.IsCancellationRequested) { - s_loggerPair.LogInformation("SF rest request timeout or explicit cancel called."); + s_logger.Info("SF rest request timeout or explicit cancel called."); cancellationToken.ThrowIfCancellationRequested(); } else if (childCts != null && childCts.Token.IsCancellationRequested) { - s_loggerPair.LogWarning("Http request timeout. Retry the request"); + s_logger.Warn("Http request timeout. Retry the request"); totalRetryTime += (int)httpTimeout.TotalSeconds; } else @@ -415,13 +415,13 @@ protected override async Task SendAsync(HttpRequestMessage if (innermostException is AuthenticationException) { - s_loggerPair.LogError("Non-retryable error encountered: ", e); + s_logger.Error("Non-retryable error encountered: ", e); throw; } else { //TODO: Should probably check to see if the error is recoverable or transient. - s_loggerPair.LogWarning("Error occurred during request, retrying...", e); + s_logger.Warn("Error occurred during request, retrying...", e); } } } @@ -445,12 +445,12 @@ protected override async Task SendAsync(HttpRequestMessage if (response.IsSuccessStatusCode) { - s_loggerPair.LogDebug($"Success Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + s_logger.Debug($"Success Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); return response; } else { - s_loggerPair.LogDebug($"Failed Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + s_logger.Debug($"Failed Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); bool isRetryable = isRetryableHTTPCode((int)response.StatusCode, forceRetryOn404); if (!isRetryable || disableRetry) @@ -463,19 +463,19 @@ protected override async Task SendAsync(HttpRequestMessage } else { - s_loggerPair.LogInformation("Response returned was null."); + s_logger.Info("Response returned was null."); } if (restTimeout.TotalSeconds > 0 && totalRetryTime >= restTimeout.TotalSeconds) { - s_loggerPair.LogDebug($"stop retry as connection_timeout {restTimeout.TotalSeconds} sec. reached"); + s_logger.Debug($"stop retry as connection_timeout {restTimeout.TotalSeconds} sec. reached"); if (response != null) { return response; } var errorMessage = $"http request failed and connection_timeout {restTimeout.TotalSeconds} sec. reached.\n"; errorMessage += $"Last exception encountered: {lastException}"; - s_loggerPair.LogError(errorMessage); + s_logger.Error(errorMessage); throw new OperationCanceledException(errorMessage); } @@ -488,14 +488,14 @@ protected override async Task SendAsync(HttpRequestMessage retryCount++; if ((maxRetryCount > 0) && (retryCount > maxRetryCount)) { - s_loggerPair.LogDebug($"stop retry as maxHttpRetries {maxRetryCount} reached"); + s_logger.Debug($"stop retry as maxHttpRetries {maxRetryCount} reached"); if (response != null) { return response; } var errorMessage = $"http request failed and max retry {maxRetryCount} reached.\n"; errorMessage += $"Last exception encountered: {lastException}"; - s_loggerPair.LogError(errorMessage); + s_logger.Error(errorMessage); throw new OperationCanceledException(errorMessage); } @@ -504,7 +504,7 @@ protected override async Task SendAsync(HttpRequestMessage requestMessage.RequestUri = updater.Update(errorReason); - s_loggerPair.LogDebug($"Sleep {backOffInSec} seconds and then retry the request, retryCount: {retryCount}"); + s_logger.Debug($"Sleep {backOffInSec} seconds and then retry the request, retryCount: {retryCount}"); await Task.Delay(TimeSpan.FromSeconds(backOffInSec), cancellationToken).ConfigureAwait(false); diff --git a/Snowflake.Data/Core/QueryContextCache.cs b/Snowflake.Data/Core/QueryContextCache.cs index 8b14bca1a..76f8bb825 100644 --- a/Snowflake.Data/Core/QueryContextCache.cs +++ b/Snowflake.Data/Core/QueryContextCache.cs @@ -75,7 +75,7 @@ internal class QueryContextCache private Dictionary _priorityMap; // Map for priority and QCC private Dictionary _newPriorityMap; // Intermediate map for priority and QCC for current round of merging private SortedSet _cacheSet; // Order data as per priority - private SFLoggerPair _loggerPair = SFLoggerPair.GetLoggerPair(); + private SFLogger _logger = SFLoggerFactory.GetLogger(); public QueryContextCache(int capacity) { @@ -91,7 +91,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) { if (_idMap.ContainsKey(id)) { - _loggerPair.LogDebug( + _logger.Debug( $"Merge with existing id in cache = {id}, priority = {priority}"); // ID found in the cache QueryContextElement qce = _idMap[id]; @@ -124,7 +124,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) // new id if (_priorityMap.ContainsKey(priority)) { - _loggerPair.LogDebug( + _logger.Debug( $"Merge with existing priority in cache = {id}, priority = {priority}"); // Same priority with different id QueryContextElement qce = _priorityMap[priority]; @@ -136,7 +136,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) { // new priority // Add new element in the cache - _loggerPair.LogDebug( + _logger.Debug( $"Adding new QCC item with either id nor priority found in cache id = {id}, priority = {priority}"); QueryContextElement newQCE = new QueryContextElement(id, readTimestamp, priority, context); AddQCE(newQCE); @@ -147,7 +147,7 @@ public void Merge(long id, long readTimestamp, long priority, string context) /** Sync the newPriorityMap with the priorityMap at the end of current round of merge */ public void SyncPriorityMap() { - _loggerPair.LogDebug( + _logger.Debug( $"syncPriorityMap called priorityMap size = {_priorityMap.Count}, newPrioirtyMap size = {_newPriorityMap.Count}"); foreach (KeyValuePair entry in _newPriorityMap) { @@ -163,7 +163,7 @@ public void SyncPriorityMap() */ public void CheckCacheCapacity() { - _loggerPair.LogDebug( + _logger.Debug( $"checkCacheCapacity() called. cacheSet size {_cacheSet.Count} cache capacity {_capacity}"); if (_cacheSet.Count > _capacity) { @@ -175,18 +175,18 @@ public void CheckCacheCapacity() } } - _loggerPair.LogDebug( + _logger.Debug( $"checkCacheCapacity() returns. cacheSet size {_cacheSet.Count} cache capacity {_capacity}"); } /** Clear the cache. */ public void ClearCache() { - _loggerPair.LogDebug("clearCache() called"); + _logger.Debug("clearCache() called"); _idMap.Clear(); _priorityMap.Clear(); _cacheSet.Clear(); - _loggerPair.LogDebug($"clearCache() returns. Number of entries in cache now {_cacheSet.Count}"); + _logger.Debug($"clearCache() returns. Number of entries in cache now {_cacheSet.Count}"); } public void SetCapacity(int cap) @@ -199,7 +199,7 @@ public void SetCapacity(int cap) if (_capacity == cap) return; - _loggerPair.LogDebug($"set capacity from {_capacity} to {cap}"); + _logger.Debug($"set capacity from {_capacity} to {cap}"); _capacity = cap; CheckCacheCapacity(); LogCacheEntries(); @@ -337,11 +337,11 @@ private void ReplaceQCE(QueryContextElement oldQCE, QueryContextElement newQCE) /** Debugging purpose, log the all entries in the cache. */ private void LogCacheEntries() { - if (_loggerPair.IsDebugEnabled()) + if (_logger.IsDebugEnabled()) { foreach (QueryContextElement elem in _cacheSet) { - _loggerPair.LogDebug($"Cache Entry: id: {elem.Id} readTimestamp: {elem.ReadTimestamp} priority: {elem.Priority}"); + _logger.Debug($"Cache Entry: id: {elem.Id} readTimestamp: {elem.ReadTimestamp} priority: {elem.Priority}"); } } } diff --git a/Snowflake.Data/Core/QueryResultsAwaiter.cs b/Snowflake.Data/Core/QueryResultsAwaiter.cs index 2021efdf7..5ea187fbe 100644 --- a/Snowflake.Data/Core/QueryResultsAwaiter.cs +++ b/Snowflake.Data/Core/QueryResultsAwaiter.cs @@ -36,7 +36,7 @@ internal QueryResultsRetryConfig(int asyncNoDataMaxRetry, int[] asyncRetryPatter internal class QueryResultsAwaiter { - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private static readonly Regex UuidRegex = new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); @@ -64,7 +64,7 @@ internal QueryStatus GetQueryStatus(SnowflakeDbConnection connection, string que else { var errorMessage = $"The given query id {queryId} is not valid uuid"; - s_loggerPair.LogError(errorMessage); + s_logger.Error(errorMessage); throw new Exception(errorMessage); } } @@ -79,7 +79,7 @@ internal async Task GetQueryStatusAsync(SnowflakeDbConnection conne else { var errorMessage = $"The given query id {queryId} is not valid uuid"; - s_loggerPair.LogError(errorMessage); + s_logger.Error(errorMessage); throw new Exception(errorMessage); } } @@ -101,7 +101,7 @@ internal async Task RetryUntilQueryResultIsAvailable(SnowflakeDbConnection conne { if (cancellationToken.IsCancellationRequested) { - s_loggerPair.LogDebug("Cancellation requested for getting results from query id"); + s_logger.Debug("Cancellation requested for getting results from query id"); cancellationToken.ThrowIfCancellationRequested(); } @@ -131,7 +131,7 @@ internal async Task RetryUntilQueryResultIsAvailable(SnowflakeDbConnection conne if (noDataCounter > _queryResultsRetryConfig._asyncNoDataMaxRetry) { var errorMessage = "Max retry for no data is reached"; - s_loggerPair.LogError(errorMessage); + s_logger.Error(errorMessage); throw new Exception(errorMessage); } } diff --git a/Snowflake.Data/Core/RestRequester.cs b/Snowflake.Data/Core/RestRequester.cs index 8cf898f7e..a6dc8f8ec 100644 --- a/Snowflake.Data/Core/RestRequester.cs +++ b/Snowflake.Data/Core/RestRequester.cs @@ -39,7 +39,7 @@ internal interface IMockRestRequester : IRestRequester internal class RestRequester : IRestRequester { - private static SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static SFLogger s_logger = SFLoggerFactory.GetLogger(); protected HttpClient _HttpClient; @@ -113,18 +113,18 @@ protected virtual async Task SendAsync(HttpRequestMessage m HttpResponseMessage response = null; try { - s_loggerPair.LogDebug($"Executing: {sid} {message.Method} {message.RequestUri} HTTP/{message.Version}"); + s_logger.Debug($"Executing: {sid} {message.Method} {message.RequestUri} HTTP/{message.Version}"); response = await _HttpClient .SendAsync(message, HttpCompletionOption.ResponseHeadersRead, linkedCts.Token) .ConfigureAwait(false); if (!response.IsSuccessStatusCode) { - s_loggerPair.LogError($"Failed Response: {sid} {message.Method} {message.RequestUri} StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + s_logger.Error($"Failed Response: {sid} {message.Method} {message.RequestUri} StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); } else { - s_loggerPair.LogDebug($"Succeeded Response: {sid} {message.Method} {message.RequestUri}"); + s_logger.Debug($"Succeeded Response: {sid} {message.Method} {message.RequestUri}"); } response.EnsureSuccessStatusCode(); diff --git a/Snowflake.Data/Core/SFBindUploader.cs b/Snowflake.Data/Core/SFBindUploader.cs index 15263eca0..00031ab2a 100644 --- a/Snowflake.Data/Core/SFBindUploader.cs +++ b/Snowflake.Data/Core/SFBindUploader.cs @@ -35,7 +35,7 @@ class SFBindUploader private string requestId; - private SFLoggerPair loggerPair = SFLoggerPair.GetLoggerPair(); + private SFLogger loggerPair = SFLoggerFactory.GetLogger(); private string stagePath; @@ -309,7 +309,7 @@ private void CreateStage() catch (Exception e) { session.SetArrayBindStageThreshold(0); - loggerPair.LogError("Failed to create temporary stage for array binds.", e); + loggerPair.Error("Failed to create temporary stage for array binds.", e); throw; } } @@ -333,7 +333,7 @@ internal async Task CreateStageAsync(CancellationToken cancellationToken) catch (Exception e) { session.SetArrayBindStageThreshold(0); - loggerPair.LogError("Failed to create temporary stage for array binds.", e); + loggerPair.Error("Failed to create temporary stage for array binds.", e); throw; } } diff --git a/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs b/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs index cd680fd96..d4f76ff44 100755 --- a/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs +++ b/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs @@ -22,7 +22,7 @@ namespace Snowflake.Data.Core { class SFBlockingChunkDownloaderV3 : IChunkDownloader { - static private SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + static private SFLogger s_logger = SFLoggerFactory.GetLogger(); private List chunkDatas = new List(); @@ -99,7 +99,7 @@ private int GetPrefetchThreads(SFBaseResultSet resultSet) public async Task GetNextChunkAsync() { - s_loggerPair.LogInformation($"NextChunkToConsume: {nextChunkToConsumeIndex}, NextChunkToDownload: {nextChunkToDownloadIndex}"); + s_logger.Info($"NextChunkToConsume: {nextChunkToConsumeIndex}, NextChunkToDownload: {nextChunkToDownloadIndex}"); if (nextChunkToConsumeIndex < chunkInfos.Count) { Task chunk = taskQueues[nextChunkToConsumeIndex % prefetchSlot]; @@ -192,7 +192,7 @@ private async Task DownloadChunkAsync(DownloadContextV3 downloa { if ((maxRetry <= 0) || (retryCount < maxRetry)) { - s_loggerPair.LogDebug($"Retry {retryCount}/{maxRetry} of parse stream to chunk error: " + e.Message); + s_logger.Debug($"Retry {retryCount}/{maxRetry} of parse stream to chunk error: " + e.Message); retry = true; // reset the chunk before retry in case there could be garbage // data left from last attempt @@ -209,13 +209,13 @@ private async Task DownloadChunkAsync(DownloadContextV3 downloa else { //parse error - s_loggerPair.LogError("Failed retries of parse stream to chunk error: " + e.Message); + s_logger.Error("Failed retries of parse stream to chunk error: " + e.Message); throw new Exception("Parse stream to chunk error: " + e.Message); } } } } while (retry); - s_loggerPair.LogInformation($"Succeed downloading chunk #{chunk.ChunkIndex}"); + s_logger.Info($"Succeed downloading chunk #{chunk.ChunkIndex}"); return chunk; } diff --git a/Snowflake.Data/Core/SFMultiStatementsResultSet.cs b/Snowflake.Data/Core/SFMultiStatementsResultSet.cs index 5e8946554..5d1e67f65 100644 --- a/Snowflake.Data/Core/SFMultiStatementsResultSet.cs +++ b/Snowflake.Data/Core/SFMultiStatementsResultSet.cs @@ -15,7 +15,7 @@ class SFMultiStatementsResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => curResultSet.ResultFormat; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private string[] resultIds; diff --git a/Snowflake.Data/Core/SFResultSet.cs b/Snowflake.Data/Core/SFResultSet.cs index e6408c97b..96c349de3 100755 --- a/Snowflake.Data/Core/SFResultSet.cs +++ b/Snowflake.Data/Core/SFResultSet.cs @@ -16,7 +16,7 @@ class SFResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => ResultFormat.JSON; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private readonly int _totalChunkCount; @@ -51,7 +51,7 @@ public SFResultSet(QueryExecResponseData responseData, SFStatement sfStatement, } catch(System.Exception ex) { - s_loggerPair.LogError("Result set error queryId="+responseData.queryId, ex); + s_logger.Error("Result set error queryId="+responseData.queryId, ex); throw; } } @@ -100,7 +100,7 @@ public SFResultSet(PutGetResponseData responseData, SFStatement sfStatement, Can internal void ResetChunkInfo(BaseResultChunk nextChunk) { - s_loggerPair.LogDebug($"Received chunk #{nextChunk.ChunkIndex + 1} of {_totalChunkCount}"); + s_logger.Debug($"Received chunk #{nextChunk.ChunkIndex + 1} of {_totalChunkCount}"); _currentChunk.RowSet = null; _currentChunk = nextChunk; } @@ -116,7 +116,7 @@ internal override async Task NextAsync() { // GetNextChunk could be blocked if download result is not done yet. // So put this piece of code in a seperate task - s_loggerPair.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_logger.Debug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); BaseResultChunk nextChunk = await _chunkDownloader.GetNextChunkAsync().ConfigureAwait(false); @@ -139,7 +139,7 @@ internal override bool Next() if (_chunkDownloader != null) { - s_loggerPair.LogDebug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + + s_logger.Debug($"Get next chunk from chunk downloader, chunk: {_currentChunk.ChunkIndex + 1}/{_totalChunkCount}" + $" rows: {_currentChunk.RowCount}, size compressed: {_currentChunk.CompressedSize}," + $" size uncompressed: {_currentChunk.UncompressedSize}"); BaseResultChunk nextChunk = Task.Run(async() => await (_chunkDownloader.GetNextChunkAsync()).ConfigureAwait(false)).Result; diff --git a/Snowflake.Data/Core/SFResultSetMetaData.cs b/Snowflake.Data/Core/SFResultSetMetaData.cs index fed09201a..3bc847ac3 100755 --- a/Snowflake.Data/Core/SFResultSetMetaData.cs +++ b/Snowflake.Data/Core/SFResultSetMetaData.cs @@ -12,7 +12,7 @@ namespace Snowflake.Data.Core { class SFResultSetMetaData { - static private readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + static private readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private int columnCount; @@ -92,7 +92,7 @@ internal int GetColumnIndexByName(string targetColumnName) { if (String.Compare(rowType.name, targetColumnName, false) == 0 ) { - s_loggerPair.LogInformation($"Found column name {targetColumnName} under index {indexCounter}"); + s_logger.Info($"Found column name {targetColumnName} under index {indexCounter}"); columnNameToIndexCache[targetColumnName] = indexCounter; return indexCounter; } diff --git a/Snowflake.Data/Core/SFStatement.cs b/Snowflake.Data/Core/SFStatement.cs index 3d91bad84..90ad6e1d9 100644 --- a/Snowflake.Data/Core/SFStatement.cs +++ b/Snowflake.Data/Core/SFStatement.cs @@ -97,7 +97,7 @@ internal static bool IsAnError(QueryStatus status) class SFStatement { - static private SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + static private SFLogger s_logger = SFLoggerFactory.GetLogger(); internal SFSession SfSession { get; set; } @@ -168,7 +168,7 @@ private void AssignQueryRequestId() if (_requestId != null) { - s_loggerPair.LogInformation("Another query is running."); + s_logger.Info("Another query is running."); throw new SnowflakeDbException(SFError.STATEMENT_ALREADY_RUNNING_QUERY); } @@ -340,7 +340,7 @@ private void registerQueryCancellationCallback(int timeout, CancellationToken ex catch (Exception ex) { // Prevent an unhandled exception from being thrown - s_loggerPair.LogError("Unable to cancel query.", ex); + s_logger.Error("Unable to cancel query.", ex); } }); } @@ -386,7 +386,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti } catch (Exception e) { - s_loggerPair.LogWarning("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); + s_logger.Warn("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); } finally { @@ -424,7 +424,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti if (SessionExpired(response)) { - s_loggerPair.LogInformation("Ping pong request failed with session expired, trying to renew the session."); + s_logger.Info("Ping pong request failed with session expired, trying to renew the session."); await SfSession.renewSessionAsync(cancellationToken).ConfigureAwait(false); } else @@ -438,7 +438,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti } catch { - s_loggerPair.LogError("Query execution failed."); + s_logger.Error("Query execution failed."); throw; } finally @@ -484,7 +484,7 @@ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, string tri bindings, describeOnly); - s_loggerPair.LogDebug("PUT/GET queryId: " + (response.data != null ? response.data.queryId : "Unknown")); + s_logger.Debug("PUT/GET queryId: " + (response.data != null ? response.data.queryId : "Unknown")); SFFileTransferAgent fileTransferAgent = new SFFileTransferAgent(trimmedSql, SfSession, response.data, CancellationToken.None); @@ -500,13 +500,13 @@ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, string tri } catch (SnowflakeDbException ex) { - s_loggerPair.LogError($"Query execution failed, QueryId: {ex.QueryId??"unavailable"}", ex); + s_logger.Error($"Query execution failed, QueryId: {ex.QueryId??"unavailable"}", ex); _lastQueryId = ex.QueryId ?? _lastQueryId; throw; } catch (Exception ex) { - s_loggerPair.LogError("Query execution failed.", ex); + s_logger.Error("Query execution failed.", ex); throw new SnowflakeDbException(ex, SFError.INTERNAL_ERROR); } } @@ -538,7 +538,7 @@ private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dicti } catch (Exception e) { - s_loggerPair.LogWarning("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); + s_logger.Warn("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); } finally { @@ -558,7 +558,7 @@ private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dicti } catch (Exception ex) { - s_loggerPair.LogError("Query execution failed.", ex); + s_logger.Error("Query execution failed.", ex); if (ex is SnowflakeDbException snowflakeDbException) { _lastQueryId = snowflakeDbException.QueryId ?? _lastQueryId; @@ -624,11 +624,11 @@ internal void Cancel() if (response.success) { - s_loggerPair.LogInformation("Query cancellation succeed"); + s_logger.Info("Query cancellation succeed"); } else { - s_loggerPair.LogWarning("Query cancellation failed."); + s_logger.Warn("Query cancellation failed."); } CleanUpCancellationTokenSources(); } @@ -685,7 +685,7 @@ internal T ExecuteHelper( if (SessionExpired(response)) { - s_loggerPair.LogInformation("Ping pong request failed with session expired, trying to renew the session."); + s_logger.Info("Ping pong request failed with session expired, trying to renew the session."); SfSession.renewSession(); } else @@ -709,7 +709,7 @@ internal T ExecuteHelper( } catch (Exception ex) { - s_loggerPair.LogError("Query execution failed.", ex); + s_logger.Error("Query execution failed.", ex); throw; } finally @@ -772,7 +772,7 @@ internal async Task ExecuteAsyncHelper( if (SessionExpired(response)) { - s_loggerPair.LogInformation("Ping pong request failed with session expired, trying to renew the session."); + s_logger.Info("Ping pong request failed with session expired, trying to renew the session."); await SfSession.renewSessionAsync(cancellationToken).ConfigureAwait(false); } else @@ -796,7 +796,7 @@ internal async Task ExecuteAsyncHelper( } catch (Exception ex) { - s_loggerPair.LogError("Query execution failed.", ex); + s_logger.Error("Query execution failed.", ex); throw; } finally @@ -873,7 +873,7 @@ internal QueryStatus GetQueryStatus(string queryId) } catch { - s_loggerPair.LogError("Query execution failed."); + s_logger.Error("Query execution failed."); throw; } finally @@ -928,7 +928,7 @@ internal async Task GetQueryStatusAsync(string queryId, Cancellatio } catch { - s_loggerPair.LogError("Query execution failed."); + s_logger.Error("Query execution failed."); throw; } finally @@ -991,7 +991,7 @@ internal static string TrimSql(string originalSql) var trimmedQuery = builder.ToString(); trimmedQuery = trimmedQuery.Trim(); - s_loggerPair.LogDebug("Trimmed query : " + trimmedQuery); + s_logger.Debug("Trimmed query : " + trimmedQuery); return trimmedQuery; } diff --git a/Snowflake.Data/Core/Session/ConnectionPoolManager.cs b/Snowflake.Data/Core/Session/ConnectionPoolManager.cs index de4e6fd88..09bfa5821 100644 --- a/Snowflake.Data/Core/Session/ConnectionPoolManager.cs +++ b/Snowflake.Data/Core/Session/ConnectionPoolManager.cs @@ -16,7 +16,7 @@ namespace Snowflake.Data.Core.Session { internal sealed class ConnectionPoolManager : IConnectionManager { - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private static readonly Object s_poolsLock = new Object(); private static readonly Exception s_operationNotAvailable = new Exception("You cannot change connection pool parameters for all the pools. Instead you can change it on a particular pool"); private readonly Dictionary _pools; @@ -31,31 +31,31 @@ internal ConnectionPoolManager() public SFSession GetSession(string connectionString, SecureString password) { - s_loggerPair.LogDebug($"ConnectionPoolManager::GetSession"); + s_logger.Debug($"ConnectionPoolManager::GetSession"); return GetPool(connectionString, password).GetSession(); } public Task GetSessionAsync(string connectionString, SecureString password, CancellationToken cancellationToken) { - s_loggerPair.LogDebug($"ConnectionPoolManager::GetSessionAsync"); + s_logger.Debug($"ConnectionPoolManager::GetSessionAsync"); return GetPool(connectionString, password).GetSessionAsync(cancellationToken); } public bool AddSession(SFSession session) { - s_loggerPair.LogDebug("ConnectionPoolManager::AddSession"); + s_logger.Debug("ConnectionPoolManager::AddSession"); return GetPool(session.ConnectionString, session.Password).AddSession(session, true); } public void ReleaseBusySession(SFSession session) { - s_loggerPair.LogDebug("ConnectionPoolManager::ReleaseBusySession"); + s_logger.Debug("ConnectionPoolManager::ReleaseBusySession"); GetPool(session.ConnectionString, session.Password).ReleaseBusySession(session); } public void ClearAllPools() { - s_loggerPair.LogDebug("ConnectionPoolManager::ClearAllPools"); + s_logger.Debug("ConnectionPoolManager::ClearAllPools"); foreach (var sessionPool in _pools.Values) { sessionPool.DestroyPool(); @@ -70,7 +70,7 @@ public void SetMaxPoolSize(int maxPoolSize) public int GetMaxPoolSize() { - s_loggerPair.LogDebug("ConnectionPoolManager::GetMaxPoolSize"); + s_logger.Debug("ConnectionPoolManager::GetMaxPoolSize"); var values = _pools.Values.Select(it => it.GetMaxPoolSize()).Distinct().ToList(); switch (values.Count) { @@ -90,7 +90,7 @@ public void SetTimeout(long connectionTimeout) public long GetTimeout() { - s_loggerPair.LogDebug("ConnectionPoolManager::GetTimeout"); + s_logger.Debug("ConnectionPoolManager::GetTimeout"); var values = _pools.Values.Select(it => it.GetTimeout()).Distinct().ToList(); switch (values.Count) { @@ -105,7 +105,7 @@ public long GetTimeout() public int GetCurrentPoolSize() { - s_loggerPair.LogDebug("ConnectionPoolManager::GetCurrentPoolSize"); + s_logger.Debug("ConnectionPoolManager::GetCurrentPoolSize"); return _pools.Values.Select(it => it.GetCurrentPoolSize()).Sum(); } @@ -116,13 +116,13 @@ public bool SetPooling(bool poolingEnabled) public bool GetPooling() { - s_loggerPair.LogDebug("ConnectionPoolManager::GetPooling"); + s_logger.Debug("ConnectionPoolManager::GetPooling"); return true; // in new pool pooling is always enabled by default, disabling only by connection string parameter } public SessionPool GetPool(string connectionString, SecureString password) { - s_loggerPair.LogDebug("ConnectionPoolManager::GetPool with connection string and secure password"); + s_logger.Debug("ConnectionPoolManager::GetPool with connection string and secure password"); var poolKey = GetPoolKey(connectionString, password); if (_pools.TryGetValue(poolKey, out var item)) @@ -138,7 +138,7 @@ public SessionPool GetPool(string connectionString, SecureString password) poolCreatedWhileWaitingOnLock.ValidateSecurePassword(password); return poolCreatedWhileWaitingOnLock; } - s_loggerPair.LogInformation($"Creating new pool"); + s_logger.Info($"Creating new pool"); var pool = SessionPool.CreateSessionPool(connectionString, password); _pools.Add(poolKey, pool); return pool; @@ -147,7 +147,7 @@ public SessionPool GetPool(string connectionString, SecureString password) public SessionPool GetPool(string connectionString) { - s_loggerPair.LogDebug("ConnectionPoolManager::GetPool with connection string"); + s_logger.Debug("ConnectionPoolManager::GetPool with connection string"); return GetPool(connectionString, null); } diff --git a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs index 05b80164a..97487256e 100644 --- a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs +++ b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs @@ -62,11 +62,11 @@ public virtual void Init(string configFilePathFromConnectionString) } if (string.IsNullOrEmpty(configFilePathFromConnectionString)) { - s_logger.Information($"Attempting to enable easy logging without a config file specified from connection string"); + s_logger.Info($"Attempting to enable easy logging without a config file specified from connection string"); } else { - s_logger.Information($"Attempting to enable easy logging using config file specified from connection string: {configFilePathFromConnectionString}"); + s_logger.Info($"Attempting to enable easy logging using config file specified from connection string: {configFilePathFromConnectionString}"); } var config = _easyLoggingConfigProvider.ProvideConfig(configFilePathFromConnectionString); if (config == null) @@ -76,8 +76,8 @@ public virtual void Init(string configFilePathFromConnectionString) } var logLevel = GetLogLevel(config.CommonProps.LogLevel); var logPath = GetLogPath(config.CommonProps.LogPath); - s_logger.Information($"LogLevel set to {logLevel}"); - s_logger.Information($"LogPath set to {logPath}"); + s_logger.Info($"LogLevel set to {logLevel}"); + s_logger.Info($"LogPath set to {logPath}"); _easyLoggerManager.ReconfigureEasyLogging(logLevel, logPath); _initTrialParameters = new EasyLoggingInitTrialParameters(configFilePathFromConnectionString); } @@ -100,7 +100,7 @@ private bool AllowedToInitialize(string configFilePathFromConnectionString) var isAllowedToInitialize = !everTriedToInitialize || (triedToInitializeWithoutConfigFile && isGivenConfigFilePath); if (!isAllowedToInitialize && _initTrialParameters.HasDifferentConfigPath(configFilePathFromConnectionString)) { - s_logger.Warning($"Easy logging will not be configured for CLIENT_CONFIG_FILE={configFilePathFromConnectionString} because it was previously configured for a different client config"); + s_logger.Warn($"Easy logging will not be configured for CLIENT_CONFIG_FILE={configFilePathFromConnectionString} because it was previously configured for a different client config"); } return isAllowedToInitialize; @@ -110,7 +110,7 @@ private EasyLoggingLogLevel GetLogLevel(string logLevel) { if (string.IsNullOrEmpty(logLevel)) { - s_logger.Warning("LogLevel in client config not found. Using default value: OFF"); + s_logger.Warn("LogLevel in client config not found. Using default value: OFF"); return EasyLoggingLogLevel.Off; } return EasyLoggingLogLevelExtensions.From(logLevel); @@ -121,7 +121,7 @@ private string GetLogPath(string logPath) var logPathOrDefault = logPath; if (string.IsNullOrEmpty(logPath)) { - s_logger.Warning("LogPath in client config not found. Using home directory as a default value"); + s_logger.Warn("LogPath in client config not found. Using home directory as a default value"); logPathOrDefault = HomeDirectoryProvider.HomeDirectory(_environmentOperations); if (string.IsNullOrEmpty(logPathOrDefault)) { @@ -163,7 +163,7 @@ private void CheckDirPermissionsOnlyAllowUser(string dirPath) var dirPermissions = _unixOperations.GetDirPermissions(dirPath); if (dirPermissions != FileAccessPermissions.UserReadWriteExecute) { - s_logger.Warning($"Access permission for the logs directory is currently " + + s_logger.Warn($"Access permission for the logs directory is currently " + $"{UnixFilePermissionsConverter.ConvertFileAccessPermissionsToInt(dirPermissions)} " + $"and is potentially accessible to users other than the owner of the logs directory"); } diff --git a/Snowflake.Data/Core/Session/SFSession.cs b/Snowflake.Data/Core/Session/SFSession.cs index aa8085f95..d17f5f675 100755 --- a/Snowflake.Data/Core/Session/SFSession.cs +++ b/Snowflake.Data/Core/Session/SFSession.cs @@ -23,7 +23,7 @@ public class SFSession { public const int SF_SESSION_EXPIRED_CODE = 390112; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private static readonly Regex APPLICATION_REGEX = new Regex(@"^[A-Za-z]([A-Za-z0-9.\-_]){1,50}$"); @@ -114,9 +114,9 @@ internal void ProcessLoginResponse(LoginResponse authnResponse) UpdateSessionParameterMap(authnResponse.data.nameValueParameter); if (_disableQueryContextCache) { - s_loggerPair.LogDebug("Query context cache disabled."); + s_logger.Debug("Query context cache disabled."); } - s_loggerPair.LogDebug($"Session opened: {sessionId}"); + s_logger.Debug($"Session opened: {sessionId}"); _startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } else @@ -127,7 +127,7 @@ internal void ProcessLoginResponse(LoginResponse authnResponse) authnResponse.message, ""); - s_loggerPair.LogError("Authentication failed", e); + s_logger.Error("Authentication failed", e); throw e; } } @@ -193,12 +193,12 @@ internal SFSession( } catch (SnowflakeDbException e) { - s_loggerPair.LogError("Unable to initialize session ", e); + s_logger.Error("Unable to initialize session ", e); throw; } catch (Exception e) { - s_loggerPair.LogError("Unable to initialize session ", e); + s_logger.Error("Unable to initialize session ", e); throw new SnowflakeDbException(e, SnowflakeDbException.CONNECTION_FAILURE_SSTATE, SFError.INVALID_CONNECTION_STRING, @@ -251,7 +251,7 @@ internal Uri BuildUri(string path, Dictionary queryParams = null internal virtual void Open() { - s_loggerPair.LogDebug("Open Session"); + s_logger.Debug("Open Session"); if (authenticator == null) { @@ -263,7 +263,7 @@ internal virtual void Open() internal virtual async Task OpenAsync(CancellationToken cancellationToken) { - s_loggerPair.LogDebug("Open Session Async"); + s_logger.Debug("Open Session Async"); if (authenticator == null) { @@ -277,7 +277,7 @@ internal void close() { // Nothing to do if the session is not open if (!IsEstablished()) return; - s_loggerPair.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + s_logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); PostCloseSession(closeSessionRequest, restRequester); @@ -288,7 +288,7 @@ internal void CloseNonBlocking() { // Nothing to do if the session is not open if (!IsEstablished()) return; - s_loggerPair.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + s_logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); Task.Run(() => PostCloseSession(closeSessionRequest, restRequester)); @@ -299,19 +299,19 @@ internal async Task CloseAsync(CancellationToken cancellationToken) { // Nothing to do if the session is not open if (!IsEstablished()) return; - s_loggerPair.LogDebug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + s_logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); - s_loggerPair.LogDebug($"Closing session async"); + s_logger.Debug($"Closing session async"); var response = await restRequester.PostAsync(closeSessionRequest, cancellationToken).ConfigureAwait(false); if (!response.success) { - s_loggerPair.LogError($"Failed to close session {sessionId}, error ignored. Code: {response.code} Message: {response.message}"); + s_logger.Error($"Failed to close session {sessionId}, error ignored. Code: {response.code} Message: {response.message}"); } - s_loggerPair.LogDebug($"Session closed: {sessionId}"); + s_logger.Debug($"Session closed: {sessionId}"); sessionToken = null; } @@ -319,18 +319,18 @@ private static void PostCloseSession(SFRestRequest closeSessionRequest, IRestReq { try { - s_loggerPair.LogDebug($"Closing session"); + s_logger.Debug($"Closing session"); var response = restRequester.Post(closeSessionRequest); if (!response.success) { - s_loggerPair.LogError($"Failed to close session: {closeSessionRequest.sid}, error ignored. Code: {response.code} Message: {response.message}"); + s_logger.Error($"Failed to close session: {closeSessionRequest.sid}, error ignored. Code: {response.code} Message: {response.message}"); } - s_loggerPair.LogDebug($"Session closed: {closeSessionRequest.sid}"); + s_logger.Debug($"Session closed: {closeSessionRequest.sid}"); } catch (Exception) { - s_loggerPair.LogError($"Failed to close session: {closeSessionRequest.sid}, because of exception."); + s_logger.Error($"Failed to close session: {closeSessionRequest.sid}, because of exception."); throw; } } @@ -354,13 +354,13 @@ private SFRestRequest PrepareCloseSessionRequest() internal void renewSession() { - s_loggerPair.LogInformation("Renew the session."); + s_logger.Info("Renew the session."); var response = restRequester.Post(getRenewSessionRequest()); if (!response.success) { SnowflakeDbException e = new SnowflakeDbException("", response.code, response.message, sessionId); - s_loggerPair.LogError($"Renew session (ID: {sessionId}) failed", e); + s_logger.Error($"Renew session (ID: {sessionId}) failed", e); throw e; } else @@ -372,7 +372,7 @@ internal void renewSession() internal async Task renewSessionAsync(CancellationToken cancellationToken) { - s_loggerPair.LogInformation("Renew the session."); + s_logger.Info("Renew the session."); var response = await restRequester.PostAsync( getRenewSessionRequest(), @@ -382,7 +382,7 @@ await restRequester.PostAsync( { SnowflakeDbException e = new SnowflakeDbException("", response.code, response.message, sessionId); - s_loggerPair.LogError($"Renew session (ID: {sessionId}) failed", e); + s_logger.Error($"Renew session (ID: {sessionId}) failed", e); throw e; } else @@ -430,7 +430,7 @@ internal SFRestRequest BuildTimeoutRestRequest(Uri uri, Object body) internal void UpdateSessionParameterMap(List parameterList) { - s_loggerPair.LogDebug("Update parameter map"); + s_logger.Debug("Update parameter map"); // with HTAP parameter removal parameters might not returned // query response if (parameterList is null) @@ -578,7 +578,7 @@ public void SetArrayBindStageThreshold(int arrayBindStageThreshold) internal void heartbeat() { - s_loggerPair.LogDebug("heartbeat"); + s_logger.Debug("heartbeat"); bool retry = false; if (IsEstablished()) @@ -599,16 +599,16 @@ internal void heartbeat() }; var response = restRequester.Post(heartBeatSessionRequest); - s_loggerPair.LogDebug("heartbeat response=" + response); + s_logger.Debug("heartbeat response=" + response); if (response.success) { - s_loggerPair.LogDebug("SFSession::heartbeat success, session token did not expire."); + s_logger.Debug("SFSession::heartbeat success, session token did not expire."); } else { if (response.code == SF_SESSION_EXPIRED_CODE) { - s_loggerPair.LogDebug($"SFSession ::heartbeat Session ID: {sessionId} session token expired and retry heartbeat"); + s_logger.Debug($"SFSession ::heartbeat Session ID: {sessionId} session token expired and retry heartbeat"); try { renewSession(); @@ -621,12 +621,12 @@ internal void heartbeat() // the heart beat, it's possible that the session get // closed when sending renew request and caused exception // thrown from renewSession(), simply ignore that - s_loggerPair.LogError($"renew session (ID: {sessionId}) failed.", ex); + s_logger.Error($"renew session (ID: {sessionId}) failed.", ex); } } else { - s_loggerPair.LogError($"heartbeat failed for session ID: {sessionId}."); + s_logger.Error($"heartbeat failed for session ID: {sessionId}."); } } retry = false; diff --git a/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs b/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs index f9b08eb86..2d818f8c8 100644 --- a/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs +++ b/Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs @@ -21,7 +21,7 @@ internal class SFSessionHttpClientProperties public const bool DefaultPoolingEnabled = true; public const int DefaultMaxHttpRetries = 7; public static readonly TimeSpan DefaultRetryTimeout = TimeSpan.FromSeconds(300); - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); internal bool validateDefaultParameters; internal bool clientSessionKeepAlive; @@ -68,11 +68,11 @@ private void DisablePoolingIfNotExplicitlyEnabled(SFSessionProperties properties if (!properties.IsPoolingEnabledValueProvided && _poolingEnabled) { _poolingEnabled = false; - s_loggerPair.LogInformation($"Disabling connection pooling for {authenticationDescription} authentication"); + s_logger.Info($"Disabling connection pooling for {authenticationDescription} authentication"); } else if (properties.IsPoolingEnabledValueProvided && _poolingEnabled) { - s_loggerPair.LogWarning($"Connection pooling is enabled for {authenticationDescription} authentication which is not recommended"); + s_logger.Warn($"Connection pooling is enabled for {authenticationDescription} authentication which is not recommended"); } } @@ -101,16 +101,16 @@ private void ValidateConnectionTimeout() { if (TimeoutHelper.IsZeroLength(connectionTimeout)) { - s_loggerPair.LogWarning("Connection timeout provided is 0. Timeout will be infinite"); + s_logger.Warn("Connection timeout provided is 0. Timeout will be infinite"); connectionTimeout = TimeoutHelper.Infinity(); } else if (TimeoutHelper.IsInfinite(connectionTimeout)) { - s_loggerPair.LogWarning("Connection timeout provided is negative. Timeout will be infinite."); + s_logger.Warn("Connection timeout provided is negative. Timeout will be infinite."); } if (!TimeoutHelper.IsInfinite(connectionTimeout) && connectionTimeout < DefaultRetryTimeout) { - s_loggerPair.LogWarning($"Connection timeout provided is less than recommended minimum value of {DefaultRetryTimeout}"); + s_logger.Warn($"Connection timeout provided is less than recommended minimum value of {DefaultRetryTimeout}"); } } @@ -118,17 +118,17 @@ private void ValidateRetryTimeout() { if (retryTimeout.TotalMilliseconds > 0 && retryTimeout < DefaultRetryTimeout) { - s_loggerPair.LogWarning($"Max retry timeout provided is less than the allowed minimum value of {DefaultRetryTimeout}"); + s_logger.Warn($"Max retry timeout provided is less than the allowed minimum value of {DefaultRetryTimeout}"); retryTimeout = DefaultRetryTimeout; } else if (TimeoutHelper.IsZeroLength(retryTimeout)) { - s_loggerPair.LogWarning($"Max retry timeout provided is 0. Timeout will be infinite"); + s_logger.Warn($"Max retry timeout provided is 0. Timeout will be infinite"); retryTimeout = TimeoutHelper.Infinity(); } else if (TimeoutHelper.IsInfinite(retryTimeout)) { - s_loggerPair.LogWarning($"Max retry timeout provided is negative. Timeout will be infinite"); + s_logger.Warn($"Max retry timeout provided is negative. Timeout will be infinite"); } } @@ -136,7 +136,7 @@ private void ShortenConnectionTimeoutByRetryTimeout() { if (!TimeoutHelper.IsInfinite(retryTimeout) && retryTimeout < connectionTimeout) { - s_loggerPair.LogWarning($"Connection timeout greater than retry timeout. Setting connection time same as retry timeout"); + s_logger.Warn($"Connection timeout greater than retry timeout. Setting connection time same as retry timeout"); connectionTimeout = retryTimeout; } } @@ -145,13 +145,13 @@ private void ValidateHttpRetries() { if (maxHttpRetries > 0 && maxHttpRetries < DefaultMaxHttpRetries) { - s_loggerPair.LogWarning($"Max retry count provided is less than the allowed minimum value of {DefaultMaxHttpRetries}"); + s_logger.Warn($"Max retry count provided is less than the allowed minimum value of {DefaultMaxHttpRetries}"); maxHttpRetries = DefaultMaxHttpRetries; } else if (maxHttpRetries == 0) { - s_loggerPair.LogWarning($"Max retry count provided is 0. Retry count will be infinite"); + s_logger.Warn($"Max retry count provided is 0. Retry count will be infinite"); } } @@ -171,7 +171,7 @@ private void ValidateWaitingForSessionIdleTimeout() } if (TimeoutHelper.IsZeroLength(_waitingForSessionIdleTimeout)) { - s_loggerPair.LogWarning("Waiting for idle session timeout is 0. There will be no waiting for idle session"); + s_logger.Warn("Waiting for idle session timeout is 0. There will be no waiting for idle session"); } } diff --git a/Snowflake.Data/Core/Session/SFSessionProperty.cs b/Snowflake.Data/Core/Session/SFSessionProperty.cs index 42f518aeb..f0d09188b 100644 --- a/Snowflake.Data/Core/Session/SFSessionProperty.cs +++ b/Snowflake.Data/Core/Session/SFSessionProperty.cs @@ -126,7 +126,7 @@ class SFSessionPropertyAttr : Attribute class SFSessionProperties : Dictionary { - private static SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static SFLogger s_logger = SFLoggerFactory.GetLogger(); internal string ConnectionStringWithoutSecrets { get; set; } @@ -171,7 +171,7 @@ public override bool Equals(object obj) } catch (InvalidCastException) { - s_loggerPair.LogWarning("Invalid casting to SFSessionProperties"); + s_logger.Warn("Invalid casting to SFSessionProperties"); return false; } } @@ -183,7 +183,7 @@ public override int GetHashCode() internal static SFSessionProperties ParseConnectionString(string connectionString, SecureString password) { - s_loggerPair.LogInformation("Start parsing connection string."); + s_logger.Info("Start parsing connection string."); var builder = new DbConnectionStringBuilder(); try { @@ -191,7 +191,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin } catch (ArgumentException e) { - s_loggerPair.LogWarning("Invalid connectionString", e); + s_logger.Warn("Invalid connectionString", e); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_STRING, e.Message); @@ -215,7 +215,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin } catch (ArgumentException) { - s_loggerPair.LogDebug($"Property {keys[i]} not found ignored."); + s_logger.Debug($"Property {keys[i]} not found ignored."); } } @@ -231,7 +231,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin catch (Exception e) { // The useProxy setting is not a valid boolean value - s_loggerPair.LogError("Unable to connect", e); + s_logger.Error("Unable to connect", e); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_STRING, e.Message); @@ -273,15 +273,15 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin if (!allowUnderscoresInHost && compliantAccountName.Contains('_')) { compliantAccountName = compliantAccountName.Replace('_', '-'); - s_loggerPair.LogInformation($"Replacing _ with - in the account name. Old: {properties[SFSessionProperty.ACCOUNT]}, new: {compliantAccountName}."); + s_logger.Info($"Replacing _ with - in the account name. Old: {properties[SFSessionProperty.ACCOUNT]}, new: {compliantAccountName}."); } var hostName = $"{compliantAccountName}.snowflakecomputing.com"; // Remove in case it's here but empty properties.Remove(SFSessionProperty.HOST); properties.Add(SFSessionProperty.HOST, hostName); - s_loggerPair.LogInformation($"Compose host name: {hostName}"); + s_logger.Info($"Compose host name: {hostName}"); } - s_loggerPair.LogInformation(ResolveConnectionAreaMessage(properties[SFSessionProperty.HOST])); + s_logger.Info(ResolveConnectionAreaMessage(properties[SFSessionProperty.HOST])); // Trim the account name to remove the region and cloud platform if any were provided // because the login request data does not expect region and cloud information to be @@ -312,7 +312,7 @@ private static void ValidateAuthenticator(SFSessionProperties properties) if (!knownAuthenticators.Contains(authenticator) && !(authenticator.Contains(OktaAuthenticator.AUTH_NAME) && authenticator.StartsWith("https://"))) { var error = $"Unknown authenticator: {authenticator}"; - s_loggerPair.LogError(error); + s_logger.Error(error); throw new SnowflakeDbException(SFError.UNKNOWN_AUTHENTICATOR, authenticator); } } @@ -405,7 +405,7 @@ private static void ValidateAccountDomain(SFSessionProperties properties) return; if (IsAccountRegexMatched(account)) return; - s_loggerPair.LogError($"Invalid account {account}"); + s_logger.Error($"Invalid account {account}"); throw new SnowflakeDbException( new Exception("Invalid account"), SFError.INVALID_CONNECTION_PARAMETER_VALUE, @@ -427,14 +427,14 @@ private static void CheckSessionProperties(SFSessionProperties properties) !properties.ContainsKey(sessionProperty)) { SnowflakeDbException e = new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY, sessionProperty); - s_loggerPair.LogError("Missing connection property", e); + s_logger.Error("Missing connection property", e); throw e; } if (IsRequired(sessionProperty, properties) && string.IsNullOrEmpty(properties[sessionProperty])) { SnowflakeDbException e = new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY, sessionProperty); - s_loggerPair.LogError("Empty connection property", e); + s_logger.Error("Empty connection property", e); throw e; } @@ -442,7 +442,7 @@ private static void CheckSessionProperties(SFSessionProperties properties) string defaultVal = sessionProperty.GetAttribute().defaultValue; if (defaultVal != null && !properties.ContainsKey(sessionProperty)) { - s_loggerPair.LogDebug($"Session property {sessionProperty} set to default value: {defaultVal}"); + s_logger.Debug($"Session property {sessionProperty} set to default value: {defaultVal}"); properties.Add(sessionProperty, defaultVal); } } @@ -463,13 +463,13 @@ private static void ValidateFileTransferMaxBytesInMemoryProperty(SFSessionProper } catch (Exception e) { - s_loggerPair.LogError($"Value for parameter {propertyName} could not be parsed"); + s_logger.Error($"Value for parameter {propertyName} could not be parsed"); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_PARAMETER_VALUE, maxBytesInMemoryString, propertyName); } if (maxBytesInMemory <= 0) { - s_loggerPair.LogError($"Value for parameter {propertyName} should be greater than 0"); + s_logger.Error($"Value for parameter {propertyName} should be greater than 0"); throw new SnowflakeDbException( new Exception($"Value for parameter {propertyName} should be greater than 0"), SFError.INVALID_CONNECTION_PARAMETER_VALUE, maxBytesInMemoryString, propertyName); @@ -529,7 +529,7 @@ private static bool ParseAllowUnderscoresInHost(SFSessionProperties properties) } catch (Exception e) { - s_loggerPair.LogWarning("Unable to parse property 'allowUnderscoresInHost'", e); + s_logger.Warn("Unable to parse property 'allowUnderscoresInHost'", e); } return allowUnderscoresInHost; diff --git a/Snowflake.Data/Core/Session/SessionPool.cs b/Snowflake.Data/Core/Session/SessionPool.cs index 43d427668..de66c2240 100644 --- a/Snowflake.Data/Core/Session/SessionPool.cs +++ b/Snowflake.Data/Core/Session/SessionPool.cs @@ -16,7 +16,7 @@ namespace Snowflake.Data.Core.Session { sealed class SessionPool : IDisposable { - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private readonly object _sessionPoolLock = new object(); private static ISessionFactory s_sessionFactory = new SessionFactory(); @@ -63,9 +63,9 @@ private SessionPool(string connectionString, SecureString password, ConnectionPo internal static SessionPool CreateSessionPool(string connectionString, SecureString password) { - s_loggerPair.LogDebug("Creating a connection pool"); + s_logger.Debug("Creating a connection pool"); var extracted = ExtractConfig(connectionString, password); - s_loggerPair.LogDebug("Creating a connection pool identified by: " + extracted.Item2); + s_logger.Debug("Creating a connection pool identified by: " + extracted.Item2); return new SessionPool(connectionString, password, extracted.Item1, extracted.Item2); } @@ -88,7 +88,7 @@ internal static ISessionFactory SessionFactory private void CleanExpiredSessions() { - s_loggerPair.LogDebug("SessionPool::CleanExpiredSessions" + PoolIdentification()); + s_logger.Debug("SessionPool::CleanExpiredSessions" + PoolIdentification()); lock (_sessionPoolLock) { var timeNow = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); @@ -115,7 +115,7 @@ internal static Tuple ExtractConfig(string connect } catch (Exception exception) { - s_loggerPair.LogError("Failed to extract pool configuration", exception); + s_logger.Error("Failed to extract pool configuration", exception); throw; } } @@ -125,7 +125,7 @@ internal void ValidateSecurePassword(SecureString password) if (!ExtractPassword(Password).Equals(ExtractPassword(password))) { var errorMessage = "Could not get a pool because of password mismatch"; - s_loggerPair.LogError(errorMessage + PoolIdentification()); + s_logger.Error(errorMessage + PoolIdentification()); throw new Exception(errorMessage); } } @@ -135,7 +135,7 @@ private string ExtractPassword(SecureString password) => internal SFSession GetSession(string connStr, SecureString password) { - s_loggerPair.LogDebug("SessionPool::GetSession" + PoolIdentification()); + s_logger.Debug("SessionPool::GetSession" + PoolIdentification()); if (!GetPooling()) return NewNonPoolingSession(connStr, password); var sessionOrCreateTokens = GetIdleSession(connStr); @@ -150,7 +150,7 @@ internal SFSession GetSession(string connStr, SecureString password) internal async Task GetSessionAsync(string connStr, SecureString password, CancellationToken cancellationToken) { - s_loggerPair.LogDebug("SessionPool::GetSessionAsync" + PoolIdentification()); + s_logger.Debug("SessionPool::GetSessionAsync" + PoolIdentification()); if (!GetPooling()) return await NewNonPoolingSessionAsync(connStr, password, cancellationToken).ConfigureAwait(false); var sessionOrCreateTokens = GetIdleSession(connStr); @@ -181,7 +181,7 @@ private void WarnAboutOverridenConfig() { if (IsConfigOverridden() && GetPooling() && IsMultiplePoolsVersion()) { - s_loggerPair.LogWarning("Providing a connection from a pool for which technical configuration has been overriden by the user"); + s_logger.Warn("Providing a connection from a pool for which technical configuration has been overriden by the user"); } } @@ -199,22 +199,22 @@ internal void SetSessionPoolEventHandler(ISessionPoolEventHandler sessionPoolEve private SessionOrCreationTokens GetIdleSession(string connStr) { - s_loggerPair.LogDebug("SessionPool::GetIdleSession" + PoolIdentification()); + s_logger.Debug("SessionPool::GetIdleSession" + PoolIdentification()); lock (_sessionPoolLock) { if (_waitingForIdleSessionQueue.IsAnyoneWaiting()) { - s_loggerPair.LogDebug("SessionPool::GetIdleSession - someone is already waiting for a session, request is going to be queued" + PoolIdentification()); + s_logger.Debug("SessionPool::GetIdleSession - someone is already waiting for a session, request is going to be queued" + PoolIdentification()); } else { var session = ExtractIdleSession(connStr); if (session != null) { - s_loggerPair.LogDebug("SessionPool::GetIdleSession - no thread was waiting for a session, an idle session was retrieved from the pool" + PoolIdentification()); + s_logger.Debug("SessionPool::GetIdleSession - no thread was waiting for a session, an idle session was retrieved from the pool" + PoolIdentification()); return new SessionOrCreationTokens(session); } - s_loggerPair.LogDebug("SessionPool::GetIdleSession - no thread was waiting for a session, but could not find any idle session available in the pool" + PoolIdentification()); + s_logger.Debug("SessionPool::GetIdleSession - no thread was waiting for a session, but could not find any idle session available in the pool" + PoolIdentification()); var sessionsCount = AllowedNumberOfNewSessionCreations(1); if (sessionsCount > 0) { @@ -244,7 +244,7 @@ private int AllowedNumberOfNewSessionCreations(int atLeastCount) if (!IsMultiplePoolsVersion()) { if (atLeastCount > 0) - s_loggerPair.LogDebug($"SessionPool - creating of new sessions is not limited"); + s_logger.Debug($"SessionPool - creating of new sessions is not limited"); return atLeastCount; // we are either in old pool or there is no pooling } var currentSize = GetCurrentPoolSize(); @@ -253,10 +253,10 @@ private int AllowedNumberOfNewSessionCreations(int atLeastCount) var maxSessionsToCreate = _poolConfig.MaxPoolSize - currentSize; var sessionsNeeded = Math.Max(_poolConfig.MinPoolSize - currentSize, atLeastCount); var sessionsToCreate = Math.Min(sessionsNeeded, maxSessionsToCreate); - s_loggerPair.LogDebug($"SessionPool - allowed to create {sessionsToCreate} sessions, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); + s_logger.Debug($"SessionPool - allowed to create {sessionsToCreate} sessions, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); return sessionsToCreate; } - s_loggerPair.LogDebug($"SessionPool - not allowed to create a session, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); + s_logger.Debug($"SessionPool - not allowed to create a session, current pool size is {currentSize} out of {_poolConfig.MaxPoolSize}" + PoolIdentification()); return 0; } @@ -266,7 +266,7 @@ private SFSession WaitForSession(string connStr) { if (TimeoutHelper.IsInfinite(_poolConfig.WaitingForIdleSessionTimeout)) throw new Exception("WaitingForIdleSessionTimeout cannot be infinite"); - s_loggerPair.LogInformation($"SessionPool::WaitForSession for {(long) _poolConfig.WaitingForIdleSessionTimeout.TotalMilliseconds} ms timeout" + PoolIdentification()); + s_logger.Info($"SessionPool::WaitForSession for {(long) _poolConfig.WaitingForIdleSessionTimeout.TotalMilliseconds} ms timeout" + PoolIdentification()); _sessionPoolEventHandler.OnWaitingForSessionStarted(this); var beforeWaitingTimeMillis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); long nowTimeMillis = beforeWaitingTimeMillis; @@ -277,25 +277,25 @@ private SFSession WaitForSession(string connStr) var successful = _waitingForIdleSessionQueue.Wait((int) timeoutLeftMillis, CancellationToken.None); if (successful) { - s_loggerPair.LogDebug($"SessionPool::WaitForSession - woken with a session granted" + PoolIdentification()); + s_logger.Debug($"SessionPool::WaitForSession - woken with a session granted" + PoolIdentification()); _sessionPoolEventHandler.OnWaitingForSessionSuccessful(this); lock (_sessionPoolLock) { var session = ExtractIdleSession(connStr); if (session != null) { - s_loggerPair.LogDebug("SessionPool::WaitForSession - provided an idle session" + PoolIdentification()); + s_logger.Debug("SessionPool::WaitForSession - provided an idle session" + PoolIdentification()); return session; } } } else { - s_loggerPair.LogDebug("SessionPool::WaitForSession - woken without a session granted" + PoolIdentification()); + s_logger.Debug("SessionPool::WaitForSession - woken without a session granted" + PoolIdentification()); } nowTimeMillis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } - s_loggerPair.LogInformation("SessionPool::WaitForSession - could not find any idle session available withing a given timeout" + PoolIdentification()); + s_logger.Info("SessionPool::WaitForSession - could not find any idle session available withing a given timeout" + PoolIdentification()); throw WaitingFailedException(); } @@ -317,7 +317,7 @@ private SFSession ExtractIdleSession(string connStr) } else { - s_loggerPair.LogDebug($"reuse pooled session with sid {session.sessionId}" + PoolIdentification()); + s_logger.Debug($"reuse pooled session with sid {session.sessionId}" + PoolIdentification()); _busySessionsCounter.Increase(); return session; } @@ -331,19 +331,19 @@ private SFSession NewNonPoolingSession(String connectionString, SecureString pas private SFSession NewSession(String connectionString, SecureString password, SessionCreationToken sessionCreationToken) { - s_loggerPair.LogDebug("SessionPool::NewSession" + PoolIdentification()); + s_logger.Debug("SessionPool::NewSession" + PoolIdentification()); try { var session = s_sessionFactory.NewSession(connectionString, password); session.Open(); - s_loggerPair.LogDebug("SessionPool::NewSession - opened" + PoolIdentification()); + s_logger.Debug("SessionPool::NewSession - opened" + PoolIdentification()); if (GetPooling() && !_underDestruction) { lock (_sessionPoolLock) { _sessionCreationTokenCounter.RemoveToken(sessionCreationToken); _busySessionsCounter.Increase(); - s_loggerPair.LogDebug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); + s_logger.Debug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); } } _sessionPoolEventHandler.OnNewSessionCreated(this); @@ -358,7 +358,7 @@ private SFSession NewSession(String connectionString, SecureString password, Ses { lock (_sessionPoolLock) { - s_loggerPair.LogDebug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); + s_logger.Debug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); } } if (e is SnowflakeDbException) @@ -379,7 +379,7 @@ private Task NewNonPoolingSessionAsync( private Task NewSessionAsync(String connectionString, SecureString password, SessionCreationToken sessionCreationToken, CancellationToken cancellationToken) { - s_loggerPair.LogDebug("SessionPool::NewSessionAsync" + PoolIdentification()); + s_logger.Debug("SessionPool::NewSessionAsync" + PoolIdentification()); var session = s_sessionFactory.NewSession(connectionString, password); return session .OpenAsync(cancellationToken) @@ -392,7 +392,7 @@ private Task NewSessionAsync(String connectionString, SecureString pa { lock (_sessionPoolLock) { - s_loggerPair.LogDebug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); + s_logger.Debug($"Failed to create a new session {GetCurrentState()}" + PoolIdentification()); } } } @@ -414,7 +414,7 @@ private Task NewSessionAsync(String connectionString, SecureString pa { _sessionCreationTokenCounter.RemoveToken(sessionCreationToken); _busySessionsCounter.Increase(); - s_loggerPair.LogDebug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); + s_logger.Debug($"Pool state after creating a session {GetCurrentState()}" + PoolIdentification()); } } @@ -427,19 +427,19 @@ private Task NewSessionAsync(String connectionString, SecureString pa internal void ReleaseBusySession(SFSession session) { - s_loggerPair.LogDebug("SessionPool::ReleaseBusySession" + PoolIdentification()); + s_logger.Debug("SessionPool::ReleaseBusySession" + PoolIdentification()); SessionPoolState poolState; lock (_sessionPoolLock) { _busySessionsCounter.Decrease(); poolState = GetCurrentState(); } - s_loggerPair.LogDebug($"After releasing a busy session from the pool {poolState}" + PoolIdentification()); + s_logger.Debug($"After releasing a busy session from the pool {poolState}" + PoolIdentification()); } internal bool AddSession(SFSession session, bool ensureMinPoolSize) { - s_loggerPair.LogDebug("SessionPool::AddSession" + PoolIdentification()); + s_logger.Debug("SessionPool::AddSession" + PoolIdentification()); if (!GetPooling() || _underDestruction) return false; @@ -448,7 +448,7 @@ internal bool AddSession(SFSession session, bool ensureMinPoolSize) session.SessionPropertiesChanged && _poolConfig.ChangedSession == ChangedSessionBehavior.Destroy) { - s_loggerPair.LogDebug($"Session returning to pool was changed. Destroying the session: {session.sessionId}."); + s_logger.Debug($"Session returning to pool was changed. Destroying the session: {session.sessionId}."); session.SetPooling(false); } @@ -481,7 +481,7 @@ private Tuple> ReturnSessionToPool(SFSession se ? RegisterSessionCreationsWhenReturningSessionToPool() : SessionOrCreationTokens.s_emptySessionCreationTokenList; var poolState = GetCurrentState(); - s_loggerPair.LogDebug($"Could not return session to pool {poolState}" + PoolIdentification()); + s_logger.Debug($"Could not return session to pool {poolState}" + PoolIdentification()); return Tuple.Create(false, sessionCreationTokens); } } @@ -496,13 +496,13 @@ private Tuple> ReturnSessionToPool(SFSession se ? RegisterSessionCreationsWhenReturningSessionToPool() : SessionOrCreationTokens.s_emptySessionCreationTokenList; var poolState = GetCurrentState(); - s_loggerPair.LogDebug($"Could not return session to pool {poolState}" + PoolIdentification()); + s_logger.Debug($"Could not return session to pool {poolState}" + PoolIdentification()); return Tuple.Create(false, sessionCreationTokens); } var poolStateBeforeReturningToPool = GetCurrentState(); if (poolStateBeforeReturningToPool.Count() >= _poolConfig.MaxPoolSize) { - s_loggerPair.LogWarning($"Pool is full - unable to add session with sid {session.sessionId} {poolStateBeforeReturningToPool}"); + s_logger.Warn($"Pool is full - unable to add session with sid {session.sessionId} {poolStateBeforeReturningToPool}"); return Tuple.Create(false, SessionOrCreationTokens.s_emptySessionCreationTokenList); } _idleSessions.Add(session); @@ -511,14 +511,14 @@ private Tuple> ReturnSessionToPool(SFSession se ? RegisterSessionCreationsWhenReturningSessionToPool() : SessionOrCreationTokens.s_emptySessionCreationTokenList; var poolStateAfterReturningToPool = GetCurrentState(); - s_loggerPair.LogDebug($"returned session with sid {session.sessionId} to pool {poolStateAfterReturningToPool}" + PoolIdentification()); + s_logger.Debug($"returned session with sid {session.sessionId} to pool {poolStateAfterReturningToPool}" + PoolIdentification()); return Tuple.Create(true, sessionCreationTokensAfterReturningToPool); } } internal void DestroyPool() { - s_loggerPair.LogDebug("SessionPool::DestroyPool" + PoolIdentification()); + s_logger.Debug("SessionPool::DestroyPool" + PoolIdentification()); lock (_sessionPoolLock) { _underDestruction = true; @@ -531,7 +531,7 @@ internal void DestroyPool() internal void DestroyPoolAsync() { - s_loggerPair.LogDebug("SessionPool::DestroyPoolAsync" + PoolIdentification()); + s_logger.Debug("SessionPool::DestroyPoolAsync" + PoolIdentification()); lock (_sessionPoolLock) { _underDestruction = true; @@ -544,7 +544,7 @@ internal void DestroyPoolAsync() internal void ClearSessions() { - s_loggerPair.LogDebug($"SessionPool::ClearSessions" + PoolIdentification()); + s_logger.Debug($"SessionPool::ClearSessions" + PoolIdentification()); lock (_sessionPoolLock) { _busySessionsCounter.Reset(); @@ -555,7 +555,7 @@ internal void ClearSessions() internal void ClearIdleSessions() { - s_loggerPair.LogDebug("SessionPool::ClearIdleSessions" + PoolIdentification()); + s_logger.Debug("SessionPool::ClearIdleSessions" + PoolIdentification()); lock (_sessionPoolLock) { foreach (SFSession session in _idleSessions) @@ -568,7 +568,7 @@ internal void ClearIdleSessions() internal async void ClearIdleSessionsAsync() { - s_loggerPair.LogDebug("SessionPool::ClearIdleSessionsAsync" + PoolIdentification()); + s_logger.Debug("SessionPool::ClearIdleSessionsAsync" + PoolIdentification()); IEnumerable idleSessionsCopy; lock (_sessionPoolLock) { @@ -583,7 +583,7 @@ internal async void ClearIdleSessionsAsync() public void SetMaxPoolSize(int size) { - s_loggerPair.LogDebug($"SessionPool::SetMaxPoolSize({size})" + PoolIdentification()); + s_logger.Debug($"SessionPool::SetMaxPoolSize({size})" + PoolIdentification()); _poolConfig.MaxPoolSize = size; _configOverriden = true; } @@ -614,7 +614,7 @@ public long GetConnectionTimeout() public void SetTimeout(long seconds) { - s_loggerPair.LogDebug($"SessionPool::SetTimeout({seconds})" + PoolIdentification()); + s_logger.Debug($"SessionPool::SetTimeout({seconds})" + PoolIdentification()); var timeout = seconds < 0 ? TimeoutHelper.Infinity() : TimeSpan.FromSeconds(seconds); _poolConfig.ExpirationTimeout = timeout; _configOverriden = true; @@ -643,7 +643,7 @@ public SessionPoolState GetCurrentState() public bool SetPooling(bool isEnable) { - s_loggerPair.LogInformation($"SessionPool::SetPooling({isEnable})" + PoolIdentification()); + s_logger.Info($"SessionPool::SetPooling({isEnable})" + PoolIdentification()); if (_poolConfig.PoolingEnabled == isEnable) return false; _poolConfig.PoolingEnabled = isEnable; diff --git a/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs b/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs index 6d77a512a..f9092c7f9 100644 --- a/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs +++ b/Snowflake.Data/Core/Session/SessionPropertiesWithDefaultValuesExtractor.cs @@ -8,7 +8,7 @@ namespace Snowflake.Data.Core.Session { internal class SessionPropertiesWithDefaultValuesExtractor { - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private static readonly Regex s_timeoutFormatRegex = new Regex(@"^(-)?[0-9]{1,10}[mM]?[sS]?$"); private readonly SFSessionProperties _propertiesDictionary; @@ -71,7 +71,7 @@ public T ExtractPropertyWithDefaultValue( var valueString = _propertiesDictionary[property]; if (string.IsNullOrEmpty(valueString)) { - s_loggerPair.LogWarning($"Parameter {property} not defined. Using a default value: {defaultValue}"); + s_logger.Warn($"Parameter {property} not defined. Using a default value: {defaultValue}"); return defaultValue; } if (!preExtractValidation(valueString)) @@ -87,10 +87,10 @@ public T ExtractPropertyWithDefaultValue( { if (_failOnWrongValue) { - s_loggerPair.LogError($"Invalid value of parameter {property}. Error: {e}"); + s_logger.Error($"Invalid value of parameter {property}. Error: {e}"); throw new Exception($"Invalid value of parameter {property}", e); } - s_loggerPair.LogWarning($"Invalid value of parameter {property}. Using a default a default value: {defaultValue}"); + s_logger.Warn($"Invalid value of parameter {property}. Using a default a default value: {defaultValue}"); return defaultValue; } if (!postExtractValidation(value)) @@ -107,10 +107,10 @@ private TResult handleFailedValidation( { if (_failOnWrongValue) { - s_loggerPair.LogError($"Invalid value of parameter {property}: {value}"); + s_logger.Error($"Invalid value of parameter {property}: {value}"); throw new Exception($"Invalid value of parameter {property}"); } - s_loggerPair.LogWarning($"Invalid value of parameter {property}. Using a default value: {defaultValue}"); + s_logger.Warn($"Invalid value of parameter {property}. Using a default value: {defaultValue}"); return defaultValue; } diff --git a/Snowflake.Data/Core/TomlConnectionBuilder.cs b/Snowflake.Data/Core/TomlConnectionBuilder.cs index f8bdaead9..a8c2396b1 100644 --- a/Snowflake.Data/Core/TomlConnectionBuilder.cs +++ b/Snowflake.Data/Core/TomlConnectionBuilder.cs @@ -27,7 +27,7 @@ internal class TomlConnectionBuilder internal const string SnowflakeDefaultConnectionName = "SNOWFLAKE_DEFAULT_CONNECTION_NAME"; internal const string SnowflakeHome = "SNOWFLAKE_HOME"; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private readonly Dictionary _tomlToNetPropertiesMapper = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { @@ -53,7 +53,7 @@ public string GetConnectionStringFromToml(string connectionName = null) { var tomlPath = ResolveConnectionTomlFile(); var connectionToml = GetTomlTableFromConfig(tomlPath, connectionName); - s_loggerPair.LogInformation($"Reading connection parameters from file using key: {connectionName} and path: {tomlPath}"); + s_logger.Info($"Reading connection parameters from file using key: {connectionName} and path: {tomlPath}"); return connectionToml == null ? string.Empty : GetConnectionStringFromTomlTable(connectionToml); } @@ -86,7 +86,7 @@ private void AppendTokenFromFileIfNotGivenExplicitly(TomlTable connectionToml, b return; } - s_loggerPair.LogInformation($"Trying to load token from file {tokenFilePathValue}"); + s_logger.Info($"Trying to load token from file {tokenFilePathValue}"); var token = LoadTokenFromFile(tokenFilePathValue); if (!string.IsNullOrEmpty(token)) { @@ -94,7 +94,7 @@ private void AppendTokenFromFileIfNotGivenExplicitly(TomlTable connectionToml, b } else { - s_loggerPair.LogWarning("The token has empty value"); + s_logger.Warn("The token has empty value"); } } @@ -109,13 +109,13 @@ private string LoadTokenFromFile(string tokenFilePathValue) { if (!_fileOperations.Exists(tokenFilePathValue)) { - s_loggerPair.LogInformation($"Specified token file {tokenFilePathValue} does not exists."); + s_logger.Info($"Specified token file {tokenFilePathValue} does not exists."); throw new SnowflakeDbException(SFError.INVALID_CONNECTION_PARAMETER_VALUE, tokenFilePathValue, "token_file_path"); } tokenFile = tokenFilePathValue; } - s_loggerPair.LogInformation($"Read token from file path: {tokenFile}"); + s_logger.Info($"Read token from file path: {tokenFile}"); return _fileOperations.Exists(tokenFile) ? _fileOperations.ReadAllText(tokenFile, ValidateFilePermissions) : null; } diff --git a/Snowflake.Data/Core/Tools/Diagnostics.cs b/Snowflake.Data/Core/Tools/Diagnostics.cs index f6117d0bc..22d37daec 100644 --- a/Snowflake.Data/Core/Tools/Diagnostics.cs +++ b/Snowflake.Data/Core/Tools/Diagnostics.cs @@ -10,9 +10,9 @@ namespace Snowflake.Data.Core.Tools internal class Diagnostics { private const int PadRight = -25; - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); - public static void LogDiagnostics() => s_loggerPair.LogInformation(GetDiagnosticInfo()); + public static void LogDiagnostics() => s_logger.Info(GetDiagnosticInfo()); private static string GetDiagnosticInfo() { @@ -39,7 +39,7 @@ private static string GetDiagnosticInfo() catch (Exception exception) { var errorMessage = $"Error caught while collecting diagnostic info: {exception.Message}"; - s_loggerPair.LogError(errorMessage, exception); + s_logger.Error(errorMessage, exception); info.AppendLine(errorMessage); } return info.ToString(); diff --git a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs index f5c6a536e..1f1959986 100644 --- a/Snowflake.Data/Core/Tools/EnvironmentOperations.cs +++ b/Snowflake.Data/Core/Tools/EnvironmentOperations.cs @@ -11,7 +11,7 @@ namespace Snowflake.Data.Core.Tools internal class EnvironmentOperations { public static readonly EnvironmentOperations Instance = new EnvironmentOperations(); - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); public virtual string GetEnvironmentVariable(string variable) { @@ -29,7 +29,7 @@ public virtual string GetExecutionDirectory() var directoryName = string.IsNullOrEmpty(executablePath) ? null : Path.GetDirectoryName(executablePath); if (string.IsNullOrEmpty(directoryName)) { - s_loggerPair.LogWarning("Unable to determine execution directory"); + s_logger.Warn("Unable to determine execution directory"); return null; } return directoryName; diff --git a/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs b/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs index 3e9b28598..05e3c4253 100644 --- a/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs +++ b/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs @@ -9,7 +9,7 @@ namespace Snowflake.Data.Core.Tools { internal class HomeDirectoryProvider { - private static readonly SFLoggerPair s_loggerPair = SFLoggerPair.GetLoggerPair(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); public static string HomeDirectory(EnvironmentOperations _environmentOperations) { try @@ -23,7 +23,7 @@ public static string HomeDirectory(EnvironmentOperations _environmentOperations) } catch (Exception e) { - s_loggerPair.LogError($"Error while trying to retrieve the home directory: {e}"); + s_logger.Error($"Error while trying to retrieve the home directory: {e}"); return null; } } diff --git a/Snowflake.Data/Logger/SFLogger.cs b/Snowflake.Data/Logger/SFLogger.cs index e4d4596c3..167a171f7 100644 --- a/Snowflake.Data/Logger/SFLogger.cs +++ b/Snowflake.Data/Logger/SFLogger.cs @@ -7,13 +7,13 @@ namespace Snowflake.Data.Log { - interface SFLogger + public interface SFLogger { bool IsDebugEnabled(); - bool IsInformationEnabled(); + bool IsInfoEnabled(); - bool IsWarningEnabled(); + bool IsWarnEnabled(); bool IsErrorEnabled(); @@ -21,9 +21,9 @@ interface SFLogger void Debug(string msg, Exception ex = null); - void Information(string msg, Exception ex = null); + void Info(string msg, Exception ex = null); - void Warning(string msg, Exception ex = null); + void Warn(string msg, Exception ex = null); void Error(string msg, Exception ex = null); diff --git a/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs b/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs index ebfac2f8a..1e6eb2e68 100644 --- a/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs +++ b/Snowflake.Data/Logger/SFLoggerEmptyImpl.cs @@ -17,12 +17,12 @@ public bool IsDebugEnabled() return false; } - public bool IsInformationEnabled() + public bool IsInfoEnabled() { return false; } - public bool IsWarningEnabled() + public bool IsWarnEnabled() { return false; } @@ -42,12 +42,12 @@ public void Debug(string msg, Exception ex) return; } - public void Information(string msg, Exception ex) + public void Info(string msg, Exception ex) { return; } - public void Warning(string msg, Exception ex) + public void Warn(string msg, Exception ex) { return; } diff --git a/Snowflake.Data/Logger/SFLoggerFactory.cs b/Snowflake.Data/Logger/SFLoggerFactory.cs index b17b4e55e..8dfb277d7 100755 --- a/Snowflake.Data/Logger/SFLoggerFactory.cs +++ b/Snowflake.Data/Logger/SFLoggerFactory.cs @@ -45,6 +45,11 @@ public static void SetCustomLogger(ILogger customLogger) s_customLogger = customLogger; } + internal static SFLogger GetLogger() + { + return new SFLoggerPair(GetSFLogger(), GetCustomLogger()); + } + internal static SFLogger GetSFLogger(bool useFileAppender = true) { // If true, return the default/specified logger diff --git a/Snowflake.Data/Logger/SFLoggerImpl.cs b/Snowflake.Data/Logger/SFLoggerImpl.cs index 91f934fb5..0c09dfdc3 100644 --- a/Snowflake.Data/Logger/SFLoggerImpl.cs +++ b/Snowflake.Data/Logger/SFLoggerImpl.cs @@ -95,18 +95,18 @@ public bool IsDebugEnabled() SFLogRepository.s_rootLogger.IsDebugEnabled(); } - public bool IsInformationEnabled() + public bool IsInfoEnabled() { return SFLogRepository.s_rootLogger == this ? _isInfoEnabled : - SFLogRepository.s_rootLogger.IsInformationEnabled(); + SFLogRepository.s_rootLogger.IsInfoEnabled(); } - public bool IsWarningEnabled() + public bool IsWarnEnabled() { return SFLogRepository.s_rootLogger == this ? _isWarnEnabled : - SFLogRepository.s_rootLogger.IsWarningEnabled(); + SFLogRepository.s_rootLogger.IsWarnEnabled(); } public bool IsErrorEnabled() @@ -131,17 +131,17 @@ public void Debug(string msg, Exception ex = null) } } - public void Information(string msg, Exception ex = null) + public void Info(string msg, Exception ex = null) { - if (IsInformationEnabled()) + if (IsInfoEnabled()) { Log(LoggingEvent.INFO.ToString(), msg, ex); } } - public void Warning(string msg, Exception ex = null) + public void Warn(string msg, Exception ex = null) { - if (IsWarningEnabled()) + if (IsWarnEnabled()) { Log(LoggingEvent.WARN.ToString(), msg, ex); } diff --git a/Snowflake.Data/Logger/SFLoggerPair.cs b/Snowflake.Data/Logger/SFLoggerPair.cs index 8aafde022..3aed30a52 100644 --- a/Snowflake.Data/Logger/SFLoggerPair.cs +++ b/Snowflake.Data/Logger/SFLoggerPair.cs @@ -4,60 +4,107 @@ using Microsoft.Extensions.Logging; using System; +using System.Collections.Generic; using System.Text; namespace Snowflake.Data.Log { - public class SFLoggerPair + public class SFLoggerPair : SFLogger { private static SFLogger s_snowflakeLogger; private static ILogger s_customLogger; - SFLoggerPair(SFLogger snowflakeLogger, ILogger customLogger) + public SFLoggerPair(SFLogger snowflakeLogger, ILogger customLogger) { s_snowflakeLogger = snowflakeLogger; s_customLogger = customLogger; } - internal static SFLoggerPair GetLoggerPair() - { - return new SFLoggerPair(SFLoggerFactory.GetSFLogger(), SFLoggerFactory.GetCustomLogger()); - } - - internal void LogDebug(string message, Exception ex = null) + public void Debug(string message, Exception ex = null) { message = SecretDetector.MaskSecrets(message).maskedText; s_snowflakeLogger.Debug(message, ex); s_customLogger.LogDebug(FormatBrackets(message), ex); } - internal void LogInformation(string message, Exception ex = null) + public void Info(string message, Exception ex = null) { message = SecretDetector.MaskSecrets(message).maskedText; - s_snowflakeLogger.Information(message, ex); + s_snowflakeLogger.Info(message, ex); s_customLogger.LogInformation(message, ex); } - internal void LogWarning(string message, Exception ex = null) + public void Warn(string message, Exception ex = null) { message = SecretDetector.MaskSecrets(message).maskedText; - s_snowflakeLogger.Warning(message, ex); + s_snowflakeLogger.Warn(message, ex); s_customLogger.LogWarning(message, ex); } - internal void LogError(string message, Exception ex = null) + public void Error(string message, Exception ex = null) { message = SecretDetector.MaskSecrets(message).maskedText; s_snowflakeLogger.Error(message, ex); s_customLogger.LogError(message, ex); } - internal bool IsDebugEnabled() + public void Fatal(string message, Exception ex = null) + { + message = SecretDetector.MaskSecrets(message).maskedText; + s_snowflakeLogger.Fatal(message, ex); + s_customLogger.LogCritical(message, ex); + } + + public bool IsDebugEnabled() { return s_snowflakeLogger.IsDebugEnabled() || s_customLogger.IsEnabled(LogLevel.Debug); } + public bool IsInfoEnabled() + { + return s_snowflakeLogger.IsInfoEnabled() || + s_customLogger.IsEnabled(LogLevel.Information); + } + + public bool IsWarnEnabled() + { + return s_snowflakeLogger.IsWarnEnabled() || + s_customLogger.IsEnabled(LogLevel.Warning); + } + + public bool IsErrorEnabled() + { + return s_snowflakeLogger.IsErrorEnabled() || + s_customLogger.IsEnabled(LogLevel.Error); + } + + public bool IsFatalEnabled() + { + return s_snowflakeLogger.IsFatalEnabled() || + s_customLogger.IsEnabled(LogLevel.Critical); + } + + public List GetAppenders() + { + throw new NotImplementedException(); + } + + public void AddAppender(SFAppender appender) + { + throw new NotImplementedException(); + } + + public void RemoveAppender(SFAppender appender) + { + throw new NotImplementedException(); + } + + public void SetLevel(LoggingEvent level) + { + throw new NotImplementedException(); + } + private string FormatBrackets(string message) { var sb = new StringBuilder(message).Replace("{", "{{").Replace("}", "}}"); From 247df19d7236b0a4b273bc6407d43f3b297e89fe Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 15:52:00 -0800 Subject: [PATCH 22/35] Replace ILogger with SFLogger in tests --- .../ConnectionMultiplePoolsAsyncIT.cs | 3 +-- .../ConnectionPoolCommonIT.cs | 9 ++++---- .../IntegrationTests/SFBindTestIT.cs | 12 +++++----- .../IntegrationTests/SFConnectionIT.cs | 20 ++++++++--------- .../SFConnectionWithTomlIT.cs | 2 +- .../Mock/MockSnowflakeDbConnection.cs | 12 +++++----- Snowflake.Data.Tests/SFBaseTest.cs | 4 ++-- .../Util/ConnectingThreads.cs | 22 +++++++++---------- .../Util/DbConnectionExtensions.cs | 6 ++--- 9 files changed, 44 insertions(+), 46 deletions(-) diff --git a/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs b/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs index c0ce63eed..e263cb9d3 100644 --- a/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/ConnectionMultiplePoolsAsyncIT.cs @@ -1,7 +1,6 @@ using System.Data.Common; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; using Snowflake.Data.Client; @@ -18,7 +17,7 @@ namespace Snowflake.Data.Tests.IntegrationTests public class ConnectionMultiplePoolsAsyncIT: SFBaseTestAsync { private readonly PoolConfig _previousPoolConfig = new PoolConfig(); - private readonly ILogger logger = SFLoggerFactory.GetCustomLogger(); + private readonly SFLogger logger = SFLoggerFactory.GetLogger(); [SetUp] public new void BeforeTest() diff --git a/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs b/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs index 2bcbb389a..ca298226b 100644 --- a/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved. */ @@ -11,7 +11,6 @@ using Snowflake.Data.Core.Session; using Snowflake.Data.Log; using Snowflake.Data.Tests.Util; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.IntegrationTests { @@ -21,7 +20,7 @@ namespace Snowflake.Data.Tests.IntegrationTests class ConnectionPoolCommonIT : SFBaseTest { private readonly ConnectionPoolType _connectionPoolTypeUnderTest; - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private readonly PoolConfig _previousPoolConfig; public ConnectionPoolCommonIT(ConnectionPoolType connectionPoolTypeUnderTest) @@ -39,8 +38,8 @@ public ConnectionPoolCommonIT(ConnectionPoolType connectionPoolTypeUnderTest) { SnowflakeDbConnectionPool.SetPooling(true); } - s_logger.LogDebug($"---------------- BeforeTest ---------------------"); - s_logger.LogDebug($"Testing Pool Type: {SnowflakeDbConnectionPool.GetConnectionPoolVersion()}"); + s_logger.Debug($"---------------- BeforeTest ---------------------"); + s_logger.Debug($"Testing Pool Type: {SnowflakeDbConnectionPool.GetConnectionPoolVersion()}"); } [TearDown] diff --git a/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs index d51e65de5..387ab7b3b 100755 --- a/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2024 Snowflake Computing Inc. All rights reserved. */ #nullable enable @@ -24,7 +24,7 @@ namespace Snowflake.Data.Tests.IntegrationTests [TestFixture] class SFBindTestIT : SFBaseTest { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); [Test] public void TestArrayBind() @@ -906,7 +906,7 @@ public void TestDateTimeBinding(ResultFormat resultFormat, SFTableType tableType var bindingThreshold = 65280; // when exceeded enforces bindings via file on stage var smallBatchRowCount = 2; var bigBatchRowCount = bindingThreshold / 2; - s_logger.LogInformation(testCase); + s_logger.Info(testCase); using (IDbConnection conn = new SnowflakeDbConnection(ConnectionString)) { @@ -945,7 +945,7 @@ public void TestDateTimeBinding(ResultFormat resultFormat, SFTableType tableType var row = 0; using (var select = conn.CreateCommand($"select {sql_columns} from {TableName} order by id")) { - s_logger.LogDebug(select.CommandText); + s_logger.Debug(select.CommandText); var reader = select.ExecuteReader(); while (reader.Read()) { @@ -992,7 +992,7 @@ private void InsertSingleRecord(IDbConnection conn, string sqlInsert, DbType bin } // Act - s_logger.LogInformation(sqlInsert); + s_logger.Info(sqlInsert); var rowsAffected = insert.ExecuteNonQuery(); // Assert @@ -1031,7 +1031,7 @@ private void InsertMultipleRecords(IDbConnection conn, string sqlInsert, DbType } // Act - s_logger.LogDebug(sqlInsert); + s_logger.Debug(sqlInsert); var rowsAffected = insert.ExecuteNonQuery(); // Assert diff --git a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs index 073053d41..902dc5e56 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved. */ @@ -25,7 +25,7 @@ namespace Snowflake.Data.Tests.IntegrationTests [TestFixture] class SFConnectionIT : SFBaseTest { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); [Test] public void TestBasicConnection() @@ -83,14 +83,14 @@ public void TestApplicationName() try { conn.Open(); - s_logger.LogDebug("{appName}"); + s_logger.Debug("{appName}"); Assert.Fail(); } catch (SnowflakeDbException e) { // Expected - s_logger.LogDebug("Failed opening connection ", e); + s_logger.Debug("Failed opening connection ", e); AssertIsConnectionFailure(e); } @@ -127,7 +127,7 @@ public void TestIncorrectUserOrPasswordBasicConnection() catch (SnowflakeDbException e) { // Expected - s_logger.LogDebug("Failed opening connection ", e); + s_logger.Debug("Failed opening connection ", e); AssertIsConnectionFailure(e); } @@ -142,7 +142,7 @@ public void TestConnectionIsNotMarkedAsOpenWhenWasNotCorrectlyOpenedBefore(bool { for (int i = 0; i < 2; ++i) { - s_logger.LogDebug($"Running try #{i}"); + s_logger.Debug($"Running try #{i}"); SnowflakeDbConnection snowflakeConnection = null; try { @@ -168,7 +168,7 @@ public void TestConnectionIsNotMarkedAsOpenWhenWasNotCorrectlyOpenedWithUsingCla { for (int i = 0; i < 2; ++i) { - s_logger.LogDebug($"Running try #{i}"); + s_logger.Debug($"Running try #{i}"); SnowflakeDbConnection snowflakeConnection = null; try { @@ -1559,7 +1559,7 @@ public void TestInvalidProxySettingFromConnectionString() catch (SnowflakeDbException e) { // Expected - s_logger.LogDebug("Failed opening connection ", e); + s_logger.Debug("Failed opening connection ", e); Assert.AreEqual(270001, e.ErrorCode); //Internal error AssertIsConnectionFailure(e); } @@ -1868,7 +1868,7 @@ public void TestKeepAlive() [TestFixture] class SFConnectionITAsync : SFBaseTestAsync { - private static ILogger logger = SFLoggerFactory.GetCustomLogger(); + private static SFLogger logger = SFLoggerFactory.GetLogger(); [Test] @@ -1898,7 +1898,7 @@ public void TestCancelLoginBeforeTimeout() // Cancel the connection because it will never succeed since there is no // connection_timeout defined - logger.LogDebug("connectionCancelToken.Cancel "); + logger.Debug("connectionCancelToken.Cancel "); connectionCancelToken.Cancel(); try diff --git a/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs index b9bab0e80..5be16fca4 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs @@ -21,7 +21,7 @@ namespace Snowflake.Data.Tests.IntegrationTests [TestFixture, NonParallelizable] class SFConnectionWithTomlIT : SFBaseTest { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private static string s_workingDirectory; diff --git a/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs b/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs index 68cb8fad3..841bafb4e 100644 --- a/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs +++ b/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 Snowflake Computing Inc. All rights reserved. */ @@ -15,7 +15,7 @@ namespace Snowflake.Data.Tests.Mock { class MockSnowflakeDbConnection : SnowflakeDbConnection { - private ILogger logger = SFLoggerFactory.GetCustomLogger(); + private SFLogger logger = SFLoggerFactory.GetLogger(); private IMockRestRequester _restRequester; @@ -32,7 +32,7 @@ public MockSnowflakeDbConnection() public override void Open() { - logger.LogDebug("Open Connection."); + logger.Debug("Open Connection."); SetMockSession(); try { @@ -42,7 +42,7 @@ public override void Open() { // Otherwise when Dispose() is called, the close request would timeout. _connectionState = System.Data.ConnectionState.Closed; - logger.LogError("Unable to connect", e); + logger.Error("Unable to connect", e); throw; } OnSessionEstablished(); @@ -62,14 +62,14 @@ public override Task OpenAsync(CancellationToken cancellationToken) // Exception from SfSession.OpenAsync Exception sfSessionEx = previousTask.Exception; _connectionState = ConnectionState.Closed; - logger.LogError("Unable to connect", sfSessionEx); + logger.Error("Unable to connect", sfSessionEx); throw //sfSessionEx.InnerException; new SnowflakeDbException(sfSessionEx, SFError.INTERNAL_ERROR, "Unable to connect"); } if (previousTask.IsCanceled) { _connectionState = ConnectionState.Closed; - logger.LogDebug("Connection canceled"); + logger.Debug("Connection canceled"); } else { diff --git a/Snowflake.Data.Tests/SFBaseTest.cs b/Snowflake.Data.Tests/SFBaseTest.cs index a49e4c73c..11b7b7606 100755 --- a/Snowflake.Data.Tests/SFBaseTest.cs +++ b/Snowflake.Data.Tests/SFBaseTest.cs @@ -58,7 +58,7 @@ public static void TearDownContext() #endif public class SFBaseTestAsync { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); private const string ConnectionStringWithoutAuthFmt = "scheme={0};host={1};port={2};" + "account={3};role={4};db={5};schema={6};warehouse={7}"; @@ -119,7 +119,7 @@ protected void CreateOrReplaceTable(IDbConnection conn, string tableName, string var columnsStr = string.Join(", ", columns); var cmd = conn.CreateCommand(); cmd.CommandText = $"CREATE OR REPLACE {tableType} TABLE {tableName}({columnsStr}) {additionalQueryStr}"; - s_logger.LogDebug(cmd.CommandText); + s_logger.Debug(cmd.CommandText); cmd.ExecuteNonQuery(); _tablesToRemove.Add(tableName); diff --git a/Snowflake.Data.Tests/Util/ConnectingThreads.cs b/Snowflake.Data.Tests/Util/ConnectingThreads.cs index 305e6b0f6..e80b4f6f3 100644 --- a/Snowflake.Data.Tests/Util/ConnectingThreads.cs +++ b/Snowflake.Data.Tests/Util/ConnectingThreads.cs @@ -56,12 +56,12 @@ public ConnectingThreads JoinAll() public void Enqueue(ThreadEvent threadEvent) => _events.Enqueue(threadEvent); - public static ILogger Logger() => SFLoggerFactory.GetCustomLogger(); // we have to choose a class from Snowflake.Data package otherwise it will be visible in GH build output + public static SFLogger Logger() => SFLoggerFactory.GetLogger(); // we have to choose a class from Snowflake.Data package otherwise it will be visible in GH build output } class ConnectingThread { - private static readonly ILogger s_logger = ConnectingThreads.Logger(); + private static readonly SFLogger s_logger = ConnectingThreads.Logger(); private string _name; @@ -104,21 +104,21 @@ private void Execute() { var connection = new SnowflakeDbConnection(); connection.ConnectionString = _connectionString; - s_logger.LogDebug($"Execution started, will sleep for {_waitBeforeConnectMillis} ms"); + s_logger.Debug($"Execution started, will sleep for {_waitBeforeConnectMillis} ms"); Sleep(_waitBeforeConnectMillis); var watch = new StopWatch(); watch.Start(); var connected = false; try { - s_logger.LogDebug("Opening the connection"); + s_logger.Debug("Opening the connection"); connection.Open(); connected = true; } catch (Exception exception) { watch.Stop(); - s_logger.LogError($"Execution failed because of the error: {exception}"); + s_logger.Error($"Execution failed because of the error: {exception}"); _events.Enqueue(ThreadEvent.EventConnectingFailed(_name, exception, watch.ElapsedMilliseconds)); } if (connected) @@ -129,7 +129,7 @@ private void Execute() Sleep(_waitAfterConnectMillis); if (_closeOnExit) { - s_logger.LogDebug($"Closing the connection"); + s_logger.Debug($"Closing the connection"); connection.Close(); } } @@ -185,7 +185,7 @@ public static ThreadEvent EventWaitingForSessionStarted(string threadName) => class SessionPoolThreadEventHandler: SessionPoolEventHandler { - private static readonly ILogger s_logger = ConnectingThreads.Logger(); + private static readonly SFLogger s_logger = ConnectingThreads.Logger(); private readonly ConnectingThreads _connectingThreads; public SessionPoolThreadEventHandler(ConnectingThreads connectingThreads) @@ -198,24 +198,24 @@ public override void OnWaitingForSessionStarted(SessionPool sessionPool) var threadName = Thread.CurrentThread.Name; var realThreadName = threadName.StartsWith(ConnectingThread.NamePrefix) ? threadName.Substring(ConnectingThread.NamePrefix.Length) : threadName; - s_logger.LogWarning($"Thread is going to wait for an available session. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); + s_logger.Warn($"Thread is going to wait for an available session. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); var waitingStartedEvent = ThreadEvent.EventWaitingForSessionStarted(realThreadName); _connectingThreads.Enqueue(waitingStartedEvent); } public override void OnWaitingForSessionStarted(SessionPool sessionPool, long millisLeft) { - s_logger.LogWarning($"Thread is going to wait with milliseconds timeout of {millisLeft}. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); + s_logger.Warn($"Thread is going to wait with milliseconds timeout of {millisLeft}. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); } public override void OnWaitingForSessionSuccessful(SessionPool sessionPool) { - s_logger.LogWarning($"Thread has been woken with a session granted. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); + s_logger.Warn($"Thread has been woken with a session granted. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); } public override void OnSessionProvided(SessionPool sessionPool) { - s_logger.LogWarning($"Thread has got a session. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); + s_logger.Warn($"Thread has got a session. Current time in milliseconds: {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"); } } } diff --git a/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs b/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs index 055de6441..744ce343a 100644 --- a/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs +++ b/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs @@ -9,21 +9,21 @@ namespace Snowflake.Data.Tests.Util { public static class DbConnectionExtensions { - private static readonly ILogger s_logger = SFLoggerFactory.GetCustomLogger(); + private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); internal static IDbCommand CreateCommand(this IDbConnection connection, string commandText) { var command = connection.CreateCommand(); command.Connection = connection; command.CommandText = commandText; - s_logger.LogDebug(commandText); + s_logger.Debug(commandText); return command; } internal static int ExecuteNonQuery(this IDbConnection connection, string commandText) { var rowsAffected = connection.CreateCommand(commandText).ExecuteNonQuery(); - s_logger.LogDebug($"Affected row(s): {rowsAffected}"); + s_logger.Debug($"Affected row(s): {rowsAffected}"); return rowsAffected; } From 44ab2548fb4ba00f5c83e4e9e0724eb96fba49b1 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 15:54:04 -0800 Subject: [PATCH 23/35] Remove unused package --- Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs | 1 - Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs | 1 - .../IntegrationTests/SFConnectionWithTomlIT.cs | 3 +-- Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs | 1 - Snowflake.Data.Tests/SFBaseTest.cs | 1 - 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs index 387ab7b3b..0a1273dd1 100755 --- a/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs @@ -16,7 +16,6 @@ using System.Globalization; using System.Collections.Generic; using Snowflake.Data.Tests.Util; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.IntegrationTests { diff --git a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs index 902dc5e56..61e15c644 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs @@ -17,7 +17,6 @@ using Snowflake.Data.Log; using Snowflake.Data.Tests.Mock; using Snowflake.Data.Tests.Util; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.IntegrationTests { diff --git a/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs index 5be16fca4..ca03d44c4 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. */ @@ -6,7 +6,6 @@ using System.Data; using System.IO; using System.Runtime.InteropServices; -using Microsoft.Extensions.Logging; using Mono.Unix.Native; using NUnit.Framework; using Snowflake.Data.Client; diff --git a/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs b/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs index 841bafb4e..a5c0cd57e 100644 --- a/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs +++ b/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs @@ -9,7 +9,6 @@ using System.Data; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.Mock { diff --git a/Snowflake.Data.Tests/SFBaseTest.cs b/Snowflake.Data.Tests/SFBaseTest.cs index 11b7b7606..1acae942b 100755 --- a/Snowflake.Data.Tests/SFBaseTest.cs +++ b/Snowflake.Data.Tests/SFBaseTest.cs @@ -14,7 +14,6 @@ using Snowflake.Data.Client; using Snowflake.Data.Log; using Snowflake.Data.Tests.Util; -using Microsoft.Extensions.Logging; [assembly:LevelOfParallelism(10)] From e1a97f5019826434fcafbe8af6e473f288246c64 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 16:13:32 -0800 Subject: [PATCH 24/35] =?UTF-8?q?Revert=20=EF=BB=BFBOM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Snowflake.Data.Tests/SFBaseTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Snowflake.Data.Tests/SFBaseTest.cs b/Snowflake.Data.Tests/SFBaseTest.cs index 1acae942b..2784f0e25 100755 --- a/Snowflake.Data.Tests/SFBaseTest.cs +++ b/Snowflake.Data.Tests/SFBaseTest.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved. */ From 7d4c4aef31b7a4ede952a64221b84675c0ae1487 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 16:19:43 -0800 Subject: [PATCH 25/35] Remove unused package and revert BOM --- Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs | 2 +- Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs | 2 +- Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs | 2 +- Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs | 2 +- Snowflake.Data.Tests/Util/ConnectingThreads.cs | 1 - Snowflake.Data.Tests/Util/DbConnectionExtensions.cs | 1 - Snowflake.Data/Client/SnowflakeDbCommand.cs | 2 +- 7 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs b/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs index ca298226b..9bf78ffbe 100644 --- a/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/ConnectionPoolCommonIT.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved. */ diff --git a/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs index 0a1273dd1..05995e0d4 100755 --- a/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFBindTestIT.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2024 Snowflake Computing Inc. All rights reserved. */ #nullable enable diff --git a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs index 61e15c644..e3303bdee 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved. */ diff --git a/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs index ca03d44c4..29d99744c 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFConnectionWithTomlIT.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. */ diff --git a/Snowflake.Data.Tests/Util/ConnectingThreads.cs b/Snowflake.Data.Tests/Util/ConnectingThreads.cs index e80b4f6f3..beba4720c 100644 --- a/Snowflake.Data.Tests/Util/ConnectingThreads.cs +++ b/Snowflake.Data.Tests/Util/ConnectingThreads.cs @@ -7,7 +7,6 @@ using Snowflake.Data.Core.Session; using Snowflake.Data.Log; using Snowflake.Data.Tests.Util; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.IntegrationTests { diff --git a/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs b/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs index 744ce343a..e8efc371d 100644 --- a/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs +++ b/Snowflake.Data.Tests/Util/DbConnectionExtensions.cs @@ -3,7 +3,6 @@ using Snowflake.Data.Client; using Snowflake.Data.Log; using Snowflake.Data.Tests.IcebergTests; -using Microsoft.Extensions.Logging; namespace Snowflake.Data.Tests.Util { diff --git a/Snowflake.Data/Client/SnowflakeDbCommand.cs b/Snowflake.Data/Client/SnowflakeDbCommand.cs index b470f1601..96771da40 100755 --- a/Snowflake.Data/Client/SnowflakeDbCommand.cs +++ b/Snowflake.Data/Client/SnowflakeDbCommand.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ From 9038aaa35ae3043abd75bf6433053a33b4c20477 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 16:39:23 -0800 Subject: [PATCH 26/35] Revert logger name --- Snowflake.Data/Client/SnowflakeDbCommand.cs | 32 ++++++------- .../Client/SnowflakeDbConnection.cs | 48 +++++++++---------- .../Client/SnowflakeDbConnectionPool.cs | 2 +- .../Client/SnowflakeDbDataReader.cs | 4 +- .../Client/SnowflakeDbTransaction.cs | 14 +++--- .../Core/Authenticator/BasicAuthenticator.cs | 4 +- .../ExternalBrowserAuthenticator.cs | 34 ++++++------- .../Core/Authenticator/IAuthenticator.cs | 4 +- .../Authenticator/KeyPairAuthenticator.cs | 10 ++-- .../Core/Authenticator/OAuthAuthenticator.cs | 2 +- 10 files changed, 77 insertions(+), 77 deletions(-) diff --git a/Snowflake.Data/Client/SnowflakeDbCommand.cs b/Snowflake.Data/Client/SnowflakeDbCommand.cs index 96771da40..68d3dccb0 100755 --- a/Snowflake.Data/Client/SnowflakeDbCommand.cs +++ b/Snowflake.Data/Client/SnowflakeDbCommand.cs @@ -22,13 +22,13 @@ public class SnowflakeDbCommand : DbCommand private SnowflakeDbParameterCollection parameterCollection; - private SFLogger _logger = SFLoggerFactory.GetLogger(); + private SFLogger logger = SFLoggerFactory.GetLogger(); private readonly QueryResultsAwaiter _queryResultsAwaiter = QueryResultsAwaiter.Instance; public SnowflakeDbCommand() { - _logger.Debug("Constructing SnowflakeDbCommand class"); + logger.Debug("Constructing SnowflakeDbCommand class"); // by default, no query timeout this.CommandTimeout = 0; parameterCollection = new SnowflakeDbParameterCollection(); @@ -165,7 +165,7 @@ public override void Cancel() public override int ExecuteNonQuery() { - _logger.Debug($"ExecuteNonQuery"); + logger.Debug($"ExecuteNonQuery"); SFBaseResultSet resultSet = ExecuteInternal(); long total = 0; do @@ -190,7 +190,7 @@ public override int ExecuteNonQuery() public override async Task ExecuteNonQueryAsync(CancellationToken cancellationToken) { - _logger.Debug($"ExecuteNonQueryAsync"); + logger.Debug($"ExecuteNonQueryAsync"); cancellationToken.ThrowIfCancellationRequested(); var resultSet = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -217,7 +217,7 @@ public override async Task ExecuteNonQueryAsync(CancellationToken cancellat public override object ExecuteScalar() { - _logger.Debug($"ExecuteScalar"); + logger.Debug($"ExecuteScalar"); SFBaseResultSet resultSet = ExecuteInternal(); if(resultSet.Next()) @@ -228,7 +228,7 @@ public override object ExecuteScalar() public override async Task ExecuteScalarAsync(CancellationToken cancellationToken) { - _logger.Debug($"ExecuteScalarAsync"); + logger.Debug($"ExecuteScalarAsync"); cancellationToken.ThrowIfCancellationRequested(); var result = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -263,14 +263,14 @@ protected override DbParameter CreateDbParameter() protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) { - _logger.Debug($"ExecuteDbDataReader"); + logger.Debug($"ExecuteDbDataReader"); SFBaseResultSet resultSet = ExecuteInternal(); return new SnowflakeDbDataReader(this, resultSet); } protected override async Task ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) { - _logger.Debug($"ExecuteDbDataReaderAsync"); + logger.Debug($"ExecuteDbDataReaderAsync"); try { var result = await ExecuteInternalAsync(cancellationToken).ConfigureAwait(false); @@ -278,7 +278,7 @@ protected override async Task ExecuteDbDataReaderAsync(CommandBeha } catch (Exception ex) { - _logger.Error("The command failed to execute.", ex); + logger.Error("The command failed to execute.", ex); throw; } } @@ -290,7 +290,7 @@ protected override async Task ExecuteDbDataReaderAsync(CommandBeha /// The query id. public string ExecuteInAsyncMode() { - _logger.Debug($"ExecuteInAsyncMode"); + logger.Debug($"ExecuteInAsyncMode"); SFBaseResultSet resultSet = ExecuteInternal(asyncExec: true); return resultSet.queryId; } @@ -303,7 +303,7 @@ public string ExecuteInAsyncMode() /// The query id. public async Task ExecuteAsyncInAsyncMode(CancellationToken cancellationToken) { - _logger.Debug($"ExecuteAsyncInAsyncMode"); + logger.Debug($"ExecuteAsyncInAsyncMode"); var resultSet = await ExecuteInternalAsync(cancellationToken, asyncExec: true).ConfigureAwait(false); return resultSet.queryId; } @@ -315,7 +315,7 @@ public async Task ExecuteAsyncInAsyncMode(CancellationToken cancellation /// The query status. public QueryStatus GetQueryStatus(string queryId) { - _logger.Debug($"GetQueryStatus"); + logger.Debug($"GetQueryStatus"); return _queryResultsAwaiter.GetQueryStatus(connection, queryId); } @@ -327,7 +327,7 @@ public QueryStatus GetQueryStatus(string queryId) /// The query status. public async Task GetQueryStatusAsync(string queryId, CancellationToken cancellationToken) { - _logger.Debug($"GetQueryStatusAsync"); + logger.Debug($"GetQueryStatusAsync"); return await _queryResultsAwaiter.GetQueryStatusAsync(connection, queryId, cancellationToken); } @@ -338,7 +338,7 @@ public async Task GetQueryStatusAsync(string queryId, CancellationT /// The query results. public DbDataReader GetResultsFromQueryId(string queryId) { - _logger.Debug($"GetResultsFromQueryId"); + logger.Debug($"GetResultsFromQueryId"); Task task = _queryResultsAwaiter.RetryUntilQueryResultIsAvailable(connection, queryId, CancellationToken.None, false); task.Wait(); @@ -356,7 +356,7 @@ public DbDataReader GetResultsFromQueryId(string queryId) /// The query results. public async Task GetResultsFromQueryIdAsync(string queryId, CancellationToken cancellationToken) { - _logger.Debug($"GetResultsFromQueryIdAsync"); + logger.Debug($"GetResultsFromQueryIdAsync"); await _queryResultsAwaiter.RetryUntilQueryResultIsAvailable(connection, queryId, cancellationToken, true); @@ -464,7 +464,7 @@ private void CheckIfCommandTextIsSet() if (string.IsNullOrEmpty(CommandText)) { var errorMessage = "Unable to execute command due to command text not being set"; - _logger.Error(errorMessage); + logger.Error(errorMessage); throw new Exception(errorMessage); } } diff --git a/Snowflake.Data/Client/SnowflakeDbConnection.cs b/Snowflake.Data/Client/SnowflakeDbConnection.cs index baf71a6b7..70fa642ea 100755 --- a/Snowflake.Data/Client/SnowflakeDbConnection.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnection.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved. */ @@ -16,7 +16,7 @@ namespace Snowflake.Data.Client [System.ComponentModel.DesignerCategory("Code")] public class SnowflakeDbConnection : DbConnection { - private SFLogger _logger = SFLoggerFactory.GetLogger(); + private SFLogger logger = SFLoggerFactory.GetLogger(); internal SFSession SfSession { get; set; } @@ -120,7 +120,7 @@ public void PreventPooling() throw new Exception("Session not yet created for this connection. Unable to prevent the session from pooling"); } SfSession.SetPooling(false); - _logger.Debug($"Session {SfSession.sessionId} marked not to be pooled any more"); + logger.Debug($"Session {SfSession.sessionId} marked not to be pooled any more"); } internal bool HasActiveExplicitTransaction() => ExplicitTransaction != null && ExplicitTransaction.IsActive; @@ -138,7 +138,7 @@ private bool TryToReturnSessionToPool() var sessionReturnedToPool = SnowflakeDbConnectionPool.AddSession(SfSession); if (sessionReturnedToPool) { - _logger.Debug($"Session pooled: {SfSession.sessionId}"); + logger.Debug($"Session pooled: {SfSession.sessionId}"); } return sessionReturnedToPool; } @@ -149,13 +149,13 @@ private TransactionRollbackStatus TerminateTransactionForDirtyConnectionReturnin return TransactionRollbackStatus.Success; try { - _logger.Debug("Closing dirty connection: an active transaction exists in session: " + SfSession.sessionId); + logger.Debug("Closing dirty connection: an active transaction exists in session: " + SfSession.sessionId); using (IDbCommand command = CreateCommand()) { command.CommandText = "ROLLBACK"; command.ExecuteNonQuery(); // error to indicate a problem within application code that a connection was closed while still having a pending transaction - _logger.Error("Closing dirty connection: rollback transaction in session " + SfSession.sessionId + " succeeded."); + logger.Error("Closing dirty connection: rollback transaction in session " + SfSession.sessionId + " succeeded."); ExplicitTransaction = null; return TransactionRollbackStatus.Success; } @@ -163,14 +163,14 @@ private TransactionRollbackStatus TerminateTransactionForDirtyConnectionReturnin catch (Exception exception) { // error to indicate a problem with rollback of an active transaction and inability to return dirty connection to the pool - _logger.Error("Closing dirty connection: rollback transaction in session: " + SfSession.sessionId + " failed, exception: " + exception.Message); + logger.Error("Closing dirty connection: rollback transaction in session: " + SfSession.sessionId + " failed, exception: " + exception.Message); return TransactionRollbackStatus.Failure; // connection won't be pooled } } public override void ChangeDatabase(string databaseName) { - _logger.Debug($"ChangeDatabase to:{databaseName}"); + logger.Debug($"ChangeDatabase to:{databaseName}"); string alterDbCommand = $"use database {databaseName}"; @@ -183,7 +183,7 @@ public override void ChangeDatabase(string databaseName) public override void Close() { - _logger.Debug("Close Connection."); + logger.Debug("Close Connection."); if (IsNonClosedWithSession()) { var returnedToPool = TryToReturnSessionToPool(); @@ -207,7 +207,7 @@ public override async Task CloseAsync() public virtual async Task CloseAsync(CancellationToken cancellationToken) { - _logger.Debug("Close Connection."); + logger.Debug("Close Connection."); TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); if (cancellationToken.IsCancellationRequested) @@ -232,18 +232,18 @@ await SfSession.CloseAsync(cancellationToken).ContinueWith( if (previousTask.IsFaulted) { // Exception from SfSession.CloseAsync - _logger.Error("Error closing the session", previousTask.Exception); + logger.Error("Error closing the session", previousTask.Exception); taskCompletionSource.SetException(previousTask.Exception); } else if (previousTask.IsCanceled) { _connectionState = ConnectionState.Closed; - _logger.Debug("Session close canceled"); + logger.Debug("Session close canceled"); taskCompletionSource.SetCanceled(); } else { - _logger.Debug("Session closed successfully"); + logger.Debug("Session closed successfully"); _connectionState = ConnectionState.Closed; taskCompletionSource.SetResult(null); } @@ -252,7 +252,7 @@ await SfSession.CloseAsync(cancellationToken).ContinueWith( } else { - _logger.Debug("Session not opened. Nothing to do."); + logger.Debug("Session not opened. Nothing to do."); taskCompletionSource.SetResult(null); } } @@ -267,10 +267,10 @@ protected virtual bool CanReuseSession(TransactionRollbackStatus transactionRoll public override void Open() { - _logger.Debug("Open Connection."); + logger.Debug("Open Connection."); if (_connectionState != ConnectionState.Closed) { - _logger.Debug($"Open with a connection already opened: {_connectionState}"); + logger.Debug($"Open with a connection already opened: {_connectionState}"); return; } try @@ -280,14 +280,14 @@ public override void Open() SfSession = SnowflakeDbConnectionPool.GetSession(ConnectionString, Password); if (SfSession == null) throw new SnowflakeDbException(SFError.INTERNAL_ERROR, "Could not open session"); - _logger.Debug($"Connection open with pooled session: {SfSession.sessionId}"); + logger.Debug($"Connection open with pooled session: {SfSession.sessionId}"); OnSessionEstablished(); } catch (Exception e) { // Otherwise when Dispose() is called, the close request would timeout. _connectionState = ConnectionState.Closed; - _logger.Error("Unable to connect: ", e); + logger.Error("Unable to connect: ", e); if (e is SnowflakeDbException) { throw; @@ -310,10 +310,10 @@ internal void FillConnectionStringFromTomlConfigIfNotSet() public override Task OpenAsync(CancellationToken cancellationToken) { - _logger.Debug("Open Connection Async."); + logger.Debug("Open Connection Async."); if (_connectionState != ConnectionState.Closed) { - _logger.Debug($"Open with a connection already opened: {_connectionState}"); + logger.Debug($"Open with a connection already opened: {_connectionState}"); return Task.CompletedTask; } registerConnectionCancellationCallback(cancellationToken); @@ -328,7 +328,7 @@ public override Task OpenAsync(CancellationToken cancellationToken) // Exception from SfSession.OpenAsync Exception sfSessionEx = previousTask.Exception; _connectionState = ConnectionState.Closed; - _logger.Error("Unable to connect", sfSessionEx); + logger.Error("Unable to connect", sfSessionEx); throw new SnowflakeDbException( sfSessionEx, SnowflakeDbException.CONNECTION_FAILURE_SSTATE, @@ -338,14 +338,14 @@ public override Task OpenAsync(CancellationToken cancellationToken) else if (previousTask.IsCanceled) { _connectionState = ConnectionState.Closed; - _logger.Debug("Connection canceled"); + logger.Debug("Connection canceled"); throw new TaskCanceledException("Connecting was cancelled"); } else { // Only continue if the session was opened successfully SfSession = previousTask.Result; - _logger.Debug($"Connection open with pooled session: {SfSession.sessionId}"); + logger.Debug($"Connection open with pooled session: {SfSession.sessionId}"); OnSessionEstablished(); } }, TaskContinuationOptions.None); // this continuation should be executed always (even if the whole operation was canceled) because it sets the proper state of the connection @@ -409,7 +409,7 @@ protected override void Dispose(bool disposing) catch (Exception ex) { // Prevent an exception from being thrown when disposing of this object - _logger.Error("Unable to close connection", ex); + logger.Error("Unable to close connection", ex); } } else diff --git a/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs b/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs index a3bea367b..fcee66e1a 100644 --- a/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2024 Snowflake Computing Inc. All rights reserved. */ diff --git a/Snowflake.Data/Client/SnowflakeDbDataReader.cs b/Snowflake.Data/Client/SnowflakeDbDataReader.cs index 24166da9c..7d475024a 100755 --- a/Snowflake.Data/Client/SnowflakeDbDataReader.cs +++ b/Snowflake.Data/Client/SnowflakeDbDataReader.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -18,7 +18,7 @@ namespace Snowflake.Data.Client { public class SnowflakeDbDataReader : DbDataReader { - static private readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + static private readonly SFLogger logger = SFLoggerFactory.GetLogger(); private SnowflakeDbCommand dbCommand; diff --git a/Snowflake.Data/Client/SnowflakeDbTransaction.cs b/Snowflake.Data/Client/SnowflakeDbTransaction.cs index eda989864..539ca225a 100755 --- a/Snowflake.Data/Client/SnowflakeDbTransaction.cs +++ b/Snowflake.Data/Client/SnowflakeDbTransaction.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -12,7 +12,7 @@ namespace Snowflake.Data.Client { public class SnowflakeDbTransaction : DbTransaction { - private SFLogger _logger = SFLoggerFactory.GetLogger(); + private SFLogger logger = SFLoggerFactory.GetLogger(); private IsolationLevel isolationLevel; @@ -25,19 +25,19 @@ public class SnowflakeDbTransaction : DbTransaction public SnowflakeDbTransaction(IsolationLevel isolationLevel, SnowflakeDbConnection connection) { - _logger.Debug("Begin transaction."); + logger.Debug("Begin transaction."); if (isolationLevel != IsolationLevel.ReadCommitted) { throw new SnowflakeDbException(SFError.UNSUPPORTED_FEATURE); } if (connection == null) { - _logger.Error("Transaction cannot be started for an unknown connection"); + logger.Error("Transaction cannot be started for an unknown connection"); throw new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY); } if (!connection.IsOpen()) { - _logger.Error("Transaction cannot be started for a closed connection"); + logger.Error("Transaction cannot be started for a closed connection"); throw new SnowflakeDbException(SFError.UNSUPPORTED_FEATURE); } @@ -71,7 +71,7 @@ protected override DbConnection DbConnection public override void Commit() { - _logger.Debug("Commit transaction."); + logger.Debug("Commit transaction."); if (!isCommittedOrRollbacked) { using (IDbCommand command = connection.CreateCommand()) @@ -85,7 +85,7 @@ public override void Commit() public override void Rollback() { - _logger.Debug("Rollback transaction."); + logger.Debug("Rollback transaction."); if (!isCommittedOrRollbacked) { using (IDbCommand command = connection.CreateCommand()) diff --git a/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs b/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs index 9ce868dd7..a26d542d3 100644 --- a/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/BasicAuthenticator.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -11,7 +11,7 @@ namespace Snowflake.Data.Core.Authenticator class BasicAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "snowflake"; - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); internal BasicAuthenticator(SFSession session) : base(session, AUTH_NAME) { diff --git a/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs b/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs index a1f352f8b..e39ec18f8 100644 --- a/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -22,7 +22,7 @@ namespace Snowflake.Data.Core.Authenticator class ExternalBrowserAuthenticator : BaseAuthenticator, IAuthenticator { public const string AUTH_NAME = "externalbrowser"; - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); private static readonly string TOKEN_REQUEST_PREFIX = "?token="; private static readonly byte[] SUCCESS_RESPONSE = System.Text.Encoding.UTF8.GetBytes( "" + @@ -47,14 +47,14 @@ internal ExternalBrowserAuthenticator(SFSession session) : base(session, AUTH_NA /// async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken) { - s_logger.Info("External Browser Authentication"); + logger.Info("External Browser Authentication"); int localPort = GetRandomUnusedPort(); using (var httpListener = GetHttpListener(localPort)) { httpListener.Start(); - s_logger.Debug("Get IdpUrl and ProofKey"); + logger.Debug("Get IdpUrl and ProofKey"); string loginUrl; if (session._disableConsoleLogin) { @@ -75,37 +75,37 @@ await session.restRequester.PostAsync( loginUrl = GetLoginUrl(_proofKey, localPort); } - s_logger.Debug("Open browser"); + logger.Debug("Open browser"); StartBrowser(loginUrl); - s_logger.Debug("Get the redirect SAML request"); + logger.Debug("Get the redirect SAML request"); _successEvent = new ManualResetEvent(false); httpListener.BeginGetContext(GetContextCallback, httpListener); var timeoutInSec = int.Parse(session.properties[SFSessionProperty.BROWSER_RESPONSE_TIMEOUT]); if (!_successEvent.WaitOne(timeoutInSec * 1000)) { - s_logger.Warn("Browser response timeout"); + logger.Warn("Browser response timeout"); throw new SnowflakeDbException(SFError.BROWSER_RESPONSE_TIMEOUT, timeoutInSec); } httpListener.Stop(); } - s_logger.Debug("Send login request"); + logger.Debug("Send login request"); await base.LoginAsync(cancellationToken).ConfigureAwait(false); } /// void IAuthenticator.Authenticate() { - s_logger.Info("External Browser Authentication"); + logger.Info("External Browser Authentication"); int localPort = GetRandomUnusedPort(); using (var httpListener = GetHttpListener(localPort)) { httpListener.Start(); - s_logger.Debug("Get IdpUrl and ProofKey"); + logger.Debug("Get IdpUrl and ProofKey"); string loginUrl; if (session._disableConsoleLogin) { @@ -122,23 +122,23 @@ void IAuthenticator.Authenticate() loginUrl = GetLoginUrl(_proofKey, localPort); } - s_logger.Debug("Open browser"); + logger.Debug("Open browser"); StartBrowser(loginUrl); - s_logger.Debug("Get the redirect SAML request"); + logger.Debug("Get the redirect SAML request"); _successEvent = new ManualResetEvent(false); httpListener.BeginGetContext(GetContextCallback, httpListener); var timeoutInSec = int.Parse(session.properties[SFSessionProperty.BROWSER_RESPONSE_TIMEOUT]); if (!_successEvent.WaitOne(timeoutInSec * 1000)) { - s_logger.Warn("Browser response timeout"); + logger.Warn("Browser response timeout"); throw new SnowflakeDbException(SFError.BROWSER_RESPONSE_TIMEOUT, timeoutInSec); } httpListener.Stop(); } - s_logger.Debug("Send login request"); + logger.Debug("Send login request"); base.Login(); } @@ -163,7 +163,7 @@ private void GetContextCallback(IAsyncResult result) catch { // Ignore the exception as it does not affect the overall authentication flow - s_logger.Warn("External browser response not sent out"); + logger.Warn("External browser response not sent out"); } } @@ -193,13 +193,13 @@ private static void StartBrowser(string url) Match m = Regex.Match(url, regexStr, RegexOptions.IgnoreCase); if (!m.Success) { - s_logger.Error("Failed to start browser. Invalid url."); + logger.Error("Failed to start browser. Invalid url."); throw new SnowflakeDbException(SFError.INVALID_BROWSER_URL); } if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) { - s_logger.Error("Failed to start browser. Invalid url."); + logger.Error("Failed to start browser. Invalid url."); throw new SnowflakeDbException(SFError.INVALID_BROWSER_URL); } diff --git a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs index 5a1ad6f3a..40a98e761 100644 --- a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved. */ @@ -45,7 +45,7 @@ internal enum SFAuthenticatorType internal abstract class BaseAuthenticator { // The logger. - private static readonly SFLogger s_logger = + private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); // The name of the authenticator. diff --git a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs index 0439deb10..2a8522dbc 100644 --- a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved. */ @@ -32,7 +32,7 @@ class KeyPairAuthenticator : BaseAuthenticator, IAuthenticator public const string AUTH_NAME = "snowflake_jwt"; // The logger. - private static readonly SFLogger s_logger = + private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); // The RSA provider to use to sign the tokens @@ -57,7 +57,7 @@ async public Task AuthenticateAsync(CancellationToken cancellationToken) jwtToken = GenerateJwtToken(); // Send the http request with the generate token - s_logger.Debug("Send login request"); + logger.Debug("Send login request"); await base.LoginAsync(cancellationToken).ConfigureAwait(false); } @@ -67,7 +67,7 @@ public void Authenticate() jwtToken = GenerateJwtToken(); // Send the http request with the generate token - s_logger.Debug("Send login request"); + logger.Debug("Send login request"); base.Login(); } @@ -84,7 +84,7 @@ protected override void SetSpecializedAuthenticatorData(ref LoginRequestData dat /// The generated JWT token. private string GenerateJwtToken() { - s_logger.Info("Key-pair Authentication"); + logger.Info("Key-pair Authentication"); bool hasPkPath = session.properties.TryGetValue(SFSessionProperty.PRIVATE_KEY_FILE, out var pkPath); diff --git a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs index 4b94c82e1..52cd2ab96 100644 --- a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs @@ -17,7 +17,7 @@ class OAuthAuthenticator : BaseAuthenticator, IAuthenticator public const string AUTH_NAME = "oauth"; // The logger. - private static readonly SFLogger s_logger = + private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); /// From d2f94f408354ddd7255af31b01373f4c86c0a1fb Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 16:53:42 -0800 Subject: [PATCH 27/35] Revert logger name --- .../Core/Authenticator/IAuthenticator.cs | 8 +-- .../Authenticator/KeyPairAuthenticator.cs | 1 - Snowflake.Data/Core/ChunkDownloaderFactory.cs | 2 +- Snowflake.Data/Core/ChunkParserFactory.cs | 2 +- Snowflake.Data/Core/FastParser.cs | 8 +-- .../Core/FileTransfer/EncryptionProvider.cs | 6 +- .../Core/FileTransfer/SFFileTransferAgent.cs | 58 +++++++++---------- .../FileTransfer/StorageClient/SFGCSClient.cs | 16 ++--- .../FileTransfer/StorageClient/SFS3Client.cs | 10 ++-- .../StorageClient/SFSnowflakeAzureClient.cs | 4 +- Snowflake.Data/Core/HttpUtil.cs | 6 +- Snowflake.Data/Core/RestRequester.cs | 10 ++-- Snowflake.Data/Core/SFBindUploader.cs | 6 +- .../Core/SFBlockingChunkDownloaderV3.cs | 10 ++-- .../Core/SFMultiStatementsResultSet.cs | 4 +- Snowflake.Data/Core/SFResultSet.cs | 4 +- Snowflake.Data/Core/SFResultSetMetaData.cs | 4 +- Snowflake.Data/Core/SFStatement.cs | 42 +++++++------- 18 files changed, 100 insertions(+), 101 deletions(-) diff --git a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs index 40a98e761..7a41a8335 100644 --- a/Snowflake.Data/Core/Authenticator/IAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/IAuthenticator.cs @@ -134,7 +134,7 @@ private SFRestRequest BuildLoginRequest() /// internal class AuthenticatorFactory { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); /// /// Generate the authenticator given the session /// @@ -164,7 +164,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) var error = new SnowflakeDbException( SFError.INVALID_CONNECTION_STRING, new object[] { invalidStringDetail }); - s_logger.Error(error.Message, error); + logger.Error(error.Message, error); throw error; } @@ -181,7 +181,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) var error = new SnowflakeDbException( SFError.INVALID_CONNECTION_STRING, new object[] { invalidStringDetail }); - s_logger.Error(error.Message, error); + logger.Error(error.Message, error); throw error; } @@ -192,7 +192,7 @@ internal static IAuthenticator GetAuthenticator(SFSession session) { return new OktaAuthenticator(session, type); } - s_logger.Error($"Unknown authenticator {type}"); + logger.Error($"Unknown authenticator {type}"); throw new SnowflakeDbException(SFError.UNKNOWN_AUTHENTICATOR, type); } } diff --git a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs index 2a8522dbc..7d86d02c9 100644 --- a/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/KeyPairAuthenticator.cs @@ -19,7 +19,6 @@ using Org.BouncyCastle.X509; using System.Security.Claims; using Microsoft.IdentityModel.Tokens; - namespace Snowflake.Data.Core.Authenticator { /// diff --git a/Snowflake.Data/Core/ChunkDownloaderFactory.cs b/Snowflake.Data/Core/ChunkDownloaderFactory.cs index 48f888a4c..553e67d2d 100755 --- a/Snowflake.Data/Core/ChunkDownloaderFactory.cs +++ b/Snowflake.Data/Core/ChunkDownloaderFactory.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ diff --git a/Snowflake.Data/Core/ChunkParserFactory.cs b/Snowflake.Data/Core/ChunkParserFactory.cs index be4435ffa..87d3a5f33 100755 --- a/Snowflake.Data/Core/ChunkParserFactory.cs +++ b/Snowflake.Data/Core/ChunkParserFactory.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ diff --git a/Snowflake.Data/Core/FastParser.cs b/Snowflake.Data/Core/FastParser.cs index 1f5b997b3..632876269 100644 --- a/Snowflake.Data/Core/FastParser.cs +++ b/Snowflake.Data/Core/FastParser.cs @@ -6,14 +6,14 @@ namespace Snowflake.Data.Core { public class FastParser { - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); public static Int64 FastParseInt64(byte[] s, int offset, int len) { if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - s_logger.Error("A null buffer was passed to FastParseInt64", ex); + Logger.Error("A null buffer was passed to FastParseInt64", ex); throw ex; } @@ -54,7 +54,7 @@ public static Int32 FastParseInt32(byte[] s, int offset, int len) if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - s_logger.Error("A null buffer was passed to FastParseInt32", ex); + Logger.Error("A null buffer was passed to FastParseInt32", ex); throw ex; } @@ -95,7 +95,7 @@ public static decimal FastParseDecimal(byte[] s, int offset, int len) if (s == null) { Exception ex = new SnowflakeDbException(SFError.INTERNAL_ERROR, $"Cannot parse a null buffer"); - s_logger.Error("A null buffer was passed to FastParseDecimal", ex); + Logger.Error("A null buffer was passed to FastParseDecimal", ex); throw ex; } diff --git a/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs b/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs index 6f02f8943..b625f80d3 100644 --- a/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs +++ b/Snowflake.Data/Core/FileTransfer/EncryptionProvider.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. */ @@ -22,7 +22,7 @@ class EncryptionProvider /// /// The logger. /// - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); /// /// Encrypt data and write to the outStream. @@ -60,7 +60,7 @@ public static StreamPair EncryptStream( { byte[] decodedMasterKey = Convert.FromBase64String(encryptionMaterial.queryStageMasterKey); int masterKeySize = decodedMasterKey.Length; - s_logger.Debug($"Master key size : {masterKeySize}"); + Logger.Debug($"Master key size : {masterKeySize}"); // Generate file key byte[] ivData = new byte[blockSize]; diff --git a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs index 6c6cbc6fd..1ee8557b6 100644 --- a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs +++ b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 Snowflake Computing Inc. All rights reserved. */ @@ -60,7 +60,7 @@ class SFFileTransferAgent /// /// The logger. /// - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); /// /// Auto-detect keyword for source compression type auto detection. @@ -230,7 +230,7 @@ public void execute() } catch (Exception e) { - s_logger.Error("Error while transferring file(s): " + e.Message); + Logger.Error("Error while transferring file(s): " + e.Message); if (e is SnowflakeDbException snowflakeException) { if (snowflakeException.QueryId == null) @@ -346,19 +346,19 @@ private void upload() //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - s_logger.Debug("Start uploading large files"); + Logger.Debug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { UploadFilesInSequential(fileMetadata); } - s_logger.Debug("End uploading large files"); + Logger.Debug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - s_logger.Debug("Start uploading small files"); + Logger.Debug("Start uploading small files"); UploadFilesInParallel(SmallFilesMetas, TransferMetadata.parallel); - s_logger.Debug("End uploading small files"); + Logger.Debug("End uploading small files"); } } @@ -372,19 +372,19 @@ private async Task uploadAsync(CancellationToken cancellationToken) //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - s_logger.Debug("Start uploading large files"); + Logger.Debug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { await UploadFilesInSequentialAsync(fileMetadata, cancellationToken).ConfigureAwait(false); } - s_logger.Debug("End uploading large files"); + Logger.Debug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - s_logger.Debug("Start uploading small files"); + Logger.Debug("Start uploading small files"); await UploadFilesInParallelAsync(SmallFilesMetas, TransferMetadata.parallel, cancellationToken).ConfigureAwait(false); - s_logger.Debug("End uploading small files"); + Logger.Debug("End uploading small files"); } } @@ -399,18 +399,18 @@ private void download() //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - s_logger.Debug("Start uploading large files"); + Logger.Debug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { DownloadFilesInSequential(fileMetadata); } - s_logger.Debug("End uploading large files"); + Logger.Debug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - s_logger.Debug("Start uploading small files"); + Logger.Debug("Start uploading small files"); DownloadFilesInParallel(SmallFilesMetas, TransferMetadata.parallel); - s_logger.Debug("End uploading small files"); + Logger.Debug("End uploading small files"); } } @@ -424,18 +424,18 @@ private async Task downloadAsync(CancellationToken cancellationToken) //For each file, using the remote client if (0 < LargeFilesMetas.Count) { - s_logger.Debug("Start uploading large files"); + Logger.Debug("Start uploading large files"); foreach (SFFileMetadata fileMetadata in LargeFilesMetas) { await DownloadFilesInSequentialAsync(fileMetadata, cancellationToken).ConfigureAwait(false); } - s_logger.Debug("End uploading large files"); + Logger.Debug("End uploading large files"); } if (0 < SmallFilesMetas.Count) { - s_logger.Debug("Start uploading small files"); + Logger.Debug("Start uploading small files"); await DownloadFilesInParallelAsync(SmallFilesMetas, TransferMetadata.parallel, cancellationToken).ConfigureAwait(false); - s_logger.Debug("End uploading small files"); + Logger.Debug("End uploading small files"); } } @@ -574,7 +574,7 @@ private void initFileMetadata( // Auto-detect source compression type // Will return NONE if no matching type is found compressionType = SFFileCompressionTypes.GuessCompressionType(file); - s_logger.Debug($"File compression detected as {compressionType.Name} for: {file}"); + Logger.Debug($"File compression detected as {compressionType.Name} for: {file}"); } else { @@ -716,7 +716,7 @@ private int GetFileTransferMaxBytesInMemory() } catch (Exception) { - s_logger.Warn("Default for FILE_TRANSFER_MEMORY_THRESHOLD used due to invalid session value."); + Logger.Warn("Default for FILE_TRANSFER_MEMORY_THRESHOLD used due to invalid session value."); return FileTransferConfiguration.DefaultMaxBytesInMemory; } } @@ -782,12 +782,12 @@ private List expandFileNames(string location) } } - if (s_logger.IsDebugEnabled()) + if (Logger.IsDebugEnabled()) { - s_logger.Debug("Expand " + location + " into: "); + Logger.Debug("Expand " + location + " into: "); foreach (var filepath in filePaths) { - s_logger.Debug("\t" + filepath ); + Logger.Debug("\t" + filepath ); } } @@ -901,7 +901,7 @@ private void compressFileWithGzip(SFFileMetadata fileMetadata) } } - s_logger.Debug($"Compressed {fileToCompress.Name} to {fileMetadata.realSrcFilePath}"); + Logger.Debug($"Compressed {fileToCompress.Name} to {fileMetadata.realSrcFilePath}"); FileInfo destInfo = new FileInfo(fileMetadata.realSrcFilePath); fileMetadata.destFileSize = destInfo.Length; } @@ -1235,7 +1235,7 @@ private SFFileMetadata UploadSingleFile( } catch (Exception ex) { - s_logger.Debug("Unhandled exception while uploading file.", ex); + Logger.Debug("Unhandled exception while uploading file.", ex); throw; } finally @@ -1284,7 +1284,7 @@ private async Task UploadSingleFileAsync( } catch (Exception ex) { - s_logger.Error("UploadSingleFileAsync encountered an error: " + ex.Message); + Logger.Error("UploadSingleFileAsync encountered an error: " + ex.Message); throw; } finally @@ -1322,7 +1322,7 @@ private SFFileMetadata DownloadSingleFile( } catch (Exception ex) { - s_logger.Error("DownloadSingleFile encountered an error: " + ex.Message); + Logger.Error("DownloadSingleFile encountered an error: " + ex.Message); throw; } finally @@ -1360,7 +1360,7 @@ private async Task DownloadSingleFileAsync( } catch (Exception ex) { - s_logger.Error("DownloadSingleFileAsync encountered an error: " + ex.Message); + Logger.Error("DownloadSingleFileAsync encountered an error: " + ex.Message); throw; } finally diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs index d0a9f1ac6..1a86b15a9 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs @@ -42,7 +42,7 @@ class SFGCSClient : ISFRemoteStorageClient /// /// The logger. /// - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); /// /// The storage client. @@ -62,11 +62,11 @@ class SFGCSClient : ISFRemoteStorageClient /// The command stage info. public SFGCSClient(PutGetStageInfo stageInfo) { - s_logger.Debug("Setting up a new GCS client "); + Logger.Debug("Setting up a new GCS client "); if (stageInfo.stageCredentials.TryGetValue(GCS_ACCESS_TOKEN, out string accessToken)) { - s_logger.Debug("Constructing client using access token"); + Logger.Debug("Constructing client using access token"); AccessToken = accessToken; GoogleCredential creds = GoogleCredential.FromAccessToken(accessToken, null); var storageClientBuilder = new StorageClientBuilder @@ -78,7 +78,7 @@ public SFGCSClient(PutGetStageInfo stageInfo) } else { - s_logger.Info("No access token received from GS, constructing anonymous client with no encryption support"); + Logger.Info("No access token received from GS, constructing anonymous client with no encryption support"); var storageClientBuilder = new StorageClientBuilder { UnauthenticatedAccess = true @@ -475,7 +475,7 @@ private void HandleDownloadResponse(HttpWebResponse response, SFFileMetadata fil /// File Metadata private SFFileMetadata HandleFileHeaderErrForPresignedUrls(WebException ex, SFFileMetadata fileMetadata) { - s_logger.Error("Failed to get file header for presigned url: " + ex.Message); + Logger.Error("Failed to get file header for presigned url: " + ex.Message); HttpWebResponse response = (HttpWebResponse)ex.Response; if (response.StatusCode == HttpStatusCode.Unauthorized || @@ -501,7 +501,7 @@ private SFFileMetadata HandleFileHeaderErrForPresignedUrls(WebException ex, SFFi /// File Metadata private SFFileMetadata HandleFileHeaderErrForGeneratedUrls(WebException ex, SFFileMetadata fileMetadata) { - s_logger.Error("Failed to get file header for non-presigned url: " + ex.Message); + Logger.Error("Failed to get file header for non-presigned url: " + ex.Message); HttpWebResponse response = (HttpWebResponse)ex.Response; if (response.StatusCode == HttpStatusCode.Unauthorized) @@ -536,7 +536,7 @@ private SFFileMetadata HandleFileHeaderErrForGeneratedUrls(WebException ex, SFFi /// File Metadata private SFFileMetadata HandleUploadFileErr(WebException ex, SFFileMetadata fileMetadata) { - s_logger.Error("Failed to upload file: " + ex.Message); + Logger.Error("Failed to upload file: " + ex.Message); fileMetadata.lastError = ex; @@ -570,7 +570,7 @@ private SFFileMetadata HandleUploadFileErr(WebException ex, SFFileMetadata fileM /// File Metadata private SFFileMetadata HandleDownloadFileErr(WebException ex, SFFileMetadata fileMetadata) { - s_logger.Error("Failed to download file: " + ex.Message); + Logger.Error("Failed to download file: " + ex.Message); fileMetadata.lastError = ex; diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs index 025dbac15..524dc23c1 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFS3Client.cs @@ -72,7 +72,7 @@ internal class S3Metadata /// /// The logger. /// - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); /// /// The underlying S3 client. @@ -89,7 +89,7 @@ public SFS3Client( int parallel, ProxyCredentials proxyCredentials) { - s_logger.Debug("Setting up a new AWS client "); + Logger.Debug("Setting up a new AWS client "); // Get the key id and secret key from the response stageInfo.stageCredentials.TryGetValue(AWS_KEY_ID, out string awsAccessKeyId); @@ -537,7 +537,7 @@ private GetObjectRequest GetGetObjectRequest(ref AmazonS3Client client, SFFileMe /// The file metadata. private void HandleFileHeaderErr(Exception ex, SFFileMetadata fileMetadata) { - s_logger.Error("Failed to get file header: " + ex.Message); + Logger.Error("Failed to get file header: " + ex.Message); switch (ex) { @@ -569,7 +569,7 @@ private void HandleFileHeaderErr(Exception ex, SFFileMetadata fileMetadata) /// The file metadata. private void HandleUploadFileErr(Exception ex, SFFileMetadata fileMetadata) { - s_logger.Error("Failed to upload file: " + ex.Message); + Logger.Error("Failed to upload file: " + ex.Message); switch (ex) { @@ -599,7 +599,7 @@ private void HandleUploadFileErr(Exception ex, SFFileMetadata fileMetadata) /// The file metadata. private void HandleDownloadFileErr(Exception ex, SFFileMetadata fileMetadata) { - s_logger.Error("Failed to download file: " + ex.Message); + Logger.Error("Failed to download file: " + ex.Message); switch (ex) { diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs index 1175ff3cd..d13dc01b9 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFSnowflakeAzureClient.cs @@ -31,7 +31,7 @@ class SFSnowflakeAzureClient : ISFRemoteStorageClient /// /// The logger. /// - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); /// /// The cloud blob client to use to upload and download data on Azure. @@ -44,7 +44,7 @@ class SFSnowflakeAzureClient : ISFRemoteStorageClient /// The command stage info. public SFSnowflakeAzureClient(PutGetStageInfo stageInfo) { - s_logger.Debug("Setting up a new Azure client "); + Logger.Debug("Setting up a new Azure client "); // Get the Azure SAS token and create the client if (stageInfo.stageCredentials.TryGetValue(AZURE_SAS_TOKEN, out string sasToken)) diff --git a/Snowflake.Data/Core/HttpUtil.cs b/Snowflake.Data/Core/HttpUtil.cs index d352dd0d3..750729885 100644 --- a/Snowflake.Data/Core/HttpUtil.cs +++ b/Snowflake.Data/Core/HttpUtil.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved. */ @@ -77,7 +77,7 @@ public sealed class HttpUtil static internal readonly int MAX_BACKOFF = 16; private static readonly int s_baseBackOffTime = 1; private static readonly int s_exponentialFactor = 2; - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); private static readonly List s_supportedEndpointsForRetryPolicy = new List { @@ -114,7 +114,7 @@ private HttpClient RegisterNewHttpClientIfNecessary(HttpClientConfig config, Del string name = config.ConfKey; if (!_HttpClients.ContainsKey(name)) { - s_logger.Debug("Http client not registered. Adding."); + logger.Debug("Http client not registered. Adding."); var httpClient = new HttpClient( new RetryHandler(SetupCustomHttpHandler(config, customHandler), config.DisableRetry, config.ForceRetryOn404, config.MaxHttpRetries, config.IncludeRetryReason)) diff --git a/Snowflake.Data/Core/RestRequester.cs b/Snowflake.Data/Core/RestRequester.cs index a6dc8f8ec..4c2c7ee39 100644 --- a/Snowflake.Data/Core/RestRequester.cs +++ b/Snowflake.Data/Core/RestRequester.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -39,7 +39,7 @@ internal interface IMockRestRequester : IRestRequester internal class RestRequester : IRestRequester { - private static SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static SFLogger logger = SFLoggerFactory.GetLogger(); protected HttpClient _HttpClient; @@ -113,18 +113,18 @@ protected virtual async Task SendAsync(HttpRequestMessage m HttpResponseMessage response = null; try { - s_logger.Debug($"Executing: {sid} {message.Method} {message.RequestUri} HTTP/{message.Version}"); + logger.Debug($"Executing: {sid} {message.Method} {message.RequestUri} HTTP/{message.Version}"); response = await _HttpClient .SendAsync(message, HttpCompletionOption.ResponseHeadersRead, linkedCts.Token) .ConfigureAwait(false); if (!response.IsSuccessStatusCode) { - s_logger.Error($"Failed Response: {sid} {message.Method} {message.RequestUri} StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + logger.Error($"Failed Response: {sid} {message.Method} {message.RequestUri} StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); } else { - s_logger.Debug($"Succeeded Response: {sid} {message.Method} {message.RequestUri}"); + logger.Debug($"Succeeded Response: {sid} {message.Method} {message.RequestUri}"); } response.EnsureSuccessStatusCode(); diff --git a/Snowflake.Data/Core/SFBindUploader.cs b/Snowflake.Data/Core/SFBindUploader.cs index 00031ab2a..dfc98c1bf 100644 --- a/Snowflake.Data/Core/SFBindUploader.cs +++ b/Snowflake.Data/Core/SFBindUploader.cs @@ -35,7 +35,7 @@ class SFBindUploader private string requestId; - private SFLogger loggerPair = SFLoggerFactory.GetLogger(); + private SFLogger logger = SFLoggerFactory.GetLogger(); private string stagePath; @@ -309,7 +309,7 @@ private void CreateStage() catch (Exception e) { session.SetArrayBindStageThreshold(0); - loggerPair.Error("Failed to create temporary stage for array binds.", e); + logger.Error("Failed to create temporary stage for array binds.", e); throw; } } @@ -333,7 +333,7 @@ internal async Task CreateStageAsync(CancellationToken cancellationToken) catch (Exception e) { session.SetArrayBindStageThreshold(0); - loggerPair.Error("Failed to create temporary stage for array binds.", e); + logger.Error("Failed to create temporary stage for array binds.", e); throw; } } diff --git a/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs b/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs index d4f76ff44..955af16a4 100755 --- a/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs +++ b/Snowflake.Data/Core/SFBlockingChunkDownloaderV3.cs @@ -22,7 +22,7 @@ namespace Snowflake.Data.Core { class SFBlockingChunkDownloaderV3 : IChunkDownloader { - static private SFLogger s_logger = SFLoggerFactory.GetLogger(); + static private SFLogger logger = SFLoggerFactory.GetLogger(); private List chunkDatas = new List(); @@ -99,7 +99,7 @@ private int GetPrefetchThreads(SFBaseResultSet resultSet) public async Task GetNextChunkAsync() { - s_logger.Info($"NextChunkToConsume: {nextChunkToConsumeIndex}, NextChunkToDownload: {nextChunkToDownloadIndex}"); + logger.Info($"NextChunkToConsume: {nextChunkToConsumeIndex}, NextChunkToDownload: {nextChunkToDownloadIndex}"); if (nextChunkToConsumeIndex < chunkInfos.Count) { Task chunk = taskQueues[nextChunkToConsumeIndex % prefetchSlot]; @@ -192,7 +192,7 @@ private async Task DownloadChunkAsync(DownloadContextV3 downloa { if ((maxRetry <= 0) || (retryCount < maxRetry)) { - s_logger.Debug($"Retry {retryCount}/{maxRetry} of parse stream to chunk error: " + e.Message); + logger.Debug($"Retry {retryCount}/{maxRetry} of parse stream to chunk error: " + e.Message); retry = true; // reset the chunk before retry in case there could be garbage // data left from last attempt @@ -209,13 +209,13 @@ private async Task DownloadChunkAsync(DownloadContextV3 downloa else { //parse error - s_logger.Error("Failed retries of parse stream to chunk error: " + e.Message); + logger.Error("Failed retries of parse stream to chunk error: " + e.Message); throw new Exception("Parse stream to chunk error: " + e.Message); } } } } while (retry); - s_logger.Info($"Succeed downloading chunk #{chunk.ChunkIndex}"); + logger.Info($"Succeed downloading chunk #{chunk.ChunkIndex}"); return chunk; } diff --git a/Snowflake.Data/Core/SFMultiStatementsResultSet.cs b/Snowflake.Data/Core/SFMultiStatementsResultSet.cs index 5d1e67f65..18eb4f650 100644 --- a/Snowflake.Data/Core/SFMultiStatementsResultSet.cs +++ b/Snowflake.Data/Core/SFMultiStatementsResultSet.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2022 Snowflake Computing Inc. All rights reserved. */ @@ -15,7 +15,7 @@ class SFMultiStatementsResultSet : SFBaseResultSet { internal override ResultFormat ResultFormat => curResultSet.ResultFormat; - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger Logger = SFLoggerFactory.GetLogger(); private string[] resultIds; diff --git a/Snowflake.Data/Core/SFResultSet.cs b/Snowflake.Data/Core/SFResultSet.cs index 96c349de3..e81db8c14 100755 --- a/Snowflake.Data/Core/SFResultSet.cs +++ b/Snowflake.Data/Core/SFResultSet.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -100,7 +100,7 @@ public SFResultSet(PutGetResponseData responseData, SFStatement sfStatement, Can internal void ResetChunkInfo(BaseResultChunk nextChunk) { - s_logger.Debug($"Received chunk #{nextChunk.ChunkIndex + 1} of {_totalChunkCount}"); + s_logger.Debug($"Received chunk #{nextChunk.ChunkIndex + 1} of {_totalChunkCount}"); _currentChunk.RowSet = null; _currentChunk = nextChunk; } diff --git a/Snowflake.Data/Core/SFResultSetMetaData.cs b/Snowflake.Data/Core/SFResultSetMetaData.cs index 3bc847ac3..bb5f2e819 100755 --- a/Snowflake.Data/Core/SFResultSetMetaData.cs +++ b/Snowflake.Data/Core/SFResultSetMetaData.cs @@ -12,7 +12,7 @@ namespace Snowflake.Data.Core { class SFResultSetMetaData { - static private readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + static private readonly SFLogger logger = SFLoggerFactory.GetLogger(); private int columnCount; @@ -92,7 +92,7 @@ internal int GetColumnIndexByName(string targetColumnName) { if (String.Compare(rowType.name, targetColumnName, false) == 0 ) { - s_logger.Info($"Found column name {targetColumnName} under index {indexCounter}"); + logger.Info($"Found column name {targetColumnName} under index {indexCounter}"); columnNameToIndexCache[targetColumnName] = indexCounter; return indexCounter; } diff --git a/Snowflake.Data/Core/SFStatement.cs b/Snowflake.Data/Core/SFStatement.cs index 90ad6e1d9..7dac1c600 100644 --- a/Snowflake.Data/Core/SFStatement.cs +++ b/Snowflake.Data/Core/SFStatement.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. */ @@ -97,7 +97,7 @@ internal static bool IsAnError(QueryStatus status) class SFStatement { - static private SFLogger s_logger = SFLoggerFactory.GetLogger(); + static private SFLogger logger = SFLoggerFactory.GetLogger(); internal SFSession SfSession { get; set; } @@ -168,7 +168,7 @@ private void AssignQueryRequestId() if (_requestId != null) { - s_logger.Info("Another query is running."); + logger.Info("Another query is running."); throw new SnowflakeDbException(SFError.STATEMENT_ALREADY_RUNNING_QUERY); } @@ -340,7 +340,7 @@ private void registerQueryCancellationCallback(int timeout, CancellationToken ex catch (Exception ex) { // Prevent an unhandled exception from being thrown - s_logger.Error("Unable to cancel query.", ex); + logger.Error("Unable to cancel query.", ex); } }); } @@ -386,7 +386,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti } catch (Exception e) { - s_logger.Warn("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); + logger.Warn("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); } finally { @@ -424,7 +424,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti if (SessionExpired(response)) { - s_logger.Info("Ping pong request failed with session expired, trying to renew the session."); + logger.Info("Ping pong request failed with session expired, trying to renew the session."); await SfSession.renewSessionAsync(cancellationToken).ConfigureAwait(false); } else @@ -438,7 +438,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti } catch { - s_logger.Error("Query execution failed."); + logger.Error("Query execution failed."); throw; } finally @@ -484,7 +484,7 @@ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, string tri bindings, describeOnly); - s_logger.Debug("PUT/GET queryId: " + (response.data != null ? response.data.queryId : "Unknown")); + logger.Debug("PUT/GET queryId: " + (response.data != null ? response.data.queryId : "Unknown")); SFFileTransferAgent fileTransferAgent = new SFFileTransferAgent(trimmedSql, SfSession, response.data, CancellationToken.None); @@ -500,13 +500,13 @@ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, string tri } catch (SnowflakeDbException ex) { - s_logger.Error($"Query execution failed, QueryId: {ex.QueryId??"unavailable"}", ex); + logger.Error($"Query execution failed, QueryId: {ex.QueryId??"unavailable"}", ex); _lastQueryId = ex.QueryId ?? _lastQueryId; throw; } catch (Exception ex) { - s_logger.Error("Query execution failed.", ex); + logger.Error("Query execution failed.", ex); throw new SnowflakeDbException(ex, SFError.INTERNAL_ERROR); } } @@ -538,7 +538,7 @@ private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dicti } catch (Exception e) { - s_logger.Warn("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); + logger.Warn("Exception encountered trying to upload binds to stage. Attaching binds in payload instead. Exception: " + e.Message); } finally { @@ -558,7 +558,7 @@ private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dicti } catch (Exception ex) { - s_logger.Error("Query execution failed.", ex); + logger.Error("Query execution failed.", ex); if (ex is SnowflakeDbException snowflakeDbException) { _lastQueryId = snowflakeDbException.QueryId ?? _lastQueryId; @@ -624,11 +624,11 @@ internal void Cancel() if (response.success) { - s_logger.Info("Query cancellation succeed"); + logger.Info("Query cancellation succeed"); } else { - s_logger.Warn("Query cancellation failed."); + logger.Warn("Query cancellation failed."); } CleanUpCancellationTokenSources(); } @@ -685,7 +685,7 @@ internal T ExecuteHelper( if (SessionExpired(response)) { - s_logger.Info("Ping pong request failed with session expired, trying to renew the session."); + logger.Info("Ping pong request failed with session expired, trying to renew the session."); SfSession.renewSession(); } else @@ -709,7 +709,7 @@ internal T ExecuteHelper( } catch (Exception ex) { - s_logger.Error("Query execution failed.", ex); + logger.Error("Query execution failed.", ex); throw; } finally @@ -772,7 +772,7 @@ internal async Task ExecuteAsyncHelper( if (SessionExpired(response)) { - s_logger.Info("Ping pong request failed with session expired, trying to renew the session."); + logger.Info("Ping pong request failed with session expired, trying to renew the session."); await SfSession.renewSessionAsync(cancellationToken).ConfigureAwait(false); } else @@ -796,7 +796,7 @@ internal async Task ExecuteAsyncHelper( } catch (Exception ex) { - s_logger.Error("Query execution failed.", ex); + logger.Error("Query execution failed.", ex); throw; } finally @@ -873,7 +873,7 @@ internal QueryStatus GetQueryStatus(string queryId) } catch { - s_logger.Error("Query execution failed."); + logger.Error("Query execution failed."); throw; } finally @@ -928,7 +928,7 @@ internal async Task GetQueryStatusAsync(string queryId, Cancellatio } catch { - s_logger.Error("Query execution failed."); + logger.Error("Query execution failed."); throw; } finally @@ -991,7 +991,7 @@ internal static string TrimSql(string originalSql) var trimmedQuery = builder.ToString(); trimmedQuery = trimmedQuery.Trim(); - s_logger.Debug("Trimmed query : " + trimmedQuery); + logger.Debug("Trimmed query : " + trimmedQuery); return trimmedQuery; } From 6affd0a013a3fa12cd3ad29825586b0bfb44871a Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 16:57:16 -0800 Subject: [PATCH 28/35] Revert logger name --- Snowflake.Data/Core/HttpUtil.cs | 32 +++++----- Snowflake.Data/Core/Session/SFSession.cs | 60 +++++++++---------- .../Core/Session/SFSessionProperty.cs | 34 +++++------ .../Core/Tools/HomeDirectoryProvider.cs | 2 +- 4 files changed, 64 insertions(+), 64 deletions(-) diff --git a/Snowflake.Data/Core/HttpUtil.cs b/Snowflake.Data/Core/HttpUtil.cs index 750729885..63cb1b531 100644 --- a/Snowflake.Data/Core/HttpUtil.cs +++ b/Snowflake.Data/Core/HttpUtil.cs @@ -333,7 +333,7 @@ internal Uri Update(int retryReason = 0) } private class RetryHandler : DelegatingHandler { - static private SFLogger s_logger = SFLoggerFactory.GetLogger(); + static private SFLogger logger = SFLoggerFactory.GetLogger(); private bool disableRetry; private bool forceRetryOn404; @@ -367,10 +367,10 @@ protected override async Task SendAsync(HttpRequestMessage TimeSpan httpTimeout = (TimeSpan)requestMessage.Properties[BaseRestRequest.HTTP_REQUEST_TIMEOUT_KEY]; TimeSpan restTimeout = (TimeSpan)requestMessage.Properties[BaseRestRequest.REST_REQUEST_TIMEOUT_KEY]; - if (s_logger.IsDebugEnabled()) + if (logger.IsDebugEnabled()) { - s_logger.Debug("Http request timeout : " + httpTimeout); - s_logger.Debug("Rest request timeout : " + restTimeout); + logger.Debug("Http request timeout : " + httpTimeout); + logger.Debug("Rest request timeout : " + restTimeout); } CancellationTokenSource childCts = null; @@ -401,12 +401,12 @@ protected override async Task SendAsync(HttpRequestMessage lastException = e; if (cancellationToken.IsCancellationRequested) { - s_logger.Info("SF rest request timeout or explicit cancel called."); + logger.Info("SF rest request timeout or explicit cancel called."); cancellationToken.ThrowIfCancellationRequested(); } else if (childCts != null && childCts.Token.IsCancellationRequested) { - s_logger.Warn("Http request timeout. Retry the request"); + logger.Warn("Http request timeout. Retry the request"); totalRetryTime += (int)httpTimeout.TotalSeconds; } else @@ -415,13 +415,13 @@ protected override async Task SendAsync(HttpRequestMessage if (innermostException is AuthenticationException) { - s_logger.Error("Non-retryable error encountered: ", e); + logger.Error("Non-retryable error encountered: ", e); throw; } else { //TODO: Should probably check to see if the error is recoverable or transient. - s_logger.Warn("Error occurred during request, retrying...", e); + logger.Warn("Error occurred during request, retrying...", e); } } } @@ -445,12 +445,12 @@ protected override async Task SendAsync(HttpRequestMessage if (response.IsSuccessStatusCode) { - s_logger.Debug($"Success Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + logger.Debug($"Success Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); return response; } else { - s_logger.Debug($"Failed Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); + logger.Debug($"Failed Response: StatusCode: {(int)response.StatusCode}, ReasonPhrase: '{response.ReasonPhrase}'"); bool isRetryable = isRetryableHTTPCode((int)response.StatusCode, forceRetryOn404); if (!isRetryable || disableRetry) @@ -463,19 +463,19 @@ protected override async Task SendAsync(HttpRequestMessage } else { - s_logger.Info("Response returned was null."); + logger.Info("Response returned was null."); } if (restTimeout.TotalSeconds > 0 && totalRetryTime >= restTimeout.TotalSeconds) { - s_logger.Debug($"stop retry as connection_timeout {restTimeout.TotalSeconds} sec. reached"); + logger.Debug($"stop retry as connection_timeout {restTimeout.TotalSeconds} sec. reached"); if (response != null) { return response; } var errorMessage = $"http request failed and connection_timeout {restTimeout.TotalSeconds} sec. reached.\n"; errorMessage += $"Last exception encountered: {lastException}"; - s_logger.Error(errorMessage); + logger.Error(errorMessage); throw new OperationCanceledException(errorMessage); } @@ -488,14 +488,14 @@ protected override async Task SendAsync(HttpRequestMessage retryCount++; if ((maxRetryCount > 0) && (retryCount > maxRetryCount)) { - s_logger.Debug($"stop retry as maxHttpRetries {maxRetryCount} reached"); + logger.Debug($"stop retry as maxHttpRetries {maxRetryCount} reached"); if (response != null) { return response; } var errorMessage = $"http request failed and max retry {maxRetryCount} reached.\n"; errorMessage += $"Last exception encountered: {lastException}"; - s_logger.Error(errorMessage); + logger.Error(errorMessage); throw new OperationCanceledException(errorMessage); } @@ -504,7 +504,7 @@ protected override async Task SendAsync(HttpRequestMessage requestMessage.RequestUri = updater.Update(errorReason); - s_logger.Debug($"Sleep {backOffInSec} seconds and then retry the request, retryCount: {retryCount}"); + logger.Debug($"Sleep {backOffInSec} seconds and then retry the request, retryCount: {retryCount}"); await Task.Delay(TimeSpan.FromSeconds(backOffInSec), cancellationToken).ConfigureAwait(false); diff --git a/Snowflake.Data/Core/Session/SFSession.cs b/Snowflake.Data/Core/Session/SFSession.cs index d17f5f675..b6a0ebf79 100755 --- a/Snowflake.Data/Core/Session/SFSession.cs +++ b/Snowflake.Data/Core/Session/SFSession.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2012-2024 Snowflake Computing Inc. All rights reserved. */ @@ -23,7 +23,7 @@ public class SFSession { public const int SF_SESSION_EXPIRED_CODE = 390112; - private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static readonly SFLogger logger = SFLoggerFactory.GetLogger(); private static readonly Regex APPLICATION_REGEX = new Regex(@"^[A-Za-z]([A-Za-z0-9.\-_]){1,50}$"); @@ -114,9 +114,9 @@ internal void ProcessLoginResponse(LoginResponse authnResponse) UpdateSessionParameterMap(authnResponse.data.nameValueParameter); if (_disableQueryContextCache) { - s_logger.Debug("Query context cache disabled."); + logger.Debug("Query context cache disabled."); } - s_logger.Debug($"Session opened: {sessionId}"); + logger.Debug($"Session opened: {sessionId}"); _startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } else @@ -127,7 +127,7 @@ internal void ProcessLoginResponse(LoginResponse authnResponse) authnResponse.message, ""); - s_logger.Error("Authentication failed", e); + logger.Error("Authentication failed", e); throw e; } } @@ -193,12 +193,12 @@ internal SFSession( } catch (SnowflakeDbException e) { - s_logger.Error("Unable to initialize session ", e); + logger.Error("Unable to initialize session ", e); throw; } catch (Exception e) { - s_logger.Error("Unable to initialize session ", e); + logger.Error("Unable to initialize session ", e); throw new SnowflakeDbException(e, SnowflakeDbException.CONNECTION_FAILURE_SSTATE, SFError.INVALID_CONNECTION_STRING, @@ -251,7 +251,7 @@ internal Uri BuildUri(string path, Dictionary queryParams = null internal virtual void Open() { - s_logger.Debug("Open Session"); + logger.Debug("Open Session"); if (authenticator == null) { @@ -263,7 +263,7 @@ internal virtual void Open() internal virtual async Task OpenAsync(CancellationToken cancellationToken) { - s_logger.Debug("Open Session Async"); + logger.Debug("Open Session Async"); if (authenticator == null) { @@ -277,7 +277,7 @@ internal void close() { // Nothing to do if the session is not open if (!IsEstablished()) return; - s_logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); PostCloseSession(closeSessionRequest, restRequester); @@ -288,7 +288,7 @@ internal void CloseNonBlocking() { // Nothing to do if the session is not open if (!IsEstablished()) return; - s_logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); Task.Run(() => PostCloseSession(closeSessionRequest, restRequester)); @@ -299,19 +299,19 @@ internal async Task CloseAsync(CancellationToken cancellationToken) { // Nothing to do if the session is not open if (!IsEstablished()) return; - s_logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); + logger.Debug($"Closing session with id: {sessionId}, user: {_user}, database: {database}, schema: {schema}, role: {role}, warehouse: {warehouse}, connection start timestamp: {_startTime}"); stopHeartBeatForThisSession(); var closeSessionRequest = PrepareCloseSessionRequest(); - s_logger.Debug($"Closing session async"); + logger.Debug($"Closing session async"); var response = await restRequester.PostAsync(closeSessionRequest, cancellationToken).ConfigureAwait(false); if (!response.success) { - s_logger.Error($"Failed to close session {sessionId}, error ignored. Code: {response.code} Message: {response.message}"); + logger.Error($"Failed to close session {sessionId}, error ignored. Code: {response.code} Message: {response.message}"); } - s_logger.Debug($"Session closed: {sessionId}"); + logger.Debug($"Session closed: {sessionId}"); sessionToken = null; } @@ -319,18 +319,18 @@ private static void PostCloseSession(SFRestRequest closeSessionRequest, IRestReq { try { - s_logger.Debug($"Closing session"); + logger.Debug($"Closing session"); var response = restRequester.Post(closeSessionRequest); if (!response.success) { - s_logger.Error($"Failed to close session: {closeSessionRequest.sid}, error ignored. Code: {response.code} Message: {response.message}"); + logger.Error($"Failed to close session: {closeSessionRequest.sid}, error ignored. Code: {response.code} Message: {response.message}"); } - s_logger.Debug($"Session closed: {closeSessionRequest.sid}"); + logger.Debug($"Session closed: {closeSessionRequest.sid}"); } catch (Exception) { - s_logger.Error($"Failed to close session: {closeSessionRequest.sid}, because of exception."); + logger.Error($"Failed to close session: {closeSessionRequest.sid}, because of exception."); throw; } } @@ -354,13 +354,13 @@ private SFRestRequest PrepareCloseSessionRequest() internal void renewSession() { - s_logger.Info("Renew the session."); + logger.Info("Renew the session."); var response = restRequester.Post(getRenewSessionRequest()); if (!response.success) { SnowflakeDbException e = new SnowflakeDbException("", response.code, response.message, sessionId); - s_logger.Error($"Renew session (ID: {sessionId}) failed", e); + logger.Error($"Renew session (ID: {sessionId}) failed", e); throw e; } else @@ -372,7 +372,7 @@ internal void renewSession() internal async Task renewSessionAsync(CancellationToken cancellationToken) { - s_logger.Info("Renew the session."); + logger.Info("Renew the session."); var response = await restRequester.PostAsync( getRenewSessionRequest(), @@ -382,7 +382,7 @@ await restRequester.PostAsync( { SnowflakeDbException e = new SnowflakeDbException("", response.code, response.message, sessionId); - s_logger.Error($"Renew session (ID: {sessionId}) failed", e); + logger.Error($"Renew session (ID: {sessionId}) failed", e); throw e; } else @@ -430,7 +430,7 @@ internal SFRestRequest BuildTimeoutRestRequest(Uri uri, Object body) internal void UpdateSessionParameterMap(List parameterList) { - s_logger.Debug("Update parameter map"); + logger.Debug("Update parameter map"); // with HTAP parameter removal parameters might not returned // query response if (parameterList is null) @@ -578,7 +578,7 @@ public void SetArrayBindStageThreshold(int arrayBindStageThreshold) internal void heartbeat() { - s_logger.Debug("heartbeat"); + logger.Debug("heartbeat"); bool retry = false; if (IsEstablished()) @@ -599,16 +599,16 @@ internal void heartbeat() }; var response = restRequester.Post(heartBeatSessionRequest); - s_logger.Debug("heartbeat response=" + response); + logger.Debug("heartbeat response=" + response); if (response.success) { - s_logger.Debug("SFSession::heartbeat success, session token did not expire."); + logger.Debug("SFSession::heartbeat success, session token did not expire."); } else { if (response.code == SF_SESSION_EXPIRED_CODE) { - s_logger.Debug($"SFSession ::heartbeat Session ID: {sessionId} session token expired and retry heartbeat"); + logger.Debug($"SFSession ::heartbeat Session ID: {sessionId} session token expired and retry heartbeat"); try { renewSession(); @@ -621,12 +621,12 @@ internal void heartbeat() // the heart beat, it's possible that the session get // closed when sending renew request and caused exception // thrown from renewSession(), simply ignore that - s_logger.Error($"renew session (ID: {sessionId}) failed.", ex); + logger.Error($"renew session (ID: {sessionId}) failed.", ex); } } else { - s_logger.Error($"heartbeat failed for session ID: {sessionId}."); + logger.Error($"heartbeat failed for session ID: {sessionId}."); } } retry = false; diff --git a/Snowflake.Data/Core/Session/SFSessionProperty.cs b/Snowflake.Data/Core/Session/SFSessionProperty.cs index f0d09188b..07896ae14 100644 --- a/Snowflake.Data/Core/Session/SFSessionProperty.cs +++ b/Snowflake.Data/Core/Session/SFSessionProperty.cs @@ -126,7 +126,7 @@ class SFSessionPropertyAttr : Attribute class SFSessionProperties : Dictionary { - private static SFLogger s_logger = SFLoggerFactory.GetLogger(); + private static SFLogger logger = SFLoggerFactory.GetLogger(); internal string ConnectionStringWithoutSecrets { get; set; } @@ -171,7 +171,7 @@ public override bool Equals(object obj) } catch (InvalidCastException) { - s_logger.Warn("Invalid casting to SFSessionProperties"); + logger.Warn("Invalid casting to SFSessionProperties"); return false; } } @@ -183,7 +183,7 @@ public override int GetHashCode() internal static SFSessionProperties ParseConnectionString(string connectionString, SecureString password) { - s_logger.Info("Start parsing connection string."); + logger.Info("Start parsing connection string."); var builder = new DbConnectionStringBuilder(); try { @@ -191,7 +191,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin } catch (ArgumentException e) { - s_logger.Warn("Invalid connectionString", e); + logger.Warn("Invalid connectionString", e); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_STRING, e.Message); @@ -215,7 +215,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin } catch (ArgumentException) { - s_logger.Debug($"Property {keys[i]} not found ignored."); + logger.Debug($"Property {keys[i]} not found ignored."); } } @@ -231,7 +231,7 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin catch (Exception e) { // The useProxy setting is not a valid boolean value - s_logger.Error("Unable to connect", e); + logger.Error("Unable to connect", e); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_STRING, e.Message); @@ -273,15 +273,15 @@ internal static SFSessionProperties ParseConnectionString(string connectionStrin if (!allowUnderscoresInHost && compliantAccountName.Contains('_')) { compliantAccountName = compliantAccountName.Replace('_', '-'); - s_logger.Info($"Replacing _ with - in the account name. Old: {properties[SFSessionProperty.ACCOUNT]}, new: {compliantAccountName}."); + logger.Info($"Replacing _ with - in the account name. Old: {properties[SFSessionProperty.ACCOUNT]}, new: {compliantAccountName}."); } var hostName = $"{compliantAccountName}.snowflakecomputing.com"; // Remove in case it's here but empty properties.Remove(SFSessionProperty.HOST); properties.Add(SFSessionProperty.HOST, hostName); - s_logger.Info($"Compose host name: {hostName}"); + logger.Info($"Compose host name: {hostName}"); } - s_logger.Info(ResolveConnectionAreaMessage(properties[SFSessionProperty.HOST])); + logger.Info(ResolveConnectionAreaMessage(properties[SFSessionProperty.HOST])); // Trim the account name to remove the region and cloud platform if any were provided // because the login request data does not expect region and cloud information to be @@ -312,7 +312,7 @@ private static void ValidateAuthenticator(SFSessionProperties properties) if (!knownAuthenticators.Contains(authenticator) && !(authenticator.Contains(OktaAuthenticator.AUTH_NAME) && authenticator.StartsWith("https://"))) { var error = $"Unknown authenticator: {authenticator}"; - s_logger.Error(error); + logger.Error(error); throw new SnowflakeDbException(SFError.UNKNOWN_AUTHENTICATOR, authenticator); } } @@ -405,7 +405,7 @@ private static void ValidateAccountDomain(SFSessionProperties properties) return; if (IsAccountRegexMatched(account)) return; - s_logger.Error($"Invalid account {account}"); + logger.Error($"Invalid account {account}"); throw new SnowflakeDbException( new Exception("Invalid account"), SFError.INVALID_CONNECTION_PARAMETER_VALUE, @@ -427,14 +427,14 @@ private static void CheckSessionProperties(SFSessionProperties properties) !properties.ContainsKey(sessionProperty)) { SnowflakeDbException e = new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY, sessionProperty); - s_logger.Error("Missing connection property", e); + logger.Error("Missing connection property", e); throw e; } if (IsRequired(sessionProperty, properties) && string.IsNullOrEmpty(properties[sessionProperty])) { SnowflakeDbException e = new SnowflakeDbException(SFError.MISSING_CONNECTION_PROPERTY, sessionProperty); - s_logger.Error("Empty connection property", e); + logger.Error("Empty connection property", e); throw e; } @@ -442,7 +442,7 @@ private static void CheckSessionProperties(SFSessionProperties properties) string defaultVal = sessionProperty.GetAttribute().defaultValue; if (defaultVal != null && !properties.ContainsKey(sessionProperty)) { - s_logger.Debug($"Session property {sessionProperty} set to default value: {defaultVal}"); + logger.Debug($"Session property {sessionProperty} set to default value: {defaultVal}"); properties.Add(sessionProperty, defaultVal); } } @@ -463,13 +463,13 @@ private static void ValidateFileTransferMaxBytesInMemoryProperty(SFSessionProper } catch (Exception e) { - s_logger.Error($"Value for parameter {propertyName} could not be parsed"); + logger.Error($"Value for parameter {propertyName} could not be parsed"); throw new SnowflakeDbException(e, SFError.INVALID_CONNECTION_PARAMETER_VALUE, maxBytesInMemoryString, propertyName); } if (maxBytesInMemory <= 0) { - s_logger.Error($"Value for parameter {propertyName} should be greater than 0"); + logger.Error($"Value for parameter {propertyName} should be greater than 0"); throw new SnowflakeDbException( new Exception($"Value for parameter {propertyName} should be greater than 0"), SFError.INVALID_CONNECTION_PARAMETER_VALUE, maxBytesInMemoryString, propertyName); @@ -529,7 +529,7 @@ private static bool ParseAllowUnderscoresInHost(SFSessionProperties properties) } catch (Exception e) { - s_logger.Warn("Unable to parse property 'allowUnderscoresInHost'", e); + logger.Warn("Unable to parse property 'allowUnderscoresInHost'", e); } return allowUnderscoresInHost; diff --git a/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs b/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs index 05e3c4253..a39a0987c 100644 --- a/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs +++ b/Snowflake.Data/Core/Tools/HomeDirectoryProvider.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2024 Snowflake Computing Inc. All rights reserved. */ From c4d358a0acdc603e310589c2bf023a853dc070c2 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 17:00:51 -0800 Subject: [PATCH 29/35] Revert BOM --- Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs | 2 +- Snowflake.Data/Core/HttpUtil.cs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs b/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs index a5c0cd57e..c6d8f0698 100644 --- a/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs +++ b/Snowflake.Data.Tests/Mock/MockSnowflakeDbConnection.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 Snowflake Computing Inc. All rights reserved. */ diff --git a/Snowflake.Data/Core/HttpUtil.cs b/Snowflake.Data/Core/HttpUtil.cs index 63cb1b531..fa52348e8 100644 --- a/Snowflake.Data/Core/HttpUtil.cs +++ b/Snowflake.Data/Core/HttpUtil.cs @@ -406,8 +406,7 @@ protected override async Task SendAsync(HttpRequestMessage } else if (childCts != null && childCts.Token.IsCancellationRequested) { - logger.Warn("Http request timeout. Retry the request"); - totalRetryTime += (int)httpTimeout.TotalSeconds; + logger.Warn($"Http request timeout. Retry the request after max {backOffInSec} sec."); } else { From b9e74da4fac71dca704993e923e2c31656f57b5d Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 17:18:44 -0800 Subject: [PATCH 30/35] Revert to original --- Snowflake.Data/Core/ArrowResultSet.cs | 2 +- Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs | 2 +- Snowflake.Data/Core/FastParser.cs | 2 +- Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs | 2 +- Snowflake.Data/Core/HttpUtil.cs | 1 - Snowflake.Data/Core/QueryContextCache.cs | 2 +- Snowflake.Data/Core/SFBindUploader.cs | 2 +- 7 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Snowflake.Data/Core/ArrowResultSet.cs b/Snowflake.Data/Core/ArrowResultSet.cs index e27246a0b..178531eaf 100644 --- a/Snowflake.Data/Core/ArrowResultSet.cs +++ b/Snowflake.Data/Core/ArrowResultSet.cs @@ -18,7 +18,7 @@ class ArrowResultSet : SFBaseResultSet internal override ResultFormat ResultFormat => ResultFormat.ARROW; private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger(); - + private readonly int _totalChunkCount; private BaseResultChunk _currentChunk; private readonly IChunkDownloader _chunkDownloader; diff --git a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs index 52cd2ab96..f36d0353e 100644 --- a/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs +++ b/Snowflake.Data/Core/Authenticator/OAuthAuthenticator.cs @@ -1,4 +1,4 @@ -using Snowflake.Data.Log; +using Snowflake.Data.Log; using System; using System.Collections.Generic; using System.Text; diff --git a/Snowflake.Data/Core/FastParser.cs b/Snowflake.Data/Core/FastParser.cs index 632876269..bb06f1eaf 100644 --- a/Snowflake.Data/Core/FastParser.cs +++ b/Snowflake.Data/Core/FastParser.cs @@ -1,4 +1,4 @@ -using System; +using System; using Snowflake.Data.Client; using Snowflake.Data.Log; diff --git a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs index 1a86b15a9..e5d0ac139 100644 --- a/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs +++ b/Snowflake.Data/Core/FileTransfer/StorageClient/SFGCSClient.cs @@ -476,7 +476,7 @@ private void HandleDownloadResponse(HttpWebResponse response, SFFileMetadata fil private SFFileMetadata HandleFileHeaderErrForPresignedUrls(WebException ex, SFFileMetadata fileMetadata) { Logger.Error("Failed to get file header for presigned url: " + ex.Message); - + HttpWebResponse response = (HttpWebResponse)ex.Response; if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.Forbidden || diff --git a/Snowflake.Data/Core/HttpUtil.cs b/Snowflake.Data/Core/HttpUtil.cs index fa52348e8..6f6145189 100644 --- a/Snowflake.Data/Core/HttpUtil.cs +++ b/Snowflake.Data/Core/HttpUtil.cs @@ -600,4 +600,3 @@ static internal bool IsOktaSSORequest(string host, string endpoint) } } - diff --git a/Snowflake.Data/Core/QueryContextCache.cs b/Snowflake.Data/Core/QueryContextCache.cs index 76f8bb825..74d041d2b 100644 --- a/Snowflake.Data/Core/QueryContextCache.cs +++ b/Snowflake.Data/Core/QueryContextCache.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Newtonsoft.Json; using System.Linq; diff --git a/Snowflake.Data/Core/SFBindUploader.cs b/Snowflake.Data/Core/SFBindUploader.cs index dfc98c1bf..400c3b0c9 100644 --- a/Snowflake.Data/Core/SFBindUploader.cs +++ b/Snowflake.Data/Core/SFBindUploader.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; From 956249ef06dea2fb31720487bdd3973b51705219 Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 6 Dec 2024 17:20:10 -0800 Subject: [PATCH 31/35] Revert eof --- Snowflake.Data/Core/HttpUtil.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Snowflake.Data/Core/HttpUtil.cs b/Snowflake.Data/Core/HttpUtil.cs index 6f6145189..fa52348e8 100644 --- a/Snowflake.Data/Core/HttpUtil.cs +++ b/Snowflake.Data/Core/HttpUtil.cs @@ -600,3 +600,4 @@ static internal bool IsOktaSSORequest(string host, string endpoint) } } + From 294f99212ba941f9cfc35fa44b06cd6aaa39dbeb Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Wed, 15 Jan 2025 14:00:21 -0800 Subject: [PATCH 32/35] Add FormatBrackets for all log types --- Snowflake.Data/Logger/SFLoggerPair.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Snowflake.Data/Logger/SFLoggerPair.cs b/Snowflake.Data/Logger/SFLoggerPair.cs index 3aed30a52..c74f5c363 100644 --- a/Snowflake.Data/Logger/SFLoggerPair.cs +++ b/Snowflake.Data/Logger/SFLoggerPair.cs @@ -31,28 +31,28 @@ public void Info(string message, Exception ex = null) { message = SecretDetector.MaskSecrets(message).maskedText; s_snowflakeLogger.Info(message, ex); - s_customLogger.LogInformation(message, ex); + s_customLogger.LogInformation(FormatBrackets(message), ex); } public void Warn(string message, Exception ex = null) { message = SecretDetector.MaskSecrets(message).maskedText; s_snowflakeLogger.Warn(message, ex); - s_customLogger.LogWarning(message, ex); + s_customLogger.LogWarning(FormatBrackets(message), ex); } public void Error(string message, Exception ex = null) { message = SecretDetector.MaskSecrets(message).maskedText; s_snowflakeLogger.Error(message, ex); - s_customLogger.LogError(message, ex); + s_customLogger.LogError(FormatBrackets(message), ex); } public void Fatal(string message, Exception ex = null) { message = SecretDetector.MaskSecrets(message).maskedText; s_snowflakeLogger.Fatal(message, ex); - s_customLogger.LogCritical(message, ex); + s_customLogger.LogCritical(FormatBrackets(message), ex); } public bool IsDebugEnabled() From 588c1ee3a9e63e1ca05fb67b7eb0d26fb398db5a Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Wed, 15 Jan 2025 15:07:48 -0800 Subject: [PATCH 33/35] Disable SF logger by default --- .../UnitTests/Logger/SFLoggerPairTest.cs | 8 ++++---- .../UnitTests/Logger/SFLoggerTest.cs | 10 +++++----- Snowflake.Data/Logger/SFLoggerFactory.cs | 18 ++++++++++++------ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerPairTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerPairTest.cs index f577a640e..8555b0fcd 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerPairTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerPairTest.cs @@ -38,13 +38,13 @@ public void BeforeTest() public void AfterTest() { // Return to default setting - SFLoggerFactory.EnableSFLogger(); + SFLoggerFactory.UseDefaultSFLogger(); } [Test] public void TestUsingSFLogger() { - SFLoggerFactory.EnableSFLogger(); + SFLoggerFactory.UseDefaultSFLogger(); _loggerPair = SFLoggerFactory.GetLogger(); Assert.IsInstanceOf(_loggerPair); } @@ -127,11 +127,11 @@ private SFLogger GetLogger(bool isEnabled) { if (isEnabled) { - SFLoggerFactory.EnableSFLogger(); + SFLoggerFactory.UseDefaultSFLogger(); } else { - SFLoggerFactory.DisableSFLogger(); + SFLoggerFactory.UseEmptySFLogger(); } return SFLoggerFactory.GetLogger(); diff --git a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs index 9910484e1..f0a2da54a 100644 --- a/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Logger/SFLoggerTest.cs @@ -32,13 +32,13 @@ public static void AfterAll() public void AfterTest() { // Return to default setting - SFLoggerFactory.EnableSFLogger(); + SFLoggerFactory.UseDefaultSFLogger(); } [Test] public void TestUsingSFLogger() { - SFLoggerFactory.EnableSFLogger(); + SFLoggerFactory.UseDefaultSFLogger(); _logger = SFLoggerFactory.GetSFLogger(); Assert.IsInstanceOf(_logger); } @@ -46,7 +46,7 @@ public void TestUsingSFLogger() [Test] public void TestUsingEmptyLogger() { - SFLoggerFactory.DisableSFLogger(); + SFLoggerFactory.UseEmptySFLogger(); _logger = SFLoggerFactory.GetSFLogger(); Assert.IsInstanceOf(_logger); } @@ -173,11 +173,11 @@ private SFLogger GetLogger(bool isEnabled) { if (isEnabled) { - SFLoggerFactory.EnableSFLogger(); + SFLoggerFactory.UseDefaultSFLogger(); } else { - SFLoggerFactory.DisableSFLogger(); + SFLoggerFactory.UseEmptySFLogger(); } return SFLoggerFactory.GetSFLogger(false); diff --git a/Snowflake.Data/Logger/SFLoggerFactory.cs b/Snowflake.Data/Logger/SFLoggerFactory.cs index 8dfb277d7..fa4300996 100755 --- a/Snowflake.Data/Logger/SFLoggerFactory.cs +++ b/Snowflake.Data/Logger/SFLoggerFactory.cs @@ -11,18 +11,20 @@ public class SFLoggerFactory { private static bool s_isCustomLoggerEnabled = false; - private static bool s_isSFLoggerEnabled = true; + private static bool s_isSFLoggerEnabled = false; + + private static bool s_useDefaultSFLogger = true; private static ILogger s_customLogger = null; - public static void DisableSFLogger() + public static void UseEmptySFLogger() { - s_isSFLoggerEnabled = false; + s_useDefaultSFLogger = false; } - public static void EnableSFLogger() + public static void UseDefaultSFLogger() { - s_isSFLoggerEnabled = true; + s_useDefaultSFLogger = true; } public static void DisableCustomLogger() @@ -53,9 +55,13 @@ internal static SFLogger GetLogger() internal static SFLogger GetSFLogger(bool useFileAppender = true) { // If true, return the default/specified logger - if (s_isSFLoggerEnabled) + if (s_useDefaultSFLogger) { var logger = new SFLoggerImpl(typeof(T)); + if (!s_isSFLoggerEnabled) + { + logger.SetLevel(LoggingEvent.OFF); // Logger is disabled by default and can be enabled by the EasyLogging feature + } if (useFileAppender) { var fileAppender = new SFRollingFileAppender() From 824cff9fe03e3633212693bfe86b8ca64708c4be Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Fri, 24 Jan 2025 09:33:04 -0800 Subject: [PATCH 34/35] Modify SetCustomLogger --- Snowflake.Data/Logger/SFLoggerFactory.cs | 1 + Snowflake.Data/Logger/SFLoggerPair.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Snowflake.Data/Logger/SFLoggerFactory.cs b/Snowflake.Data/Logger/SFLoggerFactory.cs index fa4300996..4e212ab7e 100755 --- a/Snowflake.Data/Logger/SFLoggerFactory.cs +++ b/Snowflake.Data/Logger/SFLoggerFactory.cs @@ -45,6 +45,7 @@ public static void UseDefaultLogger() public static void SetCustomLogger(ILogger customLogger) { s_customLogger = customLogger; + SFLoggerPair.s_customLogger = s_customLogger; } internal static SFLogger GetLogger() diff --git a/Snowflake.Data/Logger/SFLoggerPair.cs b/Snowflake.Data/Logger/SFLoggerPair.cs index c74f5c363..92b176e00 100644 --- a/Snowflake.Data/Logger/SFLoggerPair.cs +++ b/Snowflake.Data/Logger/SFLoggerPair.cs @@ -12,7 +12,7 @@ namespace Snowflake.Data.Log public class SFLoggerPair : SFLogger { private static SFLogger s_snowflakeLogger; - private static ILogger s_customLogger; + internal static ILogger s_customLogger; public SFLoggerPair(SFLogger snowflakeLogger, ILogger customLogger) { From 4c0bfb7e47580ccddf038336a607e86b94184d3e Mon Sep 17 00:00:00 2001 From: Louie Farol Date: Wed, 29 Jan 2025 13:51:46 -0800 Subject: [PATCH 35/35] Retrigger checks