Skip to content

4.0.0 Release #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ae084a1
Dev version bump [skip ci]
nblumhardt May 2, 2019
196d05d
code cleanup
sungam3r May 4, 2019
088e235
Merge pull request #13 from sungam3r/cleanup
nblumhardt May 8, 2019
71e875f
WithThreadName() added to readme
StefanOssendorf May 31, 2019
7b72dc8
Example completed
StefanOssendorf May 31, 2019
17b7e55
Merge pull request #14 from StefanOssendorf/feature/readme-update
nblumhardt Jun 2, 2019
a30040a
Dev version bump [skip ci]
nblumhardt Jun 23, 2019
2a4b62d
add simple caching into enrichers
sungam3r Sep 2, 2019
a049f43
Merge pull request #16 from sungam3r/caching
nblumhardt Sep 2, 2019
aae2678
Update CI build to VS 2019
Numpsy Feb 13, 2021
82cc03d
Replace PackageLicenseUrl with PackageLicenseExpression
Numpsy Feb 13, 2021
cd042be
Replace PackageIconUrl with PackageIcon
Numpsy Feb 13, 2021
8e333aa
Merge pull request #18 from Numpsy/rw/build_updates
nblumhardt Feb 15, 2021
e45190a
NuGet key - fixes #19
nblumhardt Feb 26, 2021
e7af135
Update Serilog dependency version
bdovaz May 7, 2021
3ab44ec
Merge pull request #20 from bdovaz/dev
nblumhardt May 11, 2021
a81eac0
build on VS 2022
SimonCropp Feb 3, 2023
f51900f
Enable nullability annotations in the project
Numpsy Nov 12, 2023
9c4ce63
Merge pull request #21 from Numpsy/nullable
nblumhardt Nov 13, 2023
db33d4f
New publishing key
nblumhardt Nov 14, 2023
71d1978
Update TFMs
Numpsy Jun 11, 2024
5b2ce01
Update to Serilog 4
Numpsy Jun 11, 2024
b33c2d5
Internalize and seal enricher classes
Numpsy Jun 11, 2024
a680e47
Remove AssemblyInfo.cs
Numpsy Jun 11, 2024
bc89a83
Remove note about WithThreadName() only working on some .NET versions…
Numpsy Jun 11, 2024
14cf778
Add the readme file to the nuget package
Numpsy Jun 11, 2024
4310b34
Set version to 4.0
Numpsy Jun 11, 2024
cf57f9f
Remove GenerateAssemblyVersionAttribute=false
Numpsy Jun 13, 2024
3d45ace
Publish a .snupkg
Numpsy Jun 13, 2024
602315b
Merge pull request #22 from Numpsy/updates
nblumhardt Jun 14, 2024
a070918
Branch name in build.ps1
nblumhardt Jun 14, 2024
a692515
Update publishing key, branch names
nblumhardt Jun 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ if(Test-Path .\artifacts) {

$branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$env:APPVEYOR_REPO_BRANCH -ne $NULL];
$revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL];
$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "master" -and $revision -ne "local"]
$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "main" -and $revision -ne "local"]

echo "build: Version suffix is $suffix"

Expand All @@ -20,7 +20,7 @@ foreach ($src in ls src/*) {

echo "build: Packaging project in $src"

& dotnet pack -c Release -o ..\..\artifacts --version-suffix=$suffix
& dotnet pack -c Release -o ..\..\artifacts --version-suffix=$suffix -p:ContinuousIntegrationBuild=true
if($LASTEXITCODE -ne 0) { exit 1 }

Pop-Location
Expand Down
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Serilog.Enrichers.Thread [![Build status](https://ci.appveyor.com/api/projects/status/2vgxdy3swg6eaj3f?svg=true)](https://ci.appveyor.com/project/serilog/serilog-enrichers-thread) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Enrichers.Thread.svg?style=flat)](https://www.nuget.org/packages/Serilog.Enrichers.Thread/)

Enrich Serilog events with properties from the current thread.

### Getting started

Install the package from NuGet:
Expand All @@ -10,43 +10,59 @@ Install the package from NuGet:
Install-Package Serilog.Enrichers.Thread
```

In your logger configuration, apply `Enrich.WithThreadId()`:
In your logger configuration, apply `Enrich.WithThreadId()` and `Enrich.WithThreadName()`:

```csharp
Log.Logger = new LoggerConfiguration()
.Enrich.WithThreadId()
.Enrich.WithThreadName()
.CreateLogger();
```

Many sinks simply include all properties without further action required, so the thread id will be logged automatically.
However, some sinks, such as the File and Console sinks use an output template and the new ThreadId may not be automatically output in your sink. In this case, in order for the ThreadId to show up in the logging, you will need to create or modify your output template.
However, some sinks, such as the File and Console sinks use an output template and the new `ThreadId` may not be automatically output in your sink. In this case, in order for the `ThreadId` or `ThreadName` to show up in the logging, you will need to create or modify your output template.

```csharp
w.File(...., outputTemplate:
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} {Properties}{NewLine}{Exception}")
```
Here, {Properties} can include not only ThreadId, but any other enrichment which is applied. Alternatively, {ThreadId} could be used instead, if you want to only add the thread id enrichment.
Here, \{Properties} can include not only `ThreadId` and `ThreadName`, but any other enrichment which is applied. Alternatively, \{ThreadId} could be used instead, if you want to only add the thread id enrichment and \{ThreadName}, if you want to only add the thread name enrichment.

An example, which also uses the Serilogs.Sinks.Async Nuget package, is below:

```csharp
Thread.CurrentThread.Name = "MyWorker";

var logger = Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(restrictedToMinimumLevel:Serilog.Events.LogEventLevel.Information)
.WriteTo.Async(w=>w.File("..\\..\\..\\..\\logs\\SerilogLogFile.json", rollingInterval: RollingInterval.Day, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} <{ThreadId}>{NewLine}{Exception}"))
.WriteTo.Async(w=>w.File("..\\..\\..\\..\\logs\\SerilogLogFile.json", rollingInterval: RollingInterval.Day, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} <{ThreadId}><{ThreadName}>{NewLine}{Exception}"))
.Enrich.WithThreadId()
.CreateLogger();
```
Which would produce an output in the log file as follows:
```
2018-04-06 13:12:45.684 +02:00 [ERR] The file file_name.svg does not exist <4>
2018-04-06 13:12:45.684 +02:00 [ERR] The file file_name.svg does not exist <4><MyWorker>
```
Where, <4> is an example thread id.
Where, <4> is an example thread id and \<MyWorker> is an example thread name.

To use the enricher, first install the NuGet package:

```powershell
Install-Package Serilog.Enrichers.Thread
```

Note:
The \{ThreadName} property will only be attached when it is not null. Otherwise it will be omitted.
If you want to get this property always attached you can use the following:
```csharp
using Serilog.Enrichers;

Log.Logger = new LoggerConfiguration()
.Enrich.WithThreadName()
.Enrich.WithProperty(ThreadNameEnricher.ThreadNamePropertyName, "MyDefault")
.CreateLogger();
```
The enrichment order is important. Otherwise "MyDefault" would always win.

Copyright &copy; 2016 Serilog Contributors - Provided under the [Apache License, Version 2.0](http://apache.org/licenses/LICENSE-2.0.html).
13 changes: 8 additions & 5 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
version: '{build}'
skip_tags: true
image: Visual Studio 2017
image: Visual Studio 2022
configuration: Release
build_script:
- ps: ./Build.ps1
test: off
artifacts:
- path: artifacts/Serilog.*.nupkg
- path: artifacts/Serilog.*.snupkg
deploy:
- provider: NuGet
api_key:
secure: N59tiJECUYpip6tEn0xvdmDAEiP9SIzyLEFLpwiigm/8WhJvBNs13QxzT1/3/JW/
secure: Fh92tRIFbe1FAiyD8lTThWgAorQ1vV+eFYMlUK0iLHBBenJcy/UYc1qj6kgHvUcO
skip_symbols: true
on:
branch: /^(master|dev)$/
branch: /^(main|dev)$/
- provider: GitHub
auth_token:
secure: p4LpVhBKxGS5WqucHxFQ5c7C8cP74kbNB0Z8k9Oxx/PMaDQ1+ibmoexNqVU5ZlmX
artifact: /Serilog.*\.nupkg/
artifacts:
/Serilog.*\.nupkg/
/Serilog.*\.snupkg/
tag: v$(appveyor_build_version)
on:
branch: master
branch: main
Binary file added assets/serilog-enricher-nuget.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion global.json

This file was deleted.

6 changes: 2 additions & 4 deletions serilog-enrichers-thread.sln
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.329
# Visual Studio Version 17
VisualStudioVersion = 17.10.34928.147
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{037440DE-440B-4129-9F7A-09B42D00397E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{E9D1B5E1-DEB9-4A04-8BAB-24EC7240ADAF}"
ProjectSection(SolutionItems) = preProject
Build.ps1 = Build.ps1
global.json = global.json
NuGet.Config = NuGet.Config
README.md = README.md
assets\Serilog.snk = assets\Serilog.snk
EndProjectSection
Expand Down
19 changes: 15 additions & 4 deletions src/Serilog.Enrichers.Thread/Enrichers/ThreadIdEnricher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using System.Threading;
using Serilog.Core;
using Serilog.Events;
using System;
Expand All @@ -22,12 +21,17 @@ namespace Serilog.Enrichers
/// <summary>
/// Enriches log events with a ThreadId property containing the <see cref="Environment.CurrentManagedThreadId"/>.
/// </summary>
public class ThreadIdEnricher : ILogEventEnricher
sealed class ThreadIdEnricher : ILogEventEnricher
{
/// <summary>
/// The property name added to enriched log events.
/// </summary>
public const string ThreadIdPropertyName = "ThreadId";
const string ThreadIdPropertyName = "ThreadId";

/// <summary>
/// The cached last created "ThreadId" property with some thread id. It is likely to be reused frequently so avoiding heap allocations.
/// </summary>
private LogEventProperty? _lastValue;

/// <summary>
/// Enrich the log event.
Expand All @@ -36,7 +40,14 @@ public class ThreadIdEnricher : ILogEventEnricher
/// <param name="propertyFactory">Factory for creating new properties to add to the event.</param>
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
logEvent.AddPropertyIfAbsent(new LogEventProperty(ThreadIdPropertyName, new ScalarValue(Environment.CurrentManagedThreadId)));
var threadId = Environment.CurrentManagedThreadId;

var last = _lastValue;
if (last is null || (int)((ScalarValue)last.Value).Value! != threadId)
// no need to synchronize threads on write - just some of them will win
_lastValue = last = new LogEventProperty(ThreadIdPropertyName, new ScalarValue(threadId));

logEvent.AddPropertyIfAbsent(last);
}
}
}
23 changes: 15 additions & 8 deletions src/Serilog.Enrichers.Thread/Enrichers/ThreadNameEnricher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#if THREAD_NAME
using System.Threading;
using Serilog.Core;
using Serilog.Events;

namespace Serilog.Enrichers
{

/// <summary>
/// Enriches log events with a ThreadName property containing the
/// Enriches log events with a ThreadName property containing the <see cref="Thread.CurrentThread"/> <see cref="Thread.Name"/>.
/// </summary>
public class ThreadNameEnricher : ILogEventEnricher
sealed class ThreadNameEnricher : ILogEventEnricher
{
/// <summary>
/// The property name added to enriched log events.
/// </summary>
public const string ThreadNamePropertyName = "ThreadName";
const string ThreadNamePropertyName = "ThreadName";

/// <summary>
/// The cached last created "ThreadName" property with some thread name. It is likely to be reused frequently so avoiding heap allocations.
/// </summary>
private LogEventProperty? _lastValue;

/// <summary>
/// Enrich the log event.
Expand All @@ -38,11 +41,15 @@ public class ThreadNameEnricher : ILogEventEnricher
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
var threadName = Thread.CurrentThread.Name;
if (threadName != null)
if (threadName is not null)
{
logEvent.AddPropertyIfAbsent(new LogEventProperty(ThreadNamePropertyName, new ScalarValue(threadName)));
var last = _lastValue;
if (last is null || (string)((ScalarValue)last.Value).Value! != threadName)
// no need to synchronize threads on write - just some of them will win
_lastValue = last = new LogEventProperty(ThreadNamePropertyName, new ScalarValue(threadName));

logEvent.AddPropertyIfAbsent(last);
}
}
}
}
#endif
6 changes: 0 additions & 6 deletions src/Serilog.Enrichers.Thread/Properties/AssemblyInfo.cs

This file was deleted.

43 changes: 25 additions & 18 deletions src/Serilog.Enrichers.Thread/Serilog.Enrichers.Thread.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>Enrich Serilog events with properties from the current thread.</Description>
<VersionPrefix>3.1.0</VersionPrefix>
<VersionPrefix>4.0.0</VersionPrefix>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<Authors>Serilog Contributors</Authors>
<TargetFrameworks>net45;netstandard1.0;netstandard2.0</TargetFrameworks>
<!-- .NET Framework version targeting is frozen at these two TFMs. -->
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net471;net462</TargetFrameworks>
<!-- Policy is to trim TFM-specific builds to `netstandard2.0`, `net6.0`,
all active LTS versions, and optionally the latest RTM version, when releasing new
major Serilog versions. -->
<TargetFrameworks>$(TargetFrameworks);net8.0;net6.0;netstandard2.0</TargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>Serilog.Enrichers.Thread</AssemblyName>
Expand All @@ -13,27 +19,28 @@
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageId>Serilog.Enrichers.Thread</PackageId>
<PackageTags>serilog;thread;enricher</PackageTags>
<PackageIconUrl>http://serilog.net/images/serilog-enricher-nuget.png</PackageIconUrl>
<PackageIcon>serilog-enricher-nuget.png</PackageIcon>
<PackageProjectUrl>http://serilog.net</PackageProjectUrl>
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Serilog" Version="2.3.0" />
<PackageReference Include="Serilog" Version="4.0.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
<ItemGroup>
<None Include="..\..\assets\serilog-enricher-nuget.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
<None Include="../../README.md" Pack="true" Visible="false" PackagePath="/" />
</ItemGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'net45' ">
<DefineConstants>$(DefineConstants);THREAD_NAME</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<DefineConstants>$(DefineConstants);THREAD_NAME</DefineConstants>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.


using System;
using System.Threading;
using Serilog.Configuration;
Expand All @@ -21,7 +20,7 @@
namespace Serilog
{
/// <summary>
/// Extends <see cref="LoggerConfiguration"/> to add enrichers for <see cref="Environment.CurrentManagedThreadId"/>.
/// Extends <see cref="LoggerConfiguration"/> to add enrichers for <see cref="Environment.CurrentManagedThreadId"/>
/// capabilities.
/// </summary>
public static class ThreadLoggerConfigurationExtensions
Expand All @@ -31,26 +30,25 @@ public static class ThreadLoggerConfigurationExtensions
/// </summary>
/// <param name="enrichmentConfiguration">Logger enrichment configuration.</param>
/// <returns>Configuration object allowing method chaining.</returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentNullException">If <paramref name="enrichmentConfiguration"/> is null.</exception>
public static LoggerConfiguration WithThreadId(
this LoggerEnrichmentConfiguration enrichmentConfiguration)
{
if (enrichmentConfiguration == null) throw new ArgumentNullException(nameof(enrichmentConfiguration));
return enrichmentConfiguration.With<ThreadIdEnricher>();
}

#if THREAD_NAME
/// <summary>
/// Enrich log events with a ThreadName property containing the <see cref="Thread.CurrentThread"/> <see cref="Thread.Name"/>.
/// </summary>
/// <param name="enrichmentConfiguration"></param>
/// <returns></returns>
/// <param name="enrichmentConfiguration">Logger enrichment configuration.</param>
/// <returns>Configuration object allowing method chaining.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="enrichmentConfiguration"/> is null.</exception>
public static LoggerConfiguration WithThreadName(
this LoggerEnrichmentConfiguration enrichmentConfiguration)
{
if (enrichmentConfiguration == null) throw new ArgumentNullException(nameof(enrichmentConfiguration));
return enrichmentConfiguration.With<ThreadNameEnricher>();
}
#endif
}
}