From 62705917ab2391d2f9805c3616087204207f761c Mon Sep 17 00:00:00 2001
From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com>
Date: Fri, 21 Nov 2025 11:12:33 -0600
Subject: [PATCH 1/5] Remove unreferenced FF (#6612)
---
src/Core/Constants.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs
index c4f8f6458e..b0669091b9 100644
--- a/src/Core/Constants.cs
+++ b/src/Core/Constants.cs
@@ -186,7 +186,6 @@ public static class FeatureFlagKeys
/* Billing Team */
public const string TrialPayment = "PM-8163-trial-payment";
- public const string PM19422_AllowAutomaticTaxUpdates = "pm-19422-allow-automatic-tax-updates";
public const string PM21821_ProviderPortalTakeover = "pm-21821-provider-portal-takeover";
public const string PM22415_TaxIDWarnings = "pm-22415-tax-id-warnings";
public const string PM25379_UseNewOrganizationMetadataStructure = "pm-25379-use-new-organization-metadata-structure";
From 042279682aaf843e1c5e57342a37775915e6dfa2 Mon Sep 17 00:00:00 2001
From: rr-bw <102181210+rr-bw@users.noreply.github.com>
Date: Fri, 21 Nov 2025 09:38:59 -0800
Subject: [PATCH 2/5] feat(marketing-initiated-premium): (Auth) [PM-27540] Add
optional Marketing Property to RegisterSendVerificationEmailRequestModel
(#6598)
Adds an optional `FromMarketing` property to the RegisterSendVerificationEmailRequestModel.
---
.../MarketingInitiativeValidationAttribute.cs | 29 ++++++++
.../Accounts/MarketingInitiativeConstants.cs | 10 +++
...gisterSendVerificationEmailRequestModel.cs | 3 +
...etingInitiativeValidationAttributeTests.cs | 70 +++++++++++++++++++
...rketingInitiativeConstantsSnapshotTests.cs | 18 +++++
5 files changed, 130 insertions(+)
create mode 100644 src/Core/Auth/Attributes/MarketingInitiativeValidationAttribute.cs
create mode 100644 src/Core/Auth/Models/Api/Request/Accounts/MarketingInitiativeConstants.cs
create mode 100644 test/Core.Test/Auth/Attributes/MarketingInitiativeValidationAttributeTests.cs
create mode 100644 test/Core.Test/Auth/Models/Api/Request/Accounts/MarketingInitiativeConstantsSnapshotTests.cs
diff --git a/src/Core/Auth/Attributes/MarketingInitiativeValidationAttribute.cs b/src/Core/Auth/Attributes/MarketingInitiativeValidationAttribute.cs
new file mode 100644
index 0000000000..bcc4b851c0
--- /dev/null
+++ b/src/Core/Auth/Attributes/MarketingInitiativeValidationAttribute.cs
@@ -0,0 +1,29 @@
+using System.ComponentModel.DataAnnotations;
+using Bit.Core.Auth.Models.Api.Request.Accounts;
+
+namespace Bit.Core.Auth.Attributes;
+
+public class MarketingInitiativeValidationAttribute : ValidationAttribute
+{
+ private static readonly string[] _acceptedValues = [MarketingInitiativeConstants.Premium];
+
+ public MarketingInitiativeValidationAttribute()
+ {
+ ErrorMessage = $"Marketing initiative type must be one of: {string.Join(", ", _acceptedValues)}";
+ }
+
+ public override bool IsValid(object? value)
+ {
+ if (value == null)
+ {
+ return true;
+ }
+
+ if (value is not string str)
+ {
+ return false;
+ }
+
+ return _acceptedValues.Contains(str);
+ }
+}
diff --git a/src/Core/Auth/Models/Api/Request/Accounts/MarketingInitiativeConstants.cs b/src/Core/Auth/Models/Api/Request/Accounts/MarketingInitiativeConstants.cs
new file mode 100644
index 0000000000..ab2d252dc8
--- /dev/null
+++ b/src/Core/Auth/Models/Api/Request/Accounts/MarketingInitiativeConstants.cs
@@ -0,0 +1,10 @@
+namespace Bit.Core.Auth.Models.Api.Request.Accounts;
+
+public static class MarketingInitiativeConstants
+{
+ ///
+ /// Indicates that the user began the registration process on a marketing page designed
+ /// to streamline users who intend to setup a premium subscription after registration.
+ ///
+ public const string Premium = "premium";
+}
diff --git a/src/Core/Auth/Models/Api/Request/Accounts/RegisterSendVerificationEmailRequestModel.cs b/src/Core/Auth/Models/Api/Request/Accounts/RegisterSendVerificationEmailRequestModel.cs
index 75a4da081a..638565ecfe 100644
--- a/src/Core/Auth/Models/Api/Request/Accounts/RegisterSendVerificationEmailRequestModel.cs
+++ b/src/Core/Auth/Models/Api/Request/Accounts/RegisterSendVerificationEmailRequestModel.cs
@@ -1,5 +1,6 @@
#nullable enable
using System.ComponentModel.DataAnnotations;
+using Bit.Core.Auth.Attributes;
using Bit.Core.Utilities;
namespace Bit.Core.Auth.Models.Api.Request.Accounts;
@@ -11,4 +12,6 @@ public class RegisterSendVerificationEmailRequestModel
[StringLength(256)]
public required string Email { get; set; }
public bool ReceiveMarketingEmails { get; set; }
+ [MarketingInitiativeValidation]
+ public string? FromMarketing { get; set; }
}
diff --git a/test/Core.Test/Auth/Attributes/MarketingInitiativeValidationAttributeTests.cs b/test/Core.Test/Auth/Attributes/MarketingInitiativeValidationAttributeTests.cs
new file mode 100644
index 0000000000..2b9b5cf194
--- /dev/null
+++ b/test/Core.Test/Auth/Attributes/MarketingInitiativeValidationAttributeTests.cs
@@ -0,0 +1,70 @@
+using Bit.Core.Auth.Attributes;
+using Bit.Core.Auth.Models.Api.Request.Accounts;
+using Xunit;
+
+namespace Bit.Core.Test.Auth.Attributes;
+
+public class MarketingInitiativeValidationAttributeTests
+{
+ [Fact]
+ public void IsValid_NullValue_ReturnsTrue()
+ {
+ var sut = new MarketingInitiativeValidationAttribute();
+
+ var actual = sut.IsValid(null);
+
+ Assert.True(actual);
+ }
+
+ [Theory]
+ [InlineData(MarketingInitiativeConstants.Premium)]
+ public void IsValid_AcceptedValue_ReturnsTrue(string value)
+ {
+ var sut = new MarketingInitiativeValidationAttribute();
+
+ var actual = sut.IsValid(value);
+
+ Assert.True(actual);
+ }
+
+ [Theory]
+ [InlineData("invalid")]
+ [InlineData("")]
+ [InlineData("Premium")] // case sensitive - capitalized
+ [InlineData("PREMIUM")] // case sensitive - uppercase
+ [InlineData("premium ")] // trailing space
+ [InlineData(" premium")] // leading space
+ public void IsValid_InvalidStringValue_ReturnsFalse(string value)
+ {
+ var sut = new MarketingInitiativeValidationAttribute();
+
+ var actual = sut.IsValid(value);
+
+ Assert.False(actual);
+ }
+
+ [Theory]
+ [InlineData(123)] // integer
+ [InlineData(true)] // boolean
+ [InlineData(45.67)] // double
+ public void IsValid_NonStringValue_ReturnsFalse(object value)
+ {
+ var sut = new MarketingInitiativeValidationAttribute();
+
+ var actual = sut.IsValid(value);
+
+ Assert.False(actual);
+ }
+
+ [Fact]
+ public void ErrorMessage_ContainsAcceptedValues()
+ {
+ var sut = new MarketingInitiativeValidationAttribute();
+
+ var errorMessage = sut.ErrorMessage;
+
+ Assert.NotNull(errorMessage);
+ Assert.Contains("premium", errorMessage);
+ Assert.Contains("Marketing initiative type must be one of:", errorMessage);
+ }
+}
diff --git a/test/Core.Test/Auth/Models/Api/Request/Accounts/MarketingInitiativeConstantsSnapshotTests.cs b/test/Core.Test/Auth/Models/Api/Request/Accounts/MarketingInitiativeConstantsSnapshotTests.cs
new file mode 100644
index 0000000000..b78e96e91e
--- /dev/null
+++ b/test/Core.Test/Auth/Models/Api/Request/Accounts/MarketingInitiativeConstantsSnapshotTests.cs
@@ -0,0 +1,18 @@
+using Bit.Core.Auth.Models.Api.Request.Accounts;
+using Xunit;
+
+namespace Bit.Core.Test.Auth.Models.Api.Request.Accounts;
+
+///
+/// Snapshot tests to ensure the string constants in do not change unintentionally.
+/// If you intentionally change any of these values, please update the tests to reflect the new expected values.
+///
+public class MarketingInitiativeConstantsSnapshotTests
+{
+ [Fact]
+ public void MarketingInitiativeConstants_HaveCorrectValues()
+ {
+ // Assert
+ Assert.Equal("premium", MarketingInitiativeConstants.Premium);
+ }
+}
From fdfec0ac4df89b33896aadf532e95404f01747c0 Mon Sep 17 00:00:00 2001
From: Justin Baur <19896123+justindbaur@users.noreply.github.com>
Date: Fri, 21 Nov 2025 14:39:26 -0500
Subject: [PATCH 3/5] Remove deprecated logging methods (#6516)
---
.github/renovate.json5 | 4 -
bitwarden_license/src/Scim/Program.cs | 15 +-
bitwarden_license/src/Scim/Startup.cs | 3 -
bitwarden_license/src/Scim/appsettings.json | 3 -
bitwarden_license/src/Sso/Program.cs | 14 +-
bitwarden_license/src/Sso/Startup.cs | 2 -
src/Admin/Program.cs | 13 +-
src/Admin/Startup.cs | 3 -
src/Api/Program.cs | 33 +--
src/Api/Startup.cs | 2 -
src/Api/appsettings.json | 3 -
src/Billing/Program.cs | 19 +-
src/Billing/Startup.cs | 7 +-
src/Billing/appsettings.json | 3 -
src/Core/Core.csproj | 4 -
src/Core/Settings/GlobalSettings.cs | 61 ------
src/Core/Settings/IGlobalSettings.cs | 1 -
src/Core/Settings/ILogLevelSettings.cs | 74 -------
.../LoggingSettings/AdminLogLevelSettings.cs | 8 -
.../LoggingSettings/ApiLogLevelSettings.cs | 10 -
.../BillingLogLevelSettings.cs | 9 -
.../LoggingSettings/EventsLogLevelSettings.cs | 9 -
.../EventsProcessorLogLevelSettings.cs | 8 -
.../LoggingSettings/IconsLogLevelSettings.cs | 8 -
.../IdentityLogLevelSettings.cs | 10 -
.../LoggingSettings/LogLevelSettings.cs | 16 --
.../NotificationsLogLevelSettings.cs | 9 -
.../LoggingSettings/ScimLogLevelSettings.cs | 8 -
.../LoggingSettings/SsoLogLevelSettings.cs | 8 -
src/Core/Utilities/LoggerFactoryExtensions.cs | 199 +++++-------------
src/Events/Program.cs | 20 +-
src/Events/Startup.cs | 3 -
src/Events/appsettings.json | 3 -
src/EventsProcessor/Program.cs | 3 +-
src/EventsProcessor/Startup.cs | 8 +-
src/Icons/Program.cs | 3 +-
src/Icons/Startup.cs | 3 -
src/Identity/Program.cs | 26 +--
src/Identity/Startup.cs | 3 -
src/Identity/appsettings.json | 3 -
src/Notifications/Program.cs | 32 +--
src/Notifications/Startup.cs | 2 -
src/Notifications/appsettings.json | 3 -
.../Utilities/LoggerFactoryExtensionsTests.cs | 103 ++-------
44 files changed, 93 insertions(+), 688 deletions(-)
delete mode 100644 src/Core/Settings/ILogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/AdminLogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/ApiLogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/BillingLogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/EventsLogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/EventsProcessorLogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/IconsLogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/IdentityLogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/LogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/NotificationsLogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/ScimLogLevelSettings.cs
delete mode 100644 src/Core/Settings/LoggingSettings/SsoLogLevelSettings.cs
diff --git a/.github/renovate.json5 b/.github/renovate.json5
index e892e59b22..6a23a7e832 100644
--- a/.github/renovate.json5
+++ b/.github/renovate.json5
@@ -90,11 +90,7 @@
"Microsoft.AspNetCore.Mvc.Testing",
"Newtonsoft.Json",
"NSubstitute",
- "Sentry.Serilog",
- "Serilog.AspNetCore",
- "Serilog.Extensions.Logging",
"Serilog.Extensions.Logging.File",
- "Serilog.Sinks.SyslogMessages",
"Stripe.net",
"Swashbuckle.AspNetCore",
"Swashbuckle.AspNetCore.SwaggerGen",
diff --git a/bitwarden_license/src/Scim/Program.cs b/bitwarden_license/src/Scim/Program.cs
index 92f12f59dd..02f2e00d32 100644
--- a/bitwarden_license/src/Scim/Program.cs
+++ b/bitwarden_license/src/Scim/Program.cs
@@ -11,21 +11,8 @@ public class Program
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
- webBuilder.ConfigureLogging((hostingContext, logging) =>
- logging.AddSerilog(hostingContext, (e, globalSettings) =>
- {
- var context = e.Properties["SourceContext"].ToString();
-
- if (e.Properties.TryGetValue("RequestPath", out var requestPath) &&
- !string.IsNullOrWhiteSpace(requestPath?.ToString()) &&
- (context.Contains(".Server.Kestrel") || context.Contains(".Core.IISHttpServer")))
- {
- return false;
- }
-
- return e.Level >= globalSettings.MinLogLevel.ScimSettings.Default;
- }));
})
+ .AddSerilogFileLogging()
.Build()
.Run();
}
diff --git a/bitwarden_license/src/Scim/Startup.cs b/bitwarden_license/src/Scim/Startup.cs
index edbbf34aea..2a84faa8dd 100644
--- a/bitwarden_license/src/Scim/Startup.cs
+++ b/bitwarden_license/src/Scim/Startup.cs
@@ -94,11 +94,8 @@ public class Startup
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
- IHostApplicationLifetime appLifetime,
GlobalSettings globalSettings)
{
- app.UseSerilog(env, appLifetime, globalSettings);
-
// Add general security headers
app.UseMiddleware();
diff --git a/bitwarden_license/src/Scim/appsettings.json b/bitwarden_license/src/Scim/appsettings.json
index dcdfeb3ede..18b7a7ca7b 100644
--- a/bitwarden_license/src/Scim/appsettings.json
+++ b/bitwarden_license/src/Scim/appsettings.json
@@ -30,9 +30,6 @@
"connectionString": "SECRET",
"applicationCacheTopicName": "SECRET"
},
- "sentry": {
- "dsn": "SECRET"
- },
"notificationHub": {
"connectionString": "SECRET",
"hubName": "SECRET"
diff --git a/bitwarden_license/src/Sso/Program.cs b/bitwarden_license/src/Sso/Program.cs
index 1a8ce6eb88..bac3bb3d13 100644
--- a/bitwarden_license/src/Sso/Program.cs
+++ b/bitwarden_license/src/Sso/Program.cs
@@ -1,5 +1,4 @@
using Bit.Core.Utilities;
-using Serilog;
namespace Bit.Sso;
@@ -13,19 +12,8 @@ public class Program
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
- webBuilder.ConfigureLogging((hostingContext, logging) =>
- logging.AddSerilog(hostingContext, (e, globalSettings) =>
- {
- var context = e.Properties["SourceContext"].ToString();
- if (e.Properties.TryGetValue("RequestPath", out var requestPath) &&
- !string.IsNullOrWhiteSpace(requestPath?.ToString()) &&
- (context.Contains(".Server.Kestrel") || context.Contains(".Core.IISHttpServer")))
- {
- return false;
- }
- return e.Level >= globalSettings.MinLogLevel.SsoSettings.Default;
- }));
})
+ .AddSerilogFileLogging()
.Build()
.Run();
}
diff --git a/bitwarden_license/src/Sso/Startup.cs b/bitwarden_license/src/Sso/Startup.cs
index 3ae8883ac4..2f83f3dad0 100644
--- a/bitwarden_license/src/Sso/Startup.cs
+++ b/bitwarden_license/src/Sso/Startup.cs
@@ -100,8 +100,6 @@ public class Startup
IdentityModelEventSource.ShowPII = true;
}
- app.UseSerilog(env, appLifetime, globalSettings);
-
// Add general security headers
app.UseMiddleware();
diff --git a/src/Admin/Program.cs b/src/Admin/Program.cs
index 05bf35d41d..006a8223b2 100644
--- a/src/Admin/Program.cs
+++ b/src/Admin/Program.cs
@@ -16,19 +16,8 @@ public class Program
o.Limits.MaxRequestLineSize = 20_000;
});
webBuilder.UseStartup();
- webBuilder.ConfigureLogging((hostingContext, logging) =>
- logging.AddSerilog(hostingContext, (e, globalSettings) =>
- {
- var context = e.Properties["SourceContext"].ToString();
- if (e.Properties.TryGetValue("RequestPath", out var requestPath) &&
- !string.IsNullOrWhiteSpace(requestPath?.ToString()) &&
- (context.Contains(".Server.Kestrel") || context.Contains(".Core.IISHttpServer")))
- {
- return false;
- }
- return e.Level >= globalSettings.MinLogLevel.AdminSettings.Default;
- }));
})
+ .AddSerilogFileLogging()
.Build()
.Run();
}
diff --git a/src/Admin/Startup.cs b/src/Admin/Startup.cs
index 5ecbdc899c..87d68a7ac6 100644
--- a/src/Admin/Startup.cs
+++ b/src/Admin/Startup.cs
@@ -132,11 +132,8 @@ public class Startup
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
- IHostApplicationLifetime appLifetime,
GlobalSettings globalSettings)
{
- app.UseSerilog(env, appLifetime, globalSettings);
-
// Add general security headers
app.UseMiddleware();
diff --git a/src/Api/Program.cs b/src/Api/Program.cs
index 6023f51c6d..bf924af47f 100644
--- a/src/Api/Program.cs
+++ b/src/Api/Program.cs
@@ -1,9 +1,4 @@
-// FIXME: Update this file to be null safe and then delete the line below
-#nullable disable
-
-using AspNetCoreRateLimit;
-using Bit.Core.Utilities;
-using Microsoft.IdentityModel.Tokens;
+using Bit.Core.Utilities;
namespace Bit.Api;
@@ -17,32 +12,8 @@ public class Program
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
- webBuilder.ConfigureLogging((hostingContext, logging) =>
- logging.AddSerilog(hostingContext, (e, globalSettings) =>
- {
- var context = e.Properties["SourceContext"].ToString();
- if (e.Exception != null &&
- (e.Exception.GetType() == typeof(SecurityTokenValidationException) ||
- e.Exception.Message == "Bad security stamp."))
- {
- return false;
- }
-
- if (
- context.Contains(typeof(IpRateLimitMiddleware).FullName))
- {
- return e.Level >= globalSettings.MinLogLevel.ApiSettings.IpRateLimit;
- }
-
- if (context.Contains("Duende.IdentityServer.Validation.TokenValidator") ||
- context.Contains("Duende.IdentityServer.Validation.TokenRequestValidator"))
- {
- return e.Level >= globalSettings.MinLogLevel.ApiSettings.IdentityToken;
- }
-
- return e.Level >= globalSettings.MinLogLevel.ApiSettings.Default;
- }));
})
+ .AddSerilogFileLogging()
.Build()
.Run();
}
diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs
index 0967b4f662..8ecdd148d3 100644
--- a/src/Api/Startup.cs
+++ b/src/Api/Startup.cs
@@ -234,12 +234,10 @@ public class Startup
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
- IHostApplicationLifetime appLifetime,
GlobalSettings globalSettings,
ILogger logger)
{
IdentityModelEventSource.ShowPII = true;
- app.UseSerilog(env, appLifetime, globalSettings);
// Add general security headers
app.UseMiddleware();
diff --git a/src/Api/appsettings.json b/src/Api/appsettings.json
index 98bb4df8ac..a503070d8d 100644
--- a/src/Api/appsettings.json
+++ b/src/Api/appsettings.json
@@ -32,9 +32,6 @@
"send": {
"connectionString": "SECRET"
},
- "sentry": {
- "dsn": "SECRET"
- },
"notificationHub": {
"connectionString": "SECRET",
"hubName": "SECRET"
diff --git a/src/Billing/Program.cs b/src/Billing/Program.cs
index 3e005ce7fd..72ff6072c5 100644
--- a/src/Billing/Program.cs
+++ b/src/Billing/Program.cs
@@ -11,25 +11,8 @@ public class Program
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
- webBuilder.ConfigureLogging((hostingContext, logging) =>
- logging.AddSerilog(hostingContext, (e, globalSettings) =>
- {
- var context = e.Properties["SourceContext"].ToString();
- if (context.StartsWith("\"Bit.Billing.Jobs") || context.StartsWith("\"Bit.Core.Jobs"))
- {
- return e.Level >= globalSettings.MinLogLevel.BillingSettings.Jobs;
- }
-
- if (e.Properties.TryGetValue("RequestPath", out var requestPath) &&
- !string.IsNullOrWhiteSpace(requestPath?.ToString()) &&
- (context.Contains(".Server.Kestrel") || context.Contains(".Core.IISHttpServer")))
- {
- return false;
- }
-
- return e.Level >= globalSettings.MinLogLevel.BillingSettings.Default;
- }));
})
+ .AddSerilogFileLogging()
.Build()
.Run();
}
diff --git a/src/Billing/Startup.cs b/src/Billing/Startup.cs
index cdb9700ad5..1343dc0895 100644
--- a/src/Billing/Startup.cs
+++ b/src/Billing/Startup.cs
@@ -10,7 +10,6 @@ using Bit.Core.Billing.Extensions;
using Bit.Core.Context;
using Bit.Core.SecretsManager.Repositories;
using Bit.Core.SecretsManager.Repositories.Noop;
-using Bit.Core.Settings;
using Bit.Core.Utilities;
using Bit.SharedWeb.Utilities;
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -129,12 +128,8 @@ public class Startup
public void Configure(
IApplicationBuilder app,
- IWebHostEnvironment env,
- IHostApplicationLifetime appLifetime,
- GlobalSettings globalSettings)
+ IWebHostEnvironment env)
{
- app.UseSerilog(env, appLifetime, globalSettings);
-
// Add general security headers
app.UseMiddleware();
diff --git a/src/Billing/appsettings.json b/src/Billing/appsettings.json
index a2d6acd0a1..aa14f1d377 100644
--- a/src/Billing/appsettings.json
+++ b/src/Billing/appsettings.json
@@ -30,9 +30,6 @@
"connectionString": "SECRET",
"applicationCacheTopicName": "SECRET"
},
- "sentry": {
- "dsn": "SECRET"
- },
"notificationHub": {
"connectionString": "SECRET",
"hubName": "SECRET"
diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj
index cfd10f0917..1be6e52854 100644
--- a/src/Core/Core.csproj
+++ b/src/Core/Core.csproj
@@ -50,13 +50,9 @@
-
-
-
-
diff --git a/src/Core/Settings/GlobalSettings.cs b/src/Core/Settings/GlobalSettings.cs
index 147b88623a..3446d1af2a 100644
--- a/src/Core/Settings/GlobalSettings.cs
+++ b/src/Core/Settings/GlobalSettings.cs
@@ -2,14 +2,12 @@
#nullable disable
using Bit.Core.Auth.Settings;
-using Bit.Core.Settings.LoggingSettings;
namespace Bit.Core.Settings;
public class GlobalSettings : IGlobalSettings
{
private string _mailTemplateDirectory;
- private string _logDirectory;
private string _licenseDirectory;
public GlobalSettings()
@@ -25,14 +23,6 @@ public class GlobalSettings : IGlobalSettings
public virtual string KnownProxies { get; set; }
public virtual string SiteName { get; set; }
public virtual string ProjectName { get; set; }
- public virtual string LogDirectory
- {
- get => BuildDirectory(_logDirectory, "/logs");
- set => _logDirectory = value;
- }
- public virtual bool LogDirectoryByProject { get; set; } = true;
- public virtual long? LogRollBySizeLimit { get; set; }
- public virtual bool EnableDevLogging { get; set; } = false;
public virtual string LicenseDirectory
{
get => BuildDirectory(_licenseDirectory, "/core/licenses");
@@ -73,9 +63,6 @@ public class GlobalSettings : IGlobalSettings
public virtual FileStorageSettings Send { get; set; }
public virtual IdentityServerSettings IdentityServer { get; set; } = new IdentityServerSettings();
public virtual DataProtectionSettings DataProtection { get; set; }
- public virtual SentrySettings Sentry { get; set; } = new SentrySettings();
- public virtual SyslogSettings Syslog { get; set; } = new SyslogSettings();
- public virtual ILogLevelSettings MinLogLevel { get; set; } = new LogLevelSettings();
public virtual NotificationHubPoolSettings NotificationHubPool { get; set; } = new();
public virtual YubicoSettings Yubico { get; set; } = new YubicoSettings();
public virtual DuoSettings Duo { get; set; } = new DuoSettings();
@@ -548,59 +535,11 @@ public class GlobalSettings : IGlobalSettings
}
}
- public class SentrySettings
- {
- public string Dsn { get; set; }
- }
-
public class NotificationsSettings : ConnectionStringSettings
{
public string RedisConnectionString { get; set; }
}
- public class SyslogSettings
- {
- ///
- /// The connection string used to connect to a remote syslog server over TCP or UDP, or to connect locally.
- ///
- ///
- /// The connection string will be parsed using to extract the protocol, host name and port number.
- ///
- ///
- /// Supported protocols are:
- ///
- /// - UDP (use
udp://)
- /// - TCP (use
tcp://)
- /// - TLS over TCP (use
tls://)
- ///
- ///
- ///
- ///
- /// A remote server (logging.dev.example.com) is listening on UDP (port 514):
- ///
- /// udp://logging.dev.example.com:514.
- ///
- public string Destination { get; set; }
- ///
- /// The absolute path to a Certificate (DER or Base64 encoded with private key).
- ///
- ///
- /// The certificate path and are passed into the .
- /// The file format of the certificate may be binary encoded (DER) or base64. If the private key is encrypted, provide the password in ,
- ///
- public string CertificatePath { get; set; }
- ///
- /// The password for the encrypted private key in the certificate supplied in .
- ///
- ///
- public string CertificatePassword { get; set; }
- ///
- /// The thumbprint of the certificate in the X.509 certificate store for personal certificates for the user account running Bitwarden.
- ///
- ///
- public string CertificateThumbprint { get; set; }
- }
-
public class NotificationHubSettings
{
private string _connectionString;
diff --git a/src/Core/Settings/IGlobalSettings.cs b/src/Core/Settings/IGlobalSettings.cs
index 0fc99d63e3..20b832c678 100644
--- a/src/Core/Settings/IGlobalSettings.cs
+++ b/src/Core/Settings/IGlobalSettings.cs
@@ -20,7 +20,6 @@ public interface IGlobalSettings
IConnectionStringSettings Storage { get; set; }
IBaseServiceUriSettings BaseServiceUri { get; set; }
ISsoSettings Sso { get; set; }
- ILogLevelSettings MinLogLevel { get; set; }
IPasswordlessAuthSettings PasswordlessAuth { get; set; }
IDomainVerificationSettings DomainVerification { get; set; }
ILaunchDarklySettings LaunchDarkly { get; set; }
diff --git a/src/Core/Settings/ILogLevelSettings.cs b/src/Core/Settings/ILogLevelSettings.cs
deleted file mode 100644
index b3cedf083c..0000000000
--- a/src/Core/Settings/ILogLevelSettings.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings;
-
-public interface ILogLevelSettings
-{
- IBillingLogLevelSettings BillingSettings { get; set; }
- IApiLogLevelSettings ApiSettings { get; set; }
- IIdentityLogLevelSettings IdentitySettings { get; set; }
- IScimLogLevelSettings ScimSettings { get; set; }
- ISsoLogLevelSettings SsoSettings { get; set; }
- IAdminLogLevelSettings AdminSettings { get; set; }
- IEventsLogLevelSettings EventsSettings { get; set; }
- IEventsProcessorLogLevelSettings EventsProcessorSettings { get; set; }
- IIconsLogLevelSettings IconsSettings { get; set; }
- INotificationsLogLevelSettings NotificationsSettings { get; set; }
-}
-
-public interface IBillingLogLevelSettings
-{
- LogEventLevel Default { get; set; }
- LogEventLevel Jobs { get; set; }
-}
-
-public interface IApiLogLevelSettings
-{
- LogEventLevel Default { get; set; }
- LogEventLevel IdentityToken { get; set; }
- LogEventLevel IpRateLimit { get; set; }
-}
-
-public interface IIdentityLogLevelSettings
-{
- LogEventLevel Default { get; set; }
- LogEventLevel IdentityToken { get; set; }
- LogEventLevel IpRateLimit { get; set; }
-}
-
-public interface IScimLogLevelSettings
-{
- LogEventLevel Default { get; set; }
-}
-
-public interface ISsoLogLevelSettings
-{
- LogEventLevel Default { get; set; }
-}
-
-public interface IAdminLogLevelSettings
-{
- LogEventLevel Default { get; set; }
-}
-
-public interface IEventsLogLevelSettings
-{
- LogEventLevel Default { get; set; }
- LogEventLevel IdentityToken { get; set; }
-}
-
-public interface IEventsProcessorLogLevelSettings
-{
- LogEventLevel Default { get; set; }
-}
-
-public interface IIconsLogLevelSettings
-{
- LogEventLevel Default { get; set; }
-}
-
-public interface INotificationsLogLevelSettings
-{
- LogEventLevel Default { get; set; }
- LogEventLevel IdentityToken { get; set; }
-}
diff --git a/src/Core/Settings/LoggingSettings/AdminLogLevelSettings.cs b/src/Core/Settings/LoggingSettings/AdminLogLevelSettings.cs
deleted file mode 100644
index d2c74dd076..0000000000
--- a/src/Core/Settings/LoggingSettings/AdminLogLevelSettings.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class AdminLogLevelSettings : IAdminLogLevelSettings
-{
- public LogEventLevel Default { get; set; } = LogEventLevel.Error;
-}
diff --git a/src/Core/Settings/LoggingSettings/ApiLogLevelSettings.cs b/src/Core/Settings/LoggingSettings/ApiLogLevelSettings.cs
deleted file mode 100644
index 7961ab7e3b..0000000000
--- a/src/Core/Settings/LoggingSettings/ApiLogLevelSettings.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class ApiLogLevelSettings : IApiLogLevelSettings
-{
- public LogEventLevel Default { get; set; } = LogEventLevel.Error;
- public LogEventLevel IdentityToken { get; set; } = LogEventLevel.Fatal;
- public LogEventLevel IpRateLimit { get; set; } = LogEventLevel.Information;
-}
diff --git a/src/Core/Settings/LoggingSettings/BillingLogLevelSettings.cs b/src/Core/Settings/LoggingSettings/BillingLogLevelSettings.cs
deleted file mode 100644
index b9e53e6bca..0000000000
--- a/src/Core/Settings/LoggingSettings/BillingLogLevelSettings.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class BillingLogLevelSettings : IBillingLogLevelSettings
-{
- public LogEventLevel Default { get; set; } = LogEventLevel.Warning;
- public LogEventLevel Jobs { get; set; } = LogEventLevel.Information;
-}
diff --git a/src/Core/Settings/LoggingSettings/EventsLogLevelSettings.cs b/src/Core/Settings/LoggingSettings/EventsLogLevelSettings.cs
deleted file mode 100644
index 3201748550..0000000000
--- a/src/Core/Settings/LoggingSettings/EventsLogLevelSettings.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class EventsLogLevelSettings : IEventsLogLevelSettings
-{
- public LogEventLevel Default { get; set; } = LogEventLevel.Error;
- public LogEventLevel IdentityToken { get; set; } = LogEventLevel.Fatal;
-}
diff --git a/src/Core/Settings/LoggingSettings/EventsProcessorLogLevelSettings.cs b/src/Core/Settings/LoggingSettings/EventsProcessorLogLevelSettings.cs
deleted file mode 100644
index 5aff18a216..0000000000
--- a/src/Core/Settings/LoggingSettings/EventsProcessorLogLevelSettings.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class EventsProcessorLogLevelSettings : IEventsProcessorLogLevelSettings
-{
- public LogEventLevel Default { get; set; } = LogEventLevel.Warning;
-}
diff --git a/src/Core/Settings/LoggingSettings/IconsLogLevelSettings.cs b/src/Core/Settings/LoggingSettings/IconsLogLevelSettings.cs
deleted file mode 100644
index c7b73ba687..0000000000
--- a/src/Core/Settings/LoggingSettings/IconsLogLevelSettings.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class IconsLogLevelSettings : IIconsLogLevelSettings
-{
- public LogEventLevel Default { get; set; } = LogEventLevel.Error;
-}
diff --git a/src/Core/Settings/LoggingSettings/IdentityLogLevelSettings.cs b/src/Core/Settings/LoggingSettings/IdentityLogLevelSettings.cs
deleted file mode 100644
index a823cb5109..0000000000
--- a/src/Core/Settings/LoggingSettings/IdentityLogLevelSettings.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class IdentityLogLevelSettings : IIdentityLogLevelSettings
-{
- public LogEventLevel Default { get; set; } = LogEventLevel.Error;
- public LogEventLevel IdentityToken { get; set; } = LogEventLevel.Fatal;
- public LogEventLevel IpRateLimit { get; set; } = LogEventLevel.Information;
-}
diff --git a/src/Core/Settings/LoggingSettings/LogLevelSettings.cs b/src/Core/Settings/LoggingSettings/LogLevelSettings.cs
deleted file mode 100644
index 1af05ebfde..0000000000
--- a/src/Core/Settings/LoggingSettings/LogLevelSettings.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class LogLevelSettings : ILogLevelSettings
-{
- public IBillingLogLevelSettings BillingSettings { get; set; } = new BillingLogLevelSettings();
- public IApiLogLevelSettings ApiSettings { get; set; } = new ApiLogLevelSettings();
- public IIdentityLogLevelSettings IdentitySettings { get; set; } = new IdentityLogLevelSettings();
- public IScimLogLevelSettings ScimSettings { get; set; } = new ScimLogLevelSettings();
- public ISsoLogLevelSettings SsoSettings { get; set; } = new SsoLogLevelSettings();
- public IAdminLogLevelSettings AdminSettings { get; set; } = new AdminLogLevelSettings();
- public IEventsLogLevelSettings EventsSettings { get; set; } = new EventsLogLevelSettings();
- public IEventsProcessorLogLevelSettings EventsProcessorSettings { get; set; } = new EventsProcessorLogLevelSettings();
- public IIconsLogLevelSettings IconsSettings { get; set; } = new IconsLogLevelSettings();
- public INotificationsLogLevelSettings NotificationsSettings { get; set; } = new NotificationsLogLevelSettings();
-}
diff --git a/src/Core/Settings/LoggingSettings/NotificationsLogLevelSettings.cs b/src/Core/Settings/LoggingSettings/NotificationsLogLevelSettings.cs
deleted file mode 100644
index 3494fbfcca..0000000000
--- a/src/Core/Settings/LoggingSettings/NotificationsLogLevelSettings.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class NotificationsLogLevelSettings : INotificationsLogLevelSettings
-{
- public LogEventLevel Default { get; set; } = LogEventLevel.Warning;
- public LogEventLevel IdentityToken { get; set; } = LogEventLevel.Fatal;
-}
diff --git a/src/Core/Settings/LoggingSettings/ScimLogLevelSettings.cs b/src/Core/Settings/LoggingSettings/ScimLogLevelSettings.cs
deleted file mode 100644
index f297b17e95..0000000000
--- a/src/Core/Settings/LoggingSettings/ScimLogLevelSettings.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class ScimLogLevelSettings : IScimLogLevelSettings
-{
- public LogEventLevel Default { get; set; } = LogEventLevel.Warning;
-}
diff --git a/src/Core/Settings/LoggingSettings/SsoLogLevelSettings.cs b/src/Core/Settings/LoggingSettings/SsoLogLevelSettings.cs
deleted file mode 100644
index 495ec41fd0..0000000000
--- a/src/Core/Settings/LoggingSettings/SsoLogLevelSettings.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Serilog.Events;
-
-namespace Bit.Core.Settings.LoggingSettings;
-
-public class SsoLogLevelSettings : ISsoLogLevelSettings
-{
- public LogEventLevel Default { get; set; } = LogEventLevel.Error;
-}
diff --git a/src/Core/Utilities/LoggerFactoryExtensions.cs b/src/Core/Utilities/LoggerFactoryExtensions.cs
index 54bd84df6f..b950e30d5d 100644
--- a/src/Core/Utilities/LoggerFactoryExtensions.cs
+++ b/src/Core/Utilities/LoggerFactoryExtensions.cs
@@ -1,165 +1,78 @@
-using System.Security.Cryptography.X509Certificates;
-using Bit.Core.Settings;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
-using Serilog;
-using Serilog.Events;
-using Serilog.Sinks.Syslog;
namespace Bit.Core.Utilities;
public static class LoggerFactoryExtensions
{
- public static void UseSerilog(
- this IApplicationBuilder appBuilder,
- IWebHostEnvironment env,
- IHostApplicationLifetime applicationLifetime,
- GlobalSettings globalSettings)
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static IHostBuilder AddSerilogFileLogging(this IHostBuilder hostBuilder)
{
- if (env.IsDevelopment() && !globalSettings.EnableDevLogging)
+ return hostBuilder.ConfigureLogging((context, logging) =>
{
- return;
- }
-
- applicationLifetime.ApplicationStopped.Register(Log.CloseAndFlush);
- }
-
- public static ILoggingBuilder AddSerilog(
- this ILoggingBuilder builder,
- WebHostBuilderContext context,
- Func? filter = null)
- {
- var globalSettings = new GlobalSettings();
- ConfigurationBinder.Bind(context.Configuration.GetSection("GlobalSettings"), globalSettings);
-
- if (context.HostingEnvironment.IsDevelopment() && !globalSettings.EnableDevLogging)
- {
- return builder;
- }
-
- bool inclusionPredicate(LogEvent e)
- {
- if (filter == null)
+ if (context.HostingEnvironment.IsDevelopment())
{
- return true;
+ return;
}
- var eventId = e.Properties.TryGetValue("EventId", out var eventIdValue) ? eventIdValue.ToString() : null;
- if (eventId?.Contains(Constants.BypassFiltersEventId.ToString()) ?? false)
+
+ // If they have begun using the new settings location, use that
+ if (!string.IsNullOrEmpty(context.Configuration["Logging:PathFormat"]))
{
- return true;
- }
- return filter(e, globalSettings);
- }
-
- var logSentryWarning = false;
- var logSyslogWarning = false;
-
- // Path format is the only required option for file logging, we will use that as
- // the keystone for if they have configured the new location.
- var newPathFormat = context.Configuration["Logging:PathFormat"];
-
- var config = new LoggerConfiguration()
- .MinimumLevel.Verbose()
- .Enrich.FromLogContext()
- .Filter.ByIncludingOnly(inclusionPredicate);
-
- if (CoreHelpers.SettingHasValue(globalSettings.Sentry.Dsn))
- {
- config.WriteTo.Sentry(globalSettings.Sentry.Dsn)
- .Enrich.FromLogContext()
- .Enrich.WithProperty("Project", globalSettings.ProjectName);
- }
- else if (CoreHelpers.SettingHasValue(globalSettings.Syslog.Destination))
- {
- logSyslogWarning = true;
- // appending sitename to project name to allow easier identification in syslog.
- var appName = $"{globalSettings.SiteName}-{globalSettings.ProjectName}";
- if (globalSettings.Syslog.Destination.Equals("local", StringComparison.OrdinalIgnoreCase))
- {
- config.WriteTo.LocalSyslog(appName);
- }
- else if (Uri.TryCreate(globalSettings.Syslog.Destination, UriKind.Absolute, out var syslogAddress))
- {
- // Syslog's standard port is 514 (both UDP and TCP). TLS does not have a standard port, so assume 514.
- int port = syslogAddress.Port >= 0
- ? syslogAddress.Port
- : 514;
-
- if (syslogAddress.Scheme.Equals("udp"))
- {
- config.WriteTo.UdpSyslog(syslogAddress.Host, port, appName);
- }
- else if (syslogAddress.Scheme.Equals("tcp"))
- {
- config.WriteTo.TcpSyslog(syslogAddress.Host, port, appName);
- }
- else if (syslogAddress.Scheme.Equals("tls"))
- {
- if (CoreHelpers.SettingHasValue(globalSettings.Syslog.CertificateThumbprint))
- {
- config.WriteTo.TcpSyslog(syslogAddress.Host, port, appName,
- useTls: true,
- certProvider: new CertificateStoreProvider(StoreName.My, StoreLocation.CurrentUser,
- globalSettings.Syslog.CertificateThumbprint));
- }
- else
- {
- config.WriteTo.TcpSyslog(syslogAddress.Host, port, appName,
- useTls: true,
- certProvider: new CertificateFileProvider(globalSettings.Syslog.CertificatePath,
- globalSettings.Syslog?.CertificatePassword ?? string.Empty));
- }
- }
- }
- }
- else if (!string.IsNullOrEmpty(newPathFormat))
- {
- // Use new location
- builder.AddFile(context.Configuration.GetSection("Logging"));
- }
- else if (CoreHelpers.SettingHasValue(globalSettings.LogDirectory))
- {
- if (globalSettings.LogRollBySizeLimit.HasValue)
- {
- var pathFormat = Path.Combine(globalSettings.LogDirectory, $"{globalSettings.ProjectName.ToLowerInvariant()}.log");
- if (globalSettings.LogDirectoryByProject)
- {
- pathFormat = Path.Combine(globalSettings.LogDirectory, globalSettings.ProjectName, "log.txt");
- }
- config.WriteTo.File(pathFormat, rollOnFileSizeLimit: true,
- fileSizeLimitBytes: globalSettings.LogRollBySizeLimit);
+ logging.AddFile(context.Configuration.GetSection("Logging"));
}
else
{
- var pathFormat = Path.Combine(globalSettings.LogDirectory, $"{globalSettings.ProjectName.ToLowerInvariant()}_{{Date}}.log");
- if (globalSettings.LogDirectoryByProject)
+ var globalSettingsSection = context.Configuration.GetSection("GlobalSettings");
+ var loggingOptions = new LegacyFileLoggingOptions();
+ globalSettingsSection.Bind(loggingOptions);
+
+ if (string.IsNullOrWhiteSpace(loggingOptions.LogDirectory))
{
- pathFormat = Path.Combine(globalSettings.LogDirectory, globalSettings.ProjectName, "{Date}.txt");
+ return;
+ }
+
+ var projectName = loggingOptions.ProjectName
+ ?? context.HostingEnvironment.ApplicationName;
+
+ if (loggingOptions.LogRollBySizeLimit.HasValue)
+ {
+ var 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
+ ? Path.Combine(loggingOptions.LogDirectory, projectName, "{Date}.txt")
+ : Path.Combine(loggingOptions.LogDirectory, $"{projectName.ToLowerInvariant()}_{{Date}}.log");
+
+ logging.AddFile(
+ pathFormat: pathFormat
+ );
}
- config.WriteTo.RollingFile(pathFormat);
}
- config
- .Enrich.FromLogContext()
- .Enrich.WithProperty("Project", globalSettings.ProjectName);
- }
+ });
+ }
- var serilog = config.CreateLogger();
-
- if (logSentryWarning)
- {
- serilog.Warning("Sentry for logging has been deprecated. Read more: https://btwrdn.com/log-deprecation");
- }
-
- if (logSyslogWarning)
- {
- serilog.Warning("Syslog for logging has been deprecated. Read more: https://btwrdn.com/log-deprecation");
- }
-
- builder.AddSerilog(serilog);
-
- return builder;
+ ///
+ /// Our own proprietary options that we've always supported in `GlobalSettings` configuration section.
+ ///
+ private class LegacyFileLoggingOptions
+ {
+ public string? ProjectName { get; set; }
+ public string? LogDirectory { get; set; } = "/etc/bitwarden/logs";
+ public bool LogDirectoryByProject { get; set; } = true;
+ public long? LogRollBySizeLimit { get; set; }
}
}
diff --git a/src/Events/Program.cs b/src/Events/Program.cs
index 967e94ed83..1a00549005 100644
--- a/src/Events/Program.cs
+++ b/src/Events/Program.cs
@@ -12,26 +12,8 @@ public class Program
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
- webBuilder.ConfigureLogging((hostingContext, logging) =>
- logging.AddSerilog(hostingContext, (e, globalSettings) =>
- {
- var context = e.Properties["SourceContext"].ToString();
- if (context.Contains("Duende.IdentityServer.Validation.TokenValidator") ||
- context.Contains("Duende.IdentityServer.Validation.TokenRequestValidator"))
- {
- return e.Level >= globalSettings.MinLogLevel.EventsSettings.IdentityToken;
- }
-
- if (e.Properties.TryGetValue("RequestPath", out var requestPath) &&
- !string.IsNullOrWhiteSpace(requestPath?.ToString()) &&
- (context.Contains(".Server.Kestrel") || context.Contains(".Core.IISHttpServer")))
- {
- return false;
- }
-
- return e.Level >= globalSettings.MinLogLevel.EventsSettings.Default;
- }));
})
+ .AddSerilogFileLogging()
.Build()
.Run();
}
diff --git a/src/Events/Startup.cs b/src/Events/Startup.cs
index cfe177aa2c..f67debd092 100644
--- a/src/Events/Startup.cs
+++ b/src/Events/Startup.cs
@@ -90,11 +90,8 @@ public class Startup
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
- IHostApplicationLifetime appLifetime,
GlobalSettings globalSettings)
{
- app.UseSerilog(env, appLifetime, globalSettings);
-
// Add general security headers
app.UseMiddleware();
diff --git a/src/Events/appsettings.json b/src/Events/appsettings.json
index e72b978f2f..41637c8549 100644
--- a/src/Events/appsettings.json
+++ b/src/Events/appsettings.json
@@ -14,9 +14,6 @@
"events": {
"connectionString": "SECRET"
},
- "sentry": {
- "dsn": "SECRET"
- },
"amazon": {
"accessKeyId": "SECRET",
"accessKeySecret": "SECRET",
diff --git a/src/EventsProcessor/Program.cs b/src/EventsProcessor/Program.cs
index 9b7a31e6f4..e4f4ac90d1 100644
--- a/src/EventsProcessor/Program.cs
+++ b/src/EventsProcessor/Program.cs
@@ -11,9 +11,8 @@ public class Program
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
- webBuilder.ConfigureLogging((hostingContext, logging) =>
- logging.AddSerilog(hostingContext, (e, globalSettings) => e.Level >= globalSettings.MinLogLevel.EventsProcessorSettings.Default));
})
+ .AddSerilogFileLogging()
.Build()
.Run();
}
diff --git a/src/EventsProcessor/Startup.cs b/src/EventsProcessor/Startup.cs
index 67676a8afc..260c501e01 100644
--- a/src/EventsProcessor/Startup.cs
+++ b/src/EventsProcessor/Startup.cs
@@ -1,5 +1,4 @@
using System.Globalization;
-using Bit.Core.Settings;
using Bit.Core.Utilities;
using Bit.SharedWeb.Utilities;
using Microsoft.IdentityModel.Logging;
@@ -37,14 +36,9 @@ public class Startup
services.AddHostedService();
}
- public void Configure(
- IApplicationBuilder app,
- IWebHostEnvironment env,
- IHostApplicationLifetime appLifetime,
- GlobalSettings globalSettings)
+ public void Configure(IApplicationBuilder app)
{
IdentityModelEventSource.ShowPII = true;
- app.UseSerilog(env, appLifetime, globalSettings);
// Add general security headers
app.UseMiddleware();
app.UseRouting();
diff --git a/src/Icons/Program.cs b/src/Icons/Program.cs
index 237096b0b1..80c1b5728e 100644
--- a/src/Icons/Program.cs
+++ b/src/Icons/Program.cs
@@ -11,9 +11,8 @@ public class Program
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
- webBuilder.ConfigureLogging((hostingContext, logging) =>
- logging.AddSerilog(hostingContext, (e, globalSettings) => e.Level >= globalSettings.MinLogLevel.IconsSettings.Default));
})
+ .AddSerilogFileLogging()
.Build()
.Run();
}
diff --git a/src/Icons/Startup.cs b/src/Icons/Startup.cs
index 2602dd6264..5d9b5e5a30 100644
--- a/src/Icons/Startup.cs
+++ b/src/Icons/Startup.cs
@@ -60,11 +60,8 @@ public class Startup
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
- IHostApplicationLifetime appLifetime,
GlobalSettings globalSettings)
{
- app.UseSerilog(env, appLifetime, globalSettings);
-
// Add general security headers
app.UseMiddleware();
diff --git a/src/Identity/Program.cs b/src/Identity/Program.cs
index cb6e7daf39..238ad8ce3a 100644
--- a/src/Identity/Program.cs
+++ b/src/Identity/Program.cs
@@ -1,8 +1,4 @@
-// FIXME: Update this file to be null safe and then delete the line below
-#nullable disable
-
-using AspNetCoreRateLimit;
-using Bit.Core.Utilities;
+using Bit.Core.Utilities;
namespace Bit.Identity;
@@ -23,23 +19,7 @@ public class Program
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
- webBuilder.ConfigureLogging((hostingContext, logging) =>
- logging.AddSerilog(hostingContext, (e, globalSettings) =>
- {
- var context = e.Properties["SourceContext"].ToString();
- if (context.Contains(typeof(IpRateLimitMiddleware).FullName))
- {
- return e.Level >= globalSettings.MinLogLevel.IdentitySettings.IpRateLimit;
- }
-
- if (context.Contains("Duende.IdentityServer.Validation.TokenValidator") ||
- context.Contains("Duende.IdentityServer.Validation.TokenRequestValidator"))
- {
- return e.Level >= globalSettings.MinLogLevel.IdentitySettings.IdentityToken;
- }
-
- return e.Level >= globalSettings.MinLogLevel.IdentitySettings.Default;
- }));
- });
+ })
+ .AddSerilogFileLogging();
}
}
diff --git a/src/Identity/Startup.cs b/src/Identity/Startup.cs
index 74344977a0..5dc443a73c 100644
--- a/src/Identity/Startup.cs
+++ b/src/Identity/Startup.cs
@@ -170,14 +170,11 @@ public class Startup
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
- IHostApplicationLifetime appLifetime,
GlobalSettings globalSettings,
ILogger logger)
{
IdentityModelEventSource.ShowPII = true;
- app.UseSerilog(env, appLifetime, globalSettings);
-
// Add general security headers
app.UseMiddleware();
diff --git a/src/Identity/appsettings.json b/src/Identity/appsettings.json
index 16c3efe46b..c21d2dff3b 100644
--- a/src/Identity/appsettings.json
+++ b/src/Identity/appsettings.json
@@ -27,9 +27,6 @@
"events": {
"connectionString": "SECRET"
},
- "sentry": {
- "dsn": "SECRET"
- },
"notificationHub": {
"connectionString": "SECRET",
"hubName": "SECRET"
diff --git a/src/Notifications/Program.cs b/src/Notifications/Program.cs
index 072c2404c4..2792391729 100644
--- a/src/Notifications/Program.cs
+++ b/src/Notifications/Program.cs
@@ -1,5 +1,4 @@
using Bit.Core.Utilities;
-using Serilog.Events;
namespace Bit.Notifications;
@@ -13,37 +12,8 @@ public class Program
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
- webBuilder.ConfigureLogging((hostingContext, logging) =>
- logging.AddSerilog(hostingContext, (e, globalSettings) =>
- {
- var context = e.Properties["SourceContext"].ToString();
- if (context.Contains("Duende.IdentityServer.Validation.TokenValidator") ||
- context.Contains("Duende.IdentityServer.Validation.TokenRequestValidator"))
- {
- return e.Level >= globalSettings.MinLogLevel.NotificationsSettings.IdentityToken;
- }
-
- if (e.Level == LogEventLevel.Error &&
- e.MessageTemplate.Text == "Failed connection handshake.")
- {
- return false;
- }
-
- if (e.Level == LogEventLevel.Error &&
- e.MessageTemplate.Text.StartsWith("Failed writing message."))
- {
- return false;
- }
-
- if (e.Level == LogEventLevel.Warning &&
- e.MessageTemplate.Text.StartsWith("Heartbeat took longer"))
- {
- return false;
- }
-
- return e.Level >= globalSettings.MinLogLevel.NotificationsSettings.Default;
- }));
})
+ .AddSerilogFileLogging()
.Build()
.Run();
}
diff --git a/src/Notifications/Startup.cs b/src/Notifications/Startup.cs
index 2889e90d3b..65904ea698 100644
--- a/src/Notifications/Startup.cs
+++ b/src/Notifications/Startup.cs
@@ -82,11 +82,9 @@ public class Startup
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
- IHostApplicationLifetime appLifetime,
GlobalSettings globalSettings)
{
IdentityModelEventSource.ShowPII = true;
- app.UseSerilog(env, appLifetime, globalSettings);
// Add general security headers
app.UseMiddleware();
diff --git a/src/Notifications/appsettings.json b/src/Notifications/appsettings.json
index 020d98cbd6..e36ec02dad 100644
--- a/src/Notifications/appsettings.json
+++ b/src/Notifications/appsettings.json
@@ -18,9 +18,6 @@
"connectionString": "SECRET",
"applicationCacheTopicName": "SECRET"
},
- "sentry": {
- "dsn": "SECRET"
- },
"amazon": {
"accessKeyId": "SECRET",
"accessKeySecret": "SECRET",
diff --git a/test/Core.Test/Utilities/LoggerFactoryExtensionsTests.cs b/test/Core.Test/Utilities/LoggerFactoryExtensionsTests.cs
index 06bb362336..81311cb802 100644
--- a/test/Core.Test/Utilities/LoggerFactoryExtensionsTests.cs
+++ b/test/Core.Test/Utilities/LoggerFactoryExtensionsTests.cs
@@ -1,13 +1,9 @@
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using Bit.Core.Utilities;
-using Microsoft.AspNetCore.Hosting;
+using Bit.Core.Utilities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NSubstitute;
-using Serilog;
using Serilog.Extensions.Logging;
using Xunit;
@@ -23,18 +19,6 @@ public class LoggerFactoryExtensionsTests
Assert.Empty(providers);
}
- [Fact]
- public void AddSerilog_IsDevelopment_DevLoggingEnabled_AddsSerilog()
- {
- var providers = GetProviders(new Dictionary
- {
- { "GlobalSettings:EnableDevLogging", "true" },
- }, "Development");
-
- var provider = Assert.Single(providers);
- Assert.IsAssignableFrom(provider);
- }
-
[Fact]
public void AddSerilog_IsProduction_AddsSerilog()
{
@@ -52,7 +36,7 @@ public class LoggerFactoryExtensionsTests
var providers = GetProviders(new Dictionary
{
{ "GlobalSettings:ProjectName", "Test" },
- { "GlobalSetting:LogDirectoryByProject", "true" },
+ { "GlobalSettings:LogDirectoryByProject", "true" },
{ "GlobalSettings:LogDirectory", tempDir.FullName },
});
@@ -62,6 +46,8 @@ public class LoggerFactoryExtensionsTests
var logger = provider.CreateLogger("Test");
logger.LogWarning("This is a test");
+ provider.Dispose();
+
var logFile = Assert.Single(tempDir.EnumerateFiles("Test/*.txt"));
var logFileContents = await File.ReadAllTextAsync(logFile.FullName);
@@ -104,62 +90,6 @@ public class LoggerFactoryExtensionsTests
logFileContents
);
}
-
- [Fact(Skip = "Only for local development.")]
- public async Task AddSerilog_SyslogConfigured_Warns()
- {
- // Setup a fake syslog server
- var cts = new CancellationTokenSource(TimeSpan.FromSeconds(20));
- using var listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 25000);
- listener.Start();
-
- var provider = GetServiceProvider(new Dictionary
- {
- { "GlobalSettings:SysLog:Destination", "tcp://127.0.0.1:25000" },
- { "GlobalSettings:SiteName", "TestSite" },
- { "GlobalSettings:ProjectName", "TestProject" },
- }, "Production");
-
- var loggerFactory = provider.GetRequiredService();
- var logger = loggerFactory.CreateLogger("Test");
-
- logger.LogWarning("This is a test");
-
- // Look in syslog for data
- using var socket = await listener.AcceptSocketAsync(cts.Token);
-
- // This is rather lazy as opposed to implementing smarter syslog message
- // reading but thats not what this test about, so instead just give
- // the sink time to finish its work in the background
-
- List messages = [];
-
- while (true)
- {
- var buffer = new byte[1024];
- var received = await socket.ReceiveAsync(buffer, SocketFlags.None, cts.Token);
-
- if (received == 0)
- {
- break;
- }
-
- var response = Encoding.ASCII.GetString(buffer, 0, received);
- messages.Add(response);
-
- if (messages.Count == 2)
- {
- break;
- }
- }
-
- Assert.Collection(
- messages,
- (firstMessage) => Assert.Contains("Syslog for logging has been deprecated", firstMessage),
- (secondMessage) => Assert.Contains("This is a test", secondMessage)
- );
- }
-
private static IEnumerable GetProviders(Dictionary initialData, string environment = "Production")
{
var provider = GetServiceProvider(initialData, environment);
@@ -172,23 +102,34 @@ public class LoggerFactoryExtensionsTests
.AddInMemoryCollection(initialData)
.Build();
- var hostingEnvironment = Substitute.For();
+ var hostingEnvironment = Substitute.For();
hostingEnvironment
.EnvironmentName
.Returns(environment);
- var context = new WebHostBuilderContext
+ var context = new HostBuilderContext(new Dictionary