diff --git a/README.md b/README.md
index 06fd15c..69a0ec9 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,17 @@
# ![mongo icon](https://raw.githubusercontent.com/ChangemakerStudios/serilog-sinks-mongodb/dev/assets/mongo-icon.png) Serilog.Sinks.MongoDB
-![Build status](https://github.com/ChangemakerStudios/serilog-sinks-mongodb/actions/workflows/deploy.yml/badge.svg)
+[![NuGet version](https://badge.fury.io/nu/Serilog.Sinks.MongoDB.svg)](https://badge.fury.io/nu/Serilog.Sinks.MongoDB)
+[![Downloads](https://img.shields.io/nuget/dt/Serilog.Sinks.MongoDB.svg?logo=nuget&color=purple)](https://www.nuget.org/packages/Serilog.Sinks.MongoDB)
+[![Build status](https://github.com/ChangemakerStudios/serilog-sinks-mongodb/actions/workflows/deploy.yml/badge.svg)](https://github.com/ChangemakerStudios/serilog-sinks-mongodb/actions)
A Serilog sink that writes events as documents to [MongoDB](http://mongodb.org).
**Package** - [Serilog.Sinks.MongoDB](http://nuget.org/packages/serilog.sinks.mongodb)
| **Platforms** - .NET 4.7.2, .NET Standard 2.0,, .NET Standard 2.1
+### New in v6.x
+* Upgraded to MongoDb v2.28 -- fixing breaking changes.
+
### New in v5.x
* Output structured MongoDB Bson logs by switching to the .MongoDBBson() extensions. Existing the .MongoDB() extensions will continue to work converting logs to Json and then to Bson.
* Rolling Log Collection Naming (Thanks to [Revazashvili](https://github.com/Revazashvili) for the PR!). MongoDBBson sink only.
diff --git a/src/Serilog.Sinks.MongoDB/Helpers/MongoDbDocumentHelpers.cs b/src/Serilog.Sinks.MongoDB/Helpers/MongoDbDocumentHelpers.cs
index ce63276..cb31eee 100644
--- a/src/Serilog.Sinks.MongoDB/Helpers/MongoDbDocumentHelpers.cs
+++ b/src/Serilog.Sinks.MongoDB/Helpers/MongoDbDocumentHelpers.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/src/Serilog.Sinks.MongoDB/Helpers/MongoDbHelpers.cs b/src/Serilog.Sinks.MongoDB/Helpers/MongoDbHelpers.cs
index 67625a7..af2a360 100644
--- a/src/Serilog.Sinks.MongoDB/Helpers/MongoDbHelpers.cs
+++ b/src/Serilog.Sinks.MongoDB/Helpers/MongoDbHelpers.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/src/Serilog.Sinks.MongoDB/Helpers/RollingIntervalHelper.cs b/src/Serilog.Sinks.MongoDB/Helpers/RollingIntervalHelper.cs
index f5ea6e8..5f70593 100644
--- a/src/Serilog.Sinks.MongoDB/Helpers/RollingIntervalHelper.cs
+++ b/src/Serilog.Sinks.MongoDB/Helpers/RollingIntervalHelper.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/src/Serilog.Sinks.MongoDB/Helpers/StringHelpers.cs b/src/Serilog.Sinks.MongoDB/Helpers/StringHelpers.cs
index d00a4e5..6b1207c 100644
--- a/src/Serilog.Sinks.MongoDB/Helpers/StringHelpers.cs
+++ b/src/Serilog.Sinks.MongoDB/Helpers/StringHelpers.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/src/Serilog.Sinks.MongoDB/LoggerConfigurationMongoDBExtensions.cs b/src/Serilog.Sinks.MongoDB/LoggerConfigurationMongoDBExtensions.cs
index 09d65d3..96bf3ef 100644
--- a/src/Serilog.Sinks.MongoDB/LoggerConfigurationMongoDBExtensions.cs
+++ b/src/Serilog.Sinks.MongoDB/LoggerConfigurationMongoDBExtensions.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/src/Serilog.Sinks.MongoDB/Serilog.Sinks.MongoDB.csproj b/src/Serilog.Sinks.MongoDB/Serilog.Sinks.MongoDB.csproj
index abb446f..e21fc07 100644
--- a/src/Serilog.Sinks.MongoDB/Serilog.Sinks.MongoDB.csproj
+++ b/src/Serilog.Sinks.MongoDB/Serilog.Sinks.MongoDB.csproj
@@ -9,29 +9,38 @@
- 5.4.0
+ 6.0.0
Kiran Makkapati, Jaben Cargman, Serilog Contributors
Copyright © Serilog Contributors 2014-2022
The MongoDB sink for Serilog
- http://serilog.net/images/serilog-sink-nuget.png
+ Apache-2.0
Serilog.Sinks.MongoDB
http://serilog.net
- https://github.com/ChangemakerStudios/serilog-sinks-mongodb
- git
+ serilog-sink-nuget.png
serilog, mongodb
README.md
- v5.4 - Upgraded to MongoDB.Driver to version 2.19 due to vulnerabilities.
+ v6.0 - Upgraded to MongoDB.Driver to version 2.28 due to incompatibilities.
+ https://github.com/ChangemakerStudios/serilog-sinks-mongodb
+ git
true
true
true
snupkg
+
+ true
+
+
+
+
+
+
@@ -41,10 +50,10 @@
-
+
-
+
diff --git a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/LogEntry.cs b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/LogEntry.cs
index e78458d..72cea66 100644
--- a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/LogEntry.cs
+++ b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/LogEntry.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
// limitations under the License.
using System;
+using System.Diagnostics;
using System.Linq;
using MongoDB.Bson;
@@ -33,6 +34,7 @@ public class LogEntry
public DateTime UtcTimeStamp { get; set; }
+ [BsonIgnoreIfNull]
public MessageTemplate? MessageTemplate { get; set; }
public string? RenderedMessage { get; set; }
@@ -40,22 +42,34 @@ public class LogEntry
public BsonDocument? Properties { get; set; }
public BsonDocument? Exception { get; set; }
+ [BsonIgnoreIfNull]
+ public string? TraceId { get; set; }
+ [BsonIgnoreIfNull]
+ public string? SpanId { get; set; }
- public static LogEntry MapFrom(LogEvent logEvent)
+ public static LogEntry MapFrom(LogEvent logEvent, bool includeMessageTemplate)
{
if (logEvent == null) throw new ArgumentNullException(nameof(logEvent));
- return new LogEntry
+ var logEntry = new LogEntry
+ {
+ RenderedMessage = logEvent.RenderMessage(),
+ Level = logEvent.Level,
+ UtcTimeStamp = logEvent.Timestamp.ToUniversalTime().UtcDateTime,
+ TraceId = logEvent.TraceId?.ToString(),
+ SpanId = logEvent.SpanId?.ToString(),
+ Exception = logEvent.Exception?.ToBsonDocument().SanitizeDocumentRecursive(),
+ Properties = BsonDocument.Create(
+ logEvent.Properties.ToDictionary(
+ s => s.Key.SanitizedElementName(),
+ s => s.Value.ToBsonValue()))
+ };
+
+ if (includeMessageTemplate)
{
- MessageTemplate = logEvent.MessageTemplate,
- RenderedMessage = logEvent.RenderMessage(),
- Level = logEvent.Level,
- UtcTimeStamp = logEvent.Timestamp.ToUniversalTime().UtcDateTime,
- Exception = logEvent.Exception?.ToBsonDocument().SanitizeDocumentRecursive(),
- Properties = BsonDocument.Create(
- logEvent.Properties.ToDictionary(
- s => s.Key.SanitizedElementName(),
- s => s.Value.ToBsonValue()))
- };
+ logEntry.MessageTemplate = logEvent.MessageTemplate;
+ }
+
+ return logEntry;
}
}
\ No newline at end of file
diff --git a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBJsonFormatter.cs b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBJsonFormatter.cs
index 619e86a..d7276cb 100644
--- a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBJsonFormatter.cs
+++ b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBJsonFormatter.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -84,7 +84,7 @@ protected override void WriteJsonProperty(
}
else
{
- base.WriteJsonProperty(name, value, ref precedingDelimiter, output);
+ base.WriteJsonProperty(name, value!, ref precedingDelimiter, output);
}
}
diff --git a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSink.cs b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSink.cs
index 91d4d70..725dc4c 100644
--- a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSink.cs
+++ b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSink.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,9 +14,11 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
+using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using Serilog.Events;
@@ -37,6 +39,10 @@ static MongoDBSink()
cm.MapProperty(s => s.StackTrace);
cm.MapProperty(s => s.Data);
});
+
+ // fixes https://github.com/serilog/serilog/issues/2101
+ BsonTypeMapper.RegisterCustomTypeMapper(typeof(IntPtr), new CustomIntPtrMapper());
+ BsonTypeMapper.RegisterCustomTypeMapper(typeof(UIntPtr), new CustomIntPtrMapper());
}
public MongoDBSink(MongoDBSinkConfiguration configuration)
@@ -46,6 +52,26 @@ public MongoDBSink(MongoDBSinkConfiguration configuration)
public override Task EmitBatchAsync(IEnumerable events)
{
- return this.InsertMany(events.Select(LogEntry.MapFrom));
+ return this.InsertMany(
+ events.Select(@event => LogEntry.MapFrom(@event, this.IncludeMessageTemplate)));
+ }
+
+ private class CustomIntPtrMapper : ICustomBsonTypeMapper
+ {
+ public bool TryMapToBsonValue(object value, [UnscopedRef] out BsonValue? bsonValue)
+ {
+ switch (value)
+ {
+ case IntPtr intPtr:
+ bsonValue = intPtr.ToInt32();
+ return true;
+ case UIntPtr uIntPtr:
+ bsonValue = uIntPtr.ToUInt32();
+ return true;
+ default:
+ bsonValue = null;
+ return false;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkBase.cs b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkBase.cs
index a7fe84f..38f2eec 100644
--- a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkBase.cs
+++ b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkBase.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@ public abstract class MongoDBSinkBase : IBatchedLogEventSink
///
protected MongoDBSinkBase(MongoDBSinkConfiguration configuration)
{
- if (configuration == null) throw new ArgumentNullException(nameof(configuration));
+ if (configuration! == null) throw new ArgumentNullException(nameof(configuration));
this._configuration = configuration;
@@ -51,6 +51,8 @@ protected MongoDBSinkBase(MongoDBSinkConfiguration configuration)
LazyThreadSafetyMode.ExecutionAndPublication);
}
+ protected bool IncludeMessageTemplate => !this._configuration.ExcludeMessageTemplate;
+
protected string CollectionName => this._configuration.CollectionName;
protected RollingInterval RollingInterval => this._configuration.RollingInterval;
diff --git a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkConfiguration.cs b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkConfiguration.cs
index b5b5b6a..8bf4b46 100644
--- a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkConfiguration.cs
+++ b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkConfiguration.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -38,6 +38,8 @@ public class MongoDBSinkConfiguration
public bool Legacy { get; internal set; }
+ public bool ExcludeMessageTemplate { get; internal set; }
+
public InsertManyOptions? InsertManyOptions { get; internal set; }
public RollingInterval RollingInterval { get; private set; } = RollingInterval.Infinite;
@@ -58,6 +60,11 @@ public void Validate()
throw new ArgumentNullException(
nameof(this.ExpireTTL),
"Expiration TTL is only supported on the MongoDBBson Sink");
+
+ if (this.ExcludeMessageTemplate && this.Legacy)
+ throw new ArgumentNullException(
+ nameof(this.ExcludeMessageTemplate),
+ "Exclude Message Template is only supported on the MongoDBBson Sink");
}
///
@@ -88,6 +95,17 @@ public void SetExpireTTL(TimeSpan? timeToLive)
this.ExpireTTL = timeToLive;
}
+ ///
+ /// Sets if the log should include the "MessageTemplate" field,
+ /// as the RenderedMessage field is already included the "MessageTemplate"
+ /// may be unnecessary/redundant.
+ ///
+ ///
+ public void SetExcludeMessageTemplate(bool excludeMessageTemplate)
+ {
+ this.ExcludeMessageTemplate = excludeMessageTemplate;
+ }
+
///
/// Allows configuring "InsertManyOptions" in MongoDb.
///
diff --git a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkDefaults.cs b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkDefaults.cs
index a2717aa..ee56d82 100644
--- a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkDefaults.cs
+++ b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkDefaults.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkLegacy.cs b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkLegacy.cs
index 7fc63a6..9a0491f 100644
--- a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkLegacy.cs
+++ b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/MongoDBSinkLegacy.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/RollingInterval.cs b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/RollingInterval.cs
index 7c1422f..8dd3eb6 100644
--- a/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/RollingInterval.cs
+++ b/src/Serilog.Sinks.MongoDB/Sinks/MongoDB/RollingInterval.cs
@@ -1,4 +1,4 @@
-// Copyright 2014-2022 Serilog Contributors
+// Copyright 2014-2024 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/src/Serilog.Sinks.MongoDB/serilog-sink-nuget.png b/src/Serilog.Sinks.MongoDB/serilog-sink-nuget.png
new file mode 100644
index 0000000..a77d65c
Binary files /dev/null and b/src/Serilog.Sinks.MongoDB/serilog-sink-nuget.png differ
diff --git a/test/Serilog.Sinks.MongoDB.Tests/LoggerWithTraceIdTests.cs b/test/Serilog.Sinks.MongoDB.Tests/LoggerWithTraceIdTests.cs
new file mode 100644
index 0000000..ad65844
--- /dev/null
+++ b/test/Serilog.Sinks.MongoDB.Tests/LoggerWithTraceIdTests.cs
@@ -0,0 +1,108 @@
+using FluentAssertions;
+
+using Microsoft.Extensions.Configuration;
+
+using MongoDB.Driver;
+
+using Serilog.Helpers;
+
+namespace Serilog.Sinks.MongoDB.Tests;
+
+using System.Diagnostics;
+using NUnit.Framework;
+
+[TestFixture]
+public class LoggerWithTraceIdTests
+{
+ private const string MongoConnectionString = "mongodb://localhost:27017";
+
+ private const string MongoDatabaseName = "mongodb-sink";
+
+ private static (MongoClient, IMongoDatabase) GetDatabase()
+ {
+ var mongoClient = new MongoClient(MongoConnectionString);
+ return (mongoClient, mongoClient.GetDatabase(MongoDatabaseName));
+ }
+
+ [Test]
+ public void Log_Without_Activity_Should_Have_TraceId_And_SpanId_Null()
+ {
+ var configuration = new ConfigurationBuilder()
+ .AddJsonFile("serilog.json")
+ .Build();
+
+ var collectionName = RollingInterval.Month.GetCollectionName("test");
+
+ const string Message = "some message logged into mongodb without activity";
+
+ using (var logger = new LoggerConfiguration()
+ .ReadFrom.Configuration(configuration)
+ .CreateLogger())
+ {
+ logger.Information(Message);
+ }
+
+ var (mongoClient, mongoDatabase) = GetDatabase();
+ var collectionExists = mongoDatabase.CollectionExists(collectionName);
+
+ collectionExists.Should().BeTrue();
+
+ var mongoCollection = mongoDatabase.GetCollection(collectionName);
+ var document = mongoCollection.Find(x => x.RenderedMessage == Message).FirstOrDefault();
+
+ document.Should().NotBeNull();
+ document.TraceId.Should().BeNull();
+ document.SpanId.Should().BeNull();
+
+ mongoClient.DropDatabase(MongoDatabaseName);
+ }
+
+ [Test]
+ public void Log_Within_Activity_Should_Have_TraceId_And_SpanId_Not_Null()
+ {
+ ActivityTraceId traceId;
+ ActivitySpanId spanId;
+
+ var configuration = new ConfigurationBuilder()
+ .AddJsonFile("serilog.json")
+ .Build();
+
+ var collectionName = RollingInterval.Month.GetCollectionName("test");
+
+ const string Message = "some message logged into mongodb within an activity";
+
+ using (var logger = new LoggerConfiguration()
+ .ReadFrom.Configuration(configuration)
+ .CreateLogger())
+ {
+ var activitySource = new ActivitySource("Serilog.Sinks.MongoDB.Tests");
+ var activityListener = new ActivityListener
+ {
+ ShouldListenTo = s => true,
+ SampleUsingParentId = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData,
+ Sample = (ref ActivityCreationOptions activityOptions) => ActivitySamplingResult.AllData
+ };
+ ActivitySource.AddActivityListener(activityListener);
+ using (var activity = activitySource.StartActivity("LogTest"))
+ {
+ traceId = activity.TraceId;
+ spanId = activity.SpanId;
+ logger.Information(Message);
+ }
+ }
+
+ var (mongoClient, mongoDatabase) = GetDatabase();
+ var collectionExists = mongoDatabase.CollectionExists(collectionName);
+
+ collectionExists.Should().BeTrue();
+
+ var mongoCollection = mongoDatabase.GetCollection(collectionName);
+ var document = mongoCollection.Find(x => x.RenderedMessage == Message).FirstOrDefault();
+
+ document.Should().NotBeNull();
+ document.TraceId.Should().Be(traceId.ToString());
+ document.SpanId.Should().Be(spanId.ToString());
+
+ mongoClient.DropDatabase(MongoDatabaseName);
+ }
+}
\ No newline at end of file
diff --git a/test/Serilog.Sinks.MongoDB.Tests/Serilog.Sinks.MongoDB.Tests.csproj b/test/Serilog.Sinks.MongoDB.Tests/Serilog.Sinks.MongoDB.Tests.csproj
index f7147d0..9586d50 100644
--- a/test/Serilog.Sinks.MongoDB.Tests/Serilog.Sinks.MongoDB.Tests.csproj
+++ b/test/Serilog.Sinks.MongoDB.Tests/Serilog.Sinks.MongoDB.Tests.csproj
@@ -6,12 +6,12 @@
-
+
-
-
-
+
+
+