mirror of
https://github.com/bitwarden/server.git
synced 2026-01-24 10:53:10 +08:00
[PM-30858] Fix excessive logs (#6860)
* Add tests showing issue & workaround - `AddSerilogFileLogging_LegacyConfig_InfoLogs_DoNotFillUpFile` fails - `AddSerilogFileLogging_LegacyConfig_WithLevelCustomization_InfoLogs_DoNotFillUpFile` fails - `AddSerilogFileLogging_NewConfig_InfoLogs_DoNotFillUpFile` fails - `AddSerilogFileLogging_NewConfig_WithLevelCustomization_InfoLogs_DoNotFillUpFile` works * Allow customization of LogLevel with legacy path format config * Lower default logging levels * Delete tests now that log levels have been customized
This commit is contained in:
@@ -23,11 +23,9 @@
|
||||
}
|
||||
},
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
},
|
||||
"Console": {
|
||||
"IncludeScopes": true,
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
}
|
||||
},
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
},
|
||||
"Console": {
|
||||
"IncludeScopes": true,
|
||||
|
||||
@@ -23,11 +23,9 @@
|
||||
}
|
||||
},
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
},
|
||||
"Console": {
|
||||
"IncludeScopes": true,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -8,7 +9,7 @@ namespace Bit.Core.Utilities;
|
||||
public static class LoggerFactoryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="hostBuilder"></param>
|
||||
/// <returns></returns>
|
||||
@@ -21,10 +22,12 @@ public static class LoggerFactoryExtensions
|
||||
return;
|
||||
}
|
||||
|
||||
IConfiguration loggingConfiguration;
|
||||
|
||||
// If they have begun using the new settings location, use that
|
||||
if (!string.IsNullOrEmpty(context.Configuration["Logging:PathFormat"]))
|
||||
{
|
||||
logging.AddFile(context.Configuration.GetSection("Logging"));
|
||||
loggingConfiguration = context.Configuration.GetSection("Logging");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -40,28 +43,35 @@ public static class LoggerFactoryExtensions
|
||||
var projectName = loggingOptions.ProjectName
|
||||
?? context.HostingEnvironment.ApplicationName;
|
||||
|
||||
string pathFormat;
|
||||
|
||||
if (loggingOptions.LogRollBySizeLimit.HasValue)
|
||||
{
|
||||
var pathFormat = loggingOptions.LogDirectoryByProject
|
||||
pathFormat = loggingOptions.LogDirectoryByProject
|
||||
? Path.Combine(loggingOptions.LogDirectory, projectName, "log.txt")
|
||||
: Path.Combine(loggingOptions.LogDirectory, $"{projectName.ToLowerInvariant()}.log");
|
||||
|
||||
logging.AddFile(
|
||||
pathFormat: pathFormat,
|
||||
fileSizeLimitBytes: loggingOptions.LogRollBySizeLimit.Value
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
var pathFormat = loggingOptions.LogDirectoryByProject
|
||||
pathFormat = loggingOptions.LogDirectoryByProject
|
||||
? Path.Combine(loggingOptions.LogDirectory, projectName, "{Date}.txt")
|
||||
: Path.Combine(loggingOptions.LogDirectory, $"{projectName.ToLowerInvariant()}_{{Date}}.log");
|
||||
|
||||
logging.AddFile(
|
||||
pathFormat: pathFormat
|
||||
);
|
||||
}
|
||||
|
||||
// We want to rely on Serilog using the configuration section to have customization of the log levels
|
||||
// so we make a custom configuration source for them based on the legacy values and allow overrides from
|
||||
// the new location.
|
||||
loggingConfiguration = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
{"PathFormat", pathFormat},
|
||||
{"FileSizeLimitBytes", loggingOptions.LogRollBySizeLimit?.ToString(CultureInfo.InvariantCulture)}
|
||||
})
|
||||
.AddConfiguration(context.Configuration.GetSection("Logging"))
|
||||
.Build();
|
||||
}
|
||||
|
||||
logging.AddFile(loggingConfiguration);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,9 @@
|
||||
}
|
||||
},
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
},
|
||||
"Console": {
|
||||
"IncludeScopes": true,
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
},
|
||||
"Console": {
|
||||
"IncludeScopes": true,
|
||||
|
||||
@@ -17,11 +17,9 @@
|
||||
}
|
||||
},
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
},
|
||||
"Console": {
|
||||
"IncludeScopes": true,
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
}
|
||||
},
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
},
|
||||
"Console": {
|
||||
"IncludeScopes": true,
|
||||
|
||||
@@ -17,11 +17,9 @@
|
||||
}
|
||||
},
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning"
|
||||
},
|
||||
"Console": {
|
||||
"IncludeScopes": true,
|
||||
|
||||
@@ -74,8 +74,7 @@ public class LoggerFactoryExtensionsTests
|
||||
|
||||
logger.LogWarning("This is a test");
|
||||
|
||||
// Writing to the file is buffered, give it a little time to flush
|
||||
await Task.Delay(5);
|
||||
await provider.DisposeAsync();
|
||||
|
||||
var logFile = Assert.Single(tempDir.EnumerateFiles("Logs/*.log"));
|
||||
|
||||
@@ -90,13 +89,67 @@ public class LoggerFactoryExtensionsTests
|
||||
logFileContents
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AddSerilogFileLogging_LegacyConfig_WithLevelCustomization_InfoLogs_DoNotFillUpFile()
|
||||
{
|
||||
await AssertSmallFileAsync((tempDir, config) =>
|
||||
{
|
||||
config["GlobalSettings:LogDirectory"] = tempDir;
|
||||
config["Logging:LogLevel:Microsoft.AspNetCore"] = "Warning";
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AddSerilogFileLogging_NewConfig_WithLevelCustomization_InfoLogs_DoNotFillUpFile()
|
||||
{
|
||||
await AssertSmallFileAsync((tempDir, config) =>
|
||||
{
|
||||
config["Logging:PathFormat"] = Path.Combine(tempDir, "log.txt");
|
||||
config["Logging:LogLevel:Microsoft.AspNetCore"] = "Warning";
|
||||
});
|
||||
}
|
||||
|
||||
private static async Task AssertSmallFileAsync(Action<string, Dictionary<string, string?>> configure)
|
||||
{
|
||||
using var tempDir = new TempDirectory();
|
||||
var config = new Dictionary<string, string?>();
|
||||
|
||||
configure(tempDir.Directory, config);
|
||||
|
||||
var provider = GetServiceProvider(config, "Production");
|
||||
|
||||
var loggerFactory = provider.GetRequiredService<ILoggerFactory>();
|
||||
var microsoftLogger = loggerFactory.CreateLogger("Microsoft.AspNetCore.Testing");
|
||||
|
||||
for (var i = 0; i < 100; i++)
|
||||
{
|
||||
microsoftLogger.LogInformation("Tons of useless information");
|
||||
}
|
||||
|
||||
var otherLogger = loggerFactory.CreateLogger("Bitwarden");
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
otherLogger.LogInformation("Mildly more useful information but not as frequent.");
|
||||
}
|
||||
|
||||
await provider.DisposeAsync();
|
||||
|
||||
var logFiles = Directory.EnumerateFiles(tempDir.Directory, "*.txt", SearchOption.AllDirectories);
|
||||
var logFile = Assert.Single(logFiles);
|
||||
|
||||
using var fr = File.OpenRead(logFile);
|
||||
Assert.InRange(fr.Length, 0, 1024);
|
||||
}
|
||||
|
||||
private static IEnumerable<ILoggerProvider> GetProviders(Dictionary<string, string?> initialData, string environment = "Production")
|
||||
{
|
||||
var provider = GetServiceProvider(initialData, environment);
|
||||
return provider.GetServices<ILoggerProvider>();
|
||||
}
|
||||
|
||||
private static IServiceProvider GetServiceProvider(Dictionary<string, string?> initialData, string environment)
|
||||
private static ServiceProvider GetServiceProvider(Dictionary<string, string?> initialData, string environment)
|
||||
{
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(initialData)
|
||||
|
||||
Reference in New Issue
Block a user