Skip to content

Commit

Permalink
SNOW-1899127 Fix possibility to configure easy logging log_path as ST…
Browse files Browse the repository at this point in the history
…DOUT (#1087)

Co-authored-by: Eric Finch <[email protected]>
  • Loading branch information
sfc-gh-knozderko and Coder3333 authored Jan 29, 2025
1 parent 4167b76 commit cab672d
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 24 deletions.
56 changes: 40 additions & 16 deletions Snowflake.Data.Tests/UnitTests/Logger/EasyLoggingStarterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class EasyLoggingStarterTest
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
Expand All @@ -33,7 +33,7 @@ public class EasyLoggingStarterTest
LogPath = LogPath
}
};

private static readonly ClientConfig s_configWithInfoLevel = new ClientConfig
{
CommonProps = new ClientConfigCommonProps
Expand All @@ -51,12 +51,21 @@ public class EasyLoggingStarterTest
}
};

private static readonly ClientConfig s_configWithStdoutAsLogPath = new ClientConfig
{
CommonProps = new ClientConfigCommonProps
{
LogLevel = "Info",
LogPath = "STDOUT"
}
};

[ThreadStatic]
private static Mock<EasyLoggingConfigProvider> t_easyLoggingProvider;

[ThreadStatic]
private static Mock<EasyLoggerManager> t_easyLoggerManager;

[ThreadStatic]
private static Mock<UnixOperations> t_unixOperations;

Expand All @@ -68,7 +77,7 @@ public class EasyLoggingStarterTest

[ThreadStatic]
private static EasyLoggingStarter t_easyLoggerStarter;

[SetUp]
public void BeforeEach()
{
Expand Down Expand Up @@ -158,7 +167,7 @@ public void TestFailIfDirectoryCreationFails()
{
Assert.Ignore("skip test on Windows");
}

// arrange
t_easyLoggingProvider
.Setup(provider => provider.ProvideConfig(ConfigPath))
Expand All @@ -169,7 +178,7 @@ public void TestFailIfDirectoryCreationFails()

// act
var thrown = Assert.Throws<Exception>(() => t_easyLoggerStarter.Init(ConfigPath));

// assert
Assert.That(thrown.Message, Does.Contain("Failed to create logs directory"));
}
Expand All @@ -187,10 +196,10 @@ public void TestThatConfiguresEasyLoggingOnlyOnceWhenInitializedWithConfigPath()
t_easyLoggingProvider
.Setup(provider => provider.ProvideConfig(AnotherConfigPath))
.Returns(s_configWithInfoLevel);

// act
t_easyLoggerStarter.Init(ConfigPath);

// assert
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Expand All @@ -202,24 +211,24 @@ public void TestThatConfiguresEasyLoggingOnlyOnceWhenInitializedWithConfigPath()
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);
Expand Down Expand Up @@ -247,10 +256,10 @@ public void TestThatReconfiguresEasyLoggingWithConfigPathIfNotGivenForTheFirstTi
t_easyLoggingProvider
.Setup(provider => provider.ProvideConfig(ConfigPath))
.Returns(s_configWithInfoLevel);

// act
t_easyLoggerStarter.Init(null);

// assert
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Expand All @@ -265,10 +274,25 @@ public void TestThatReconfiguresEasyLoggingWithConfigPathIfNotGivenForTheFirstTi

// act
t_easyLoggerStarter.Init(ConfigPath);

// assert
t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Info, s_expectedLogPath), Times.Once);
t_easyLoggerManager.VerifyNoOtherCalls();
}

[Test]
public void TestConfigureStdout()
{
// arrange
t_easyLoggingProvider
.Setup(provider => provider.ProvideConfig(null))
.Returns(s_configWithStdoutAsLogPath);

// act
t_easyLoggerStarter.Init(null);

// assert
t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Info, "STDOUT"), Times.Once);
}
}
}
14 changes: 9 additions & 5 deletions Snowflake.Data/Core/Session/EasyLoggingStarter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Snowflake.Data.Core
internal class EasyLoggingStarter
{
private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger<EasyLoggingStarter>();

private readonly EasyLoggingConfigProvider _easyLoggingConfigProvider;

private readonly EasyLoggerManager _easyLoggerManager;
Expand All @@ -28,12 +28,12 @@ internal class EasyLoggingStarter
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,
Expand Down Expand Up @@ -91,7 +91,7 @@ internal void Reset(EasyLoggingLogLevel logLevel)
_easyLoggerManager.ResetEasyLogging(logLevel);
}
}

private bool AllowedToInitialize(string configFilePathFromConnectionString)
{
var everTriedToInitialize = _initTrialParameters != null;
Expand Down Expand Up @@ -128,6 +128,10 @@ private string GetLogPath(string logPath)
throw new Exception("No log path found for easy logging. Home directory is not configured and log path is not provided");
}
}
if (EasyLoggerManager.IsStdout(logPath))
{
return logPath;
}
var pathWithDotnetSubdirectory = Path.Combine(logPathOrDefault, "dotnet");
if (!_directoryOperations.Exists(pathWithDotnetSubdirectory))
{
Expand Down Expand Up @@ -184,7 +188,7 @@ public bool IsConfigFilePathGiven()
{
return _configFilePathFromConnectionString != null;
}

public bool HasDifferentConfigPath(string configFilePath)
{
return IsConfigFilePathGiven()
Expand Down
11 changes: 8 additions & 3 deletions Snowflake.Data/Logger/EasyLoggerManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal class EasyLoggerManager
private const string AppenderPrefix = "SFEasyLogging";

private readonly EasyLoggingLevelMapper _levelMapper = EasyLoggingLevelMapper.Instance;

public virtual void ReconfigureEasyLogging(EasyLoggingLogLevel easyLoggingLogLevel, string logsPath)
{
var log4netLevel = _levelMapper.ToLog4NetLevel(easyLoggingLogLevel);
Expand All @@ -30,14 +30,19 @@ public virtual void ReconfigureEasyLogging(EasyLoggingLogLevel easyLoggingLogLev
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)
var appender = IsStdout(logsPath)
? AddConsoleAppender(rootLogger)
: AddRollingFileAppender(rootLogger, logsPath);
RemoveOtherEasyLoggingAppenders(rootLogger, appender);
repository.RaiseConfigurationChanged(EventArgs.Empty);
}
}

internal static bool IsStdout(string logsPath)
{
return string.Equals(logsPath, "STDOUT", StringComparison.OrdinalIgnoreCase);
}

internal void ResetEasyLogging(EasyLoggingLogLevel easyLoggingLogLevel)
{
var log4netLevel = _levelMapper.ToLog4NetLevel(easyLoggingLogLevel);
Expand All @@ -57,7 +62,7 @@ internal static bool HasEasyLoggingAppender()
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();
Expand Down

0 comments on commit cab672d

Please sign in to comment.