Skip to content

Commit

Permalink
NBB.MultiTenancy.Serilog (#212)
Browse files Browse the repository at this point in the history
* NBB.MultiTenancy.Serilog

* tests and cleanup

* documentation update

Co-authored-by: [email protected] <[email protected]>
  • Loading branch information
dorinsimionescu and [email protected] authored Mar 16, 2022
1 parent 5000bd2 commit 9528ffe
Show file tree
Hide file tree
Showing 14 changed files with 542 additions and 12 deletions.
39 changes: 38 additions & 1 deletion NBB.sln
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBB.MultiTenancy.Abstractio
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBB.EventStore.AdoNet.Tests", "test\UnitTests\EventStore\NBB.EventStore.AdoNet.Tests\NBB.EventStore.AdoNet.Tests.csproj", "{C3F79479-1011-4ECB-8876-81B81CA2457B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBB.Tools.Serilog.Enrichers.ServiceIdentifier", "src\Tools\Serilog\NBB.Tools.Serilog.Enrichers.ServiceIdentifier\NBB.Tools.Serilog.Enrichers.ServiceIdentifier.csproj", "{EE64CE9C-7A9C-4832-B9CD-00106CFA620C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{2177F9CE-CD18-4D61-8DAE-0E27D3C44AB3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBB.Tools.Serilog.Enrichers.ServiceIdentifier.Tests", "test\UnitTests\Tools\NBB.Tools.Serilog.Enrichers.ServiceIdentifier.Tests\NBB.Tools.Serilog.Enrichers.ServiceIdentifier.Tests.csproj", "{E2F3DA74-E8BB-492B-877C-24E781C4FB1F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBB.Tools.Serilog.Enrichers.TenantId", "src\Tools\Serilog\NBB.Tools.Serilog.Enrichers.TenantId\NBB.Tools.Serilog.Enrichers.TenantId.csproj", "{C964F164-C8BF-487A-9D24-5E169A7E950F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBB.Tools.Serilog.Enrichers.TenantId.Tests", "test\UnitTests\Tools\NBB.Tools.Serilog.Enrichers.TenantId.Tests\NBB.Tools.Serilog.Enrichers.TenantId.Tests.csproj", "{81E535EC-ACB5-4EE4-A173-06983B40F80F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Serilog", "Serilog", "{33AEB049-EC66-4728-9B22-CC0F282D3E73}"
ProjectSection(SolutionItems) = preProject
src\Tools\Serilog\README.md = src\Tools\Serilog\README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -861,6 +876,22 @@ Global
{C3F79479-1011-4ECB-8876-81B81CA2457B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3F79479-1011-4ECB-8876-81B81CA2457B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3F79479-1011-4ECB-8876-81B81CA2457B}.Release|Any CPU.Build.0 = Release|Any CPU
{EE64CE9C-7A9C-4832-B9CD-00106CFA620C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE64CE9C-7A9C-4832-B9CD-00106CFA620C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE64CE9C-7A9C-4832-B9CD-00106CFA620C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE64CE9C-7A9C-4832-B9CD-00106CFA620C}.Release|Any CPU.Build.0 = Release|Any CPU
{E2F3DA74-E8BB-492B-877C-24E781C4FB1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2F3DA74-E8BB-492B-877C-24E781C4FB1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2F3DA74-E8BB-492B-877C-24E781C4FB1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2F3DA74-E8BB-492B-877C-24E781C4FB1F}.Release|Any CPU.Build.0 = Release|Any CPU
{C964F164-C8BF-487A-9D24-5E169A7E950F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C964F164-C8BF-487A-9D24-5E169A7E950F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C964F164-C8BF-487A-9D24-5E169A7E950F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C964F164-C8BF-487A-9D24-5E169A7E950F}.Release|Any CPU.Build.0 = Release|Any CPU
{81E535EC-ACB5-4EE4-A173-06983B40F80F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81E535EC-ACB5-4EE4-A173-06983B40F80F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81E535EC-ACB5-4EE4-A173-06983B40F80F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81E535EC-ACB5-4EE4-A173-06983B40F80F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -991,7 +1022,7 @@ Global
{74583BC7-B9BC-4D27-B9E9-5DB136A8E41C} = {D28298B7-63A2-4751-BEB9-C3C30F2E7107}
{A2A174AF-8612-4796-B5FA-E2F9EB3AB68F} = {74583BC7-B9BC-4D27-B9E9-5DB136A8E41C}
{EF374BA2-61FC-41FB-8229-5187DCBAA63A} = {7311E32F-C1B0-41C9-B5F1-DE9EBB6ABB55}
{A5826A9E-7E96-4A52-8A06-2B6DC9855954} = {EF374BA2-61FC-41FB-8229-5187DCBAA63A}
{A5826A9E-7E96-4A52-8A06-2B6DC9855954} = {33AEB049-EC66-4728-9B22-CC0F282D3E73}
{2FEDB78D-E355-4449-A9D3-1C3079E38FD9} = {20C8482D-1525-47B0-B78B-09632892E8E4}
{0B65210B-9A1D-4D07-98B4-69995FEF21BD} = {4DCC0E0D-52D8-4F97-9B26-C3F9CB76F16F}
{04556BEE-32FE-47D5-8C22-7D336FA44D7C} = {584C62C0-2AE6-4DD6-9BCF-8FF28B7122CE}
Expand Down Expand Up @@ -1020,6 +1051,12 @@ Global
{A53CE5F4-841F-40E3-A079-22C583509D6E} = {584C62C0-2AE6-4DD6-9BCF-8FF28B7122CE}
{CEE3FAE5-2E96-4318-9A4D-7FAAC529CB08} = {0ECF24A0-BFED-4F7A-8B06-CC40E628E852}
{C3F79479-1011-4ECB-8876-81B81CA2457B} = {0407911F-89FC-4138-BD4D-D4CFCFBB5DC1}
{EE64CE9C-7A9C-4832-B9CD-00106CFA620C} = {33AEB049-EC66-4728-9B22-CC0F282D3E73}
{2177F9CE-CD18-4D61-8DAE-0E27D3C44AB3} = {90E022FB-CA1B-49DD-9BEA-CE7F8E74E8BB}
{E2F3DA74-E8BB-492B-877C-24E781C4FB1F} = {2177F9CE-CD18-4D61-8DAE-0E27D3C44AB3}
{C964F164-C8BF-487A-9D24-5E169A7E950F} = {33AEB049-EC66-4728-9B22-CC0F282D3E73}
{81E535EC-ACB5-4EE4-A173-06983B40F80F} = {2177F9CE-CD18-4D61-8DAE-0E27D3C44AB3}
{33AEB049-EC66-4728-9B22-CC0F282D3E73} = {EF374BA2-61FC-41FB-8229-5187DCBAA63A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {23A42379-616A-43EF-99BC-803DF151F54E}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ private MessagingEnvelope<TMessage> PrepareMessageEnvelope<TMessage>(TMessage me

private string GetSourceId()
{
var topicPrefix = _configuration.GetSection("Messaging")?["Source"];
return topicPrefix ?? "";
var sourceId = _configuration.GetSection("Messaging")?["Source"];
return sourceId ?? "";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@

namespace NBB.Messaging.Abstractions
{
public class MessagingContextAccessor
{
private static readonly AsyncLocal<MessagingContext> AsyncLocal = new();

public MessagingContext MessagingContext
{
get => AsyncLocal.Value;
set => AsyncLocal.Value = value;
}
public class MessagingContextAccessor
{
private static readonly AsyncLocal<MessagingContext> AsyncLocal = new();

public MessagingContext MessagingContext
{
get => AsyncLocal.Value;
set => AsyncLocal.Value = value;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Serilog" Version="$(SerilogPackageVersion)" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# NBB.Tools.Serilog.Enrichers.ServiceIdentifier

This project provides a Serilog Enricher that adds a service identifier to the log context.
The identifier is taken either from messaging source or from the Assembly.GetEntryAssembly().Name.


## NuGet install
```
dotnet add package NBB.Tools.Serilog.Enrichers.ServiceIdentifier
```
# Registration
The enricher should be registered in `Startup.cs`:

```csharp
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<ServiceIdentifierEnricher>();
...
}
```
# Usage: example for Program.cs
```csharp
var hostBuilder = CreateHostBuilder(args);
var tempLogger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.CreateLogger();

hostBuilder.UseSerilog((context, services, configuration) =>
{
configuration.ReadFrom.Configuration(Configuration);
configuration.Enrich.With(services.GetRequiredService<ServiceIdentifierEnricher>());
...
});
```

# Usage: example for an sql logger configured in appsettings.json
"Serilog": {
"MinimumLevel": "Debug",
"tableName": "TABLE_NAME",
"WriteTo": [
{
"Name": "MSSqlServer",
"Args": {
"connectionString": "Server=SERVER,POST;Database=DB;User Id=USERID;Password=PASS;MultipleActiveResultSets=true",
"tableName": "TABLE_NAME",
"autoCreateSqlTable": false,
"columnOptionsSection": {
"addStandardColumns": [ "LogEvent" ],
"customColumns": [
{
"ColumnName": "ServiceIdentifier",
"PropertyName": "ServiceIdentifier",
"DataType": "nvarchar",
"DataLength": "255",
"AllowNull": true
}
]
}
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message} T: {TenantId} E: {EnvelopeGuid} N: {FirstName} {LastName} ID: {IdCardIdentifier} EID: {FingerprintId} {NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId", "ServiceIdentifier" ]
},

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) TotalSoft.
// This source code is licensed under the MIT license.

using Microsoft.Extensions.Configuration;
using Serilog.Core;
using Serilog.Events;
using System.Reflection;

namespace NBB.Tools.Serilog.Enrichers.ServiceIdentifier
{
public class ServiceIdentifierEnricher : ILogEventEnricher
{
private readonly IConfiguration _configuration;
public static string PropertyName { get; } = "ServiceIdentifier";

public ServiceIdentifierEnricher(IConfiguration configuration)
{
_configuration = configuration;
}

public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
var source = _configuration.GetSection("Messaging")?["Source"];
if (string.IsNullOrEmpty(source))
{
source = Assembly.GetEntryAssembly().GetName().Name;
}
logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty(PropertyName, source));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Serilog" Version="$(SerilogPackageVersion)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\MultiTenancy\NBB.MultiTenancy.Abstractions\NBB.MultiTenancy.Abstractions.csproj" />
</ItemGroup>
</Project>
76 changes: 76 additions & 0 deletions src/Tools/Serilog/NBB.Tools.Serilog.Enrichers.TenantId/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# NBB.Tools.Serilog.Enrichers.TenantId

This project provides a Serilog Enricher that adds the tenant id to the log context.
It can be the case that logging is requested before tenant identification is requested or that tenant cannot be found. In this case, the empty guid will be set in the context.


## NuGet install
```
dotnet add package NBB.MultiTenancy.Serilog
```
# Registration
The enricher should be registered in `Startup.cs`:

```csharp
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<TenantEnricher>();
...
}
```
# Usage: example for Program.cs
```csharp
var hostBuilder = CreateHostBuilder(args);
var tempLogger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.CreateLogger();

hostBuilder.UseSerilog((context, services, configuration) =>
{
configuration.ReadFrom.Configuration(Configuration);
configuration.Enrich.With(services.GetRequiredService<TenantEnricher>());
...
});
```

# Usage: example for an sql logger configured in appsettings.json
"Serilog": {
"MinimumLevel": "Debug",
"tableName": "TABLE_NAME",
"WriteTo": [
{
"Name": "MSSqlServer",
"Args": {
"connectionString": "Server=SERVER,POST;Database=DB;User Id=USERID;Password=PASS;MultipleActiveResultSets=true",
"tableName": "TABLE_NAME",
"autoCreateSqlTable": false,
"columnOptionsSection": {
"addStandardColumns": [ "LogEvent" ],
"customColumns": [
{
"ColumnName": "TenantId",
"PropertyName": "TenantId",
"DataType": "uniqueidentifier",
"AllowNull": false
},
{
"ColumnName": "OtherId",
"PropertyName": "OtherId",
"DataType": "uniqueidentifier",
"AllowNull": true
}
]
}
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message} T: {TenantId} E: {EnvelopeGuid} N: {FirstName} {LastName} ID: {IdCardIdentifier} EID: {FingerprintId} {NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId", "Tenant" ]
},

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) TotalSoft.
// This source code is licensed under the MIT license.

using NBB.MultiTenancy.Abstractions;
using NBB.MultiTenancy.Abstractions.Context;
using Serilog.Core;
using Serilog.Events;

namespace NBB.Tools.Serilog.Enrichers.TenantId
{
public class TenantEnricher : ILogEventEnricher
{
private readonly ITenantContextAccessor _tenantContextAccessor;
public static string PropertyName { get; } = nameof(Tenant.Default.TenantId);

public TenantEnricher(ITenantContextAccessor tenantContextAccessor)
{
_tenantContextAccessor = tenantContextAccessor;
}

public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
if (_tenantContextAccessor.TenantContext == null)
{
logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty(PropertyName, Tenant.Default.TenantId));
return;
}
var tenantId = _tenantContextAccessor.TenantContext.TryGetTenantId();
logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty(PropertyName, tenantId ?? Tenant.Default.TenantId));
}
}
}
9 changes: 9 additions & 0 deletions src/Tools/Serilog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Serilog tools

NBB serilog tools provide enrichers and sinks for NBB.

The package [`NBB.Tools.Serilog.Enrichers.ServiceIdentifier`](NBB.Tools.Serilog.Enrichers.ServiceIdentifier) provides an enricher for service identifier. It is taken from nbb source / entry assembly name / process name.

The package [`NBB.Tools.Serilog.Enrichers.TenantId`](NBB.Tools.Serilog.Enrichers.TenantId) provides an enricher for tenant id from nbb tenant context.

The package [`NBB.Tools.Serilog.OpenTracingSink`](NBB.Tools.Serilog.OpenTracingSink) provides a sink for serilog and opentracing.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="$(FluentAssertionsPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsPackagesVersion)" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="$(MicrosoftExtensionsPackagesVersion)" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(MicrosoftExtensionsPackagesVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkPackageVersion)" />
<PackageReference Include="Moq" Version="$(MoqPackageVersion)" />
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Tools\Serilog\NBB.Tools.Serilog.Enrichers.ServiceIdentifier\NBB.Tools.Serilog.Enrichers.ServiceIdentifier.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit 9528ffe

Please sign in to comment.