diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index b9a27d757f..b731aff187 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -258,6 +258,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Minify.Tests", "te
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Serilog", "src\Volo.Abp.AspNetCore.Serilog\Volo.Abp.AspNetCore.Serilog.csproj", "{3B801003-BE74-49ED-9749-DA5E99F45EBF}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Serilog.Tests", "test\Volo.Abp.AspNetCore.Serilog.Tests\Volo.Abp.AspNetCore.Serilog.Tests.csproj", "{9CAA07ED-FE5C-4427-A6FA-6C6CB5B4CC62}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -768,6 +770,10 @@ Global
{3B801003-BE74-49ED-9749-DA5E99F45EBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B801003-BE74-49ED-9749-DA5E99F45EBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B801003-BE74-49ED-9749-DA5E99F45EBF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9CAA07ED-FE5C-4427-A6FA-6C6CB5B4CC62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9CAA07ED-FE5C-4427-A6FA-6C6CB5B4CC62}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9CAA07ED-FE5C-4427-A6FA-6C6CB5B4CC62}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9CAA07ED-FE5C-4427-A6FA-6C6CB5B4CC62}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -899,6 +905,7 @@ Global
{928DC30D-C078-4BB4-A9F8-FE7252C67DC6} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{E69182B3-350A-43F5-A935-5EBBEBECEF97} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{3B801003-BE74-49ED-9749-DA5E99F45EBF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {9CAA07ED-FE5C-4427-A6FA-6C6CB5B4CC62} = {447C8A77-E5F0-4538-8687-7383196D04EA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj
new file mode 100644
index 0000000000..740c57949d
--- /dev/null
+++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj
@@ -0,0 +1,24 @@
+
+
+
+
+
+ netcoreapp3.1
+ Volo.Abp.AspNetCore.Serilog.Tests
+ Volo.Abp.AspNetCore.Serilog.Tests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/AbpSerilogTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/AbpSerilogTestModule.cs
new file mode 100644
index 0000000000..64ac0d76bc
--- /dev/null
+++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/AbpSerilogTestModule.cs
@@ -0,0 +1,39 @@
+using Microsoft.AspNetCore.Builder;
+using Volo.Abp.AspNetCore.MultiTenancy;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.AspNetCore.Serilog;
+using Volo.Abp.AspNetCore.TestBase;
+using Volo.Abp.Autofac;
+using Volo.Abp.Modularity;
+using Volo.Abp.MultiTenancy;
+
+namespace Volo.Abp.AspNetCore.App
+{
+ [DependsOn(
+ typeof(AbpAspNetCoreTestBaseModule),
+ typeof(AbpAspNetCoreMvcModule),
+ typeof(AbpAspNetCoreMultiTenancyModule),
+ typeof(AbpSerilogModule),
+ typeof(AbpAutofacModule)
+ )]
+ public class AbpSerilogTestModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options => { options.IsEnabled = true; });
+ }
+
+ public override void OnApplicationInitialization(ApplicationInitializationContext context)
+ {
+ var app = context.GetApplicationBuilder();
+
+ app.UseCorrelationId();
+ app.UseRouting();
+ app.UseAuthorization();
+ app.UseMultiTenancy();
+ app.UseAuditing();
+ app.UseSerilogEnrichers();
+ app.UseMvcWithDefaultRouteAndArea();
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/CollectingSink.cs b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/CollectingSink.cs
new file mode 100644
index 0000000000..fe403e02ef
--- /dev/null
+++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/CollectingSink.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+using System.Linq;
+using Serilog.Core;
+using Serilog.Events;
+
+namespace Volo.Abp.AspNetCore.App
+{
+ public class CollectingSink : ILogEventSink
+ {
+ public List Events { get; } = new List();
+
+ public LogEvent SingleEvent => Events.Single();
+
+ public void Emit(LogEvent logEvent)
+ {
+ Events.Add(logEvent);
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/SerilogTestController.cs b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/SerilogTestController.cs
new file mode 100644
index 0000000000..972af4c801
--- /dev/null
+++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/SerilogTestController.cs
@@ -0,0 +1,27 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.Tracing;
+
+namespace Volo.Abp.AspNetCore.App
+{
+ public class SerilogTestController : AbpController
+ {
+ private readonly ICorrelationIdProvider _correlationIdProvider;
+
+ public SerilogTestController(ICorrelationIdProvider correlationIdProvider)
+ {
+ _correlationIdProvider = correlationIdProvider;
+ }
+
+ public ActionResult Index()
+ {
+ return Content("Index-Result");
+ }
+
+ public ActionResult CorrelationId()
+ {
+ return Content(_correlationIdProvider.Get());
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/Startup.cs b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/Startup.cs
new file mode 100644
index 0000000000..a1a58100d5
--- /dev/null
+++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/App/Startup.cs
@@ -0,0 +1,20 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace Volo.Abp.AspNetCore.App
+{
+ public class Startup
+ {
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddApplication();
+ }
+
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ILoggerFactory loggerFactory)
+ {
+ app.InitializeApplication();
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/AbpSerilogTestBase.cs b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/AbpSerilogTestBase.cs
new file mode 100644
index 0000000000..96a13ac45b
--- /dev/null
+++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/AbpSerilogTestBase.cs
@@ -0,0 +1,31 @@
+using System.Linq;
+using Microsoft.Extensions.Hosting;
+using Serilog;
+using Serilog.Events;
+using Volo.Abp.AspNetCore.App;
+
+namespace Volo.Abp.AspNetCore.Serilog
+{
+ public class AbpSerilogTestBase : AbpAspNetCoreTestBase
+ {
+ protected readonly CollectingSink CollectingSink = new CollectingSink();
+
+ protected override IHostBuilder CreateHostBuilder()
+ {
+ Log.Logger = new LoggerConfiguration()
+ .MinimumLevel.Information()
+ .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
+ .Enrich.FromLogContext()
+ .WriteTo.Sink(CollectingSink)
+ .CreateLogger();
+
+ return base.CreateHostBuilder()
+ .UseSerilog();
+ }
+
+ protected LogEvent GetLogEvent(string text)
+ {
+ return CollectingSink.Events.FirstOrDefault(m => m.MessageTemplate.Text == text);
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs
new file mode 100644
index 0000000000..bc45eb7c51
--- /dev/null
+++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Serilog.Events;
+using Shouldly;
+using Volo.Abp.AspNetCore.App;
+using Volo.Abp.AspNetCore.MultiTenancy;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.MultiTenancy.ConfigurationStore;
+using Xunit;
+
+namespace Volo.Abp.AspNetCore.Serilog
+{
+ public class Serilog_Enrichers_Tests : AbpSerilogTestBase
+ {
+ private const string ExecutedEndpointLogEventText = "Executed endpoint '{EndpointName}'";
+
+ private readonly Guid _testTenantId = Guid.NewGuid();
+ private readonly string _testTenantName = "acme";
+
+ private readonly AbpAspNetCoreMultiTenancyOptions _tenancyOptions;
+ private readonly AbpAspNetCoreSerilogEnrichersOptions _serilogEnrichersOptions;
+ private readonly ILogger _logger;
+
+ public Serilog_Enrichers_Tests()
+ {
+ _tenancyOptions = ServiceProvider.GetRequiredService>().Value;
+ _serilogEnrichersOptions =
+ ServiceProvider.GetRequiredService>().Value;
+ _logger = ServiceProvider.GetRequiredService>();
+ }
+
+ protected override IHostBuilder CreateHostBuilder()
+ {
+ return base.CreateHostBuilder().ConfigureServices(services =>
+ {
+ services.Configure(options =>
+ {
+ options.Tenants = new[]
+ {
+ new TenantConfiguration(_testTenantId, _testTenantName)
+ };
+ });
+ });
+ }
+
+ [Fact]
+ public async Task TenantId_Not_Set_Test()
+ {
+ var url = GetUrl(nameof(SerilogTestController.Index));
+ var result = await GetResponseAsStringAsync(url).ConfigureAwait(false);
+
+ var executedLogEvent = GetLogEvent(ExecutedEndpointLogEventText);
+
+ executedLogEvent.ShouldNotBeNull();
+ executedLogEvent.Properties.ContainsKey(_serilogEnrichersOptions.TenantIdEnricherPropertyName)
+ .ShouldBe(false);
+ }
+
+ [Fact]
+ public async Task TenantId_Set_Test()
+ {
+ var url =
+ GetUrl(nameof(SerilogTestController.Index)) +
+ $"?{_tenancyOptions.TenantKey}={_testTenantName}";
+ var result = await GetResponseAsStringAsync(url).ConfigureAwait(false);
+
+ var executedLogEvent = GetLogEvent(ExecutedEndpointLogEventText);
+
+ executedLogEvent.ShouldNotBeNull();
+ executedLogEvent.Properties.ContainsKey(_serilogEnrichersOptions.TenantIdEnricherPropertyName)
+ .ShouldBe(true);
+ ((ScalarValue) executedLogEvent.Properties[_serilogEnrichersOptions.TenantIdEnricherPropertyName]).Value
+ .ShouldBe(_testTenantId);
+ }
+
+ [Fact]
+ public async Task CorrelationId_Enrichers_Test()
+ {
+ var url = GetUrl(nameof(SerilogTestController.CorrelationId));
+ var result = await GetResponseAsStringAsync(url).ConfigureAwait(false);
+
+ var executedLogEvent = GetLogEvent(ExecutedEndpointLogEventText);
+
+ executedLogEvent.ShouldNotBeNull();
+
+ executedLogEvent.Properties.ContainsKey(_serilogEnrichersOptions.CorrelationIdPropertyName)
+ .ShouldNotBeNull();
+
+ ((ScalarValue) executedLogEvent.Properties[_serilogEnrichersOptions.CorrelationIdPropertyName]).Value
+ .ShouldBe(result);
+ }
+ }
+}
\ No newline at end of file