Skip to content

Commit 37e1351

Browse files
committed
Merge branch 'release/v7.2.0'
2 parents 58fc6bc + c43d305 commit 37e1351

12 files changed

Lines changed: 681 additions & 157 deletions

.github/workflows/deploy.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ jobs:
88
strategy:
99
matrix:
1010
dotnet-version: [8.x]
11-
mongodb-version: ['5.0']
12-
11+
1312
steps:
1413
- name: Checkout
1514
uses: actions/checkout@v4
@@ -32,13 +31,8 @@ jobs:
3231
with:
3332
useConfigFile: true
3433

35-
- name: Start MongoDB
36-
uses: supercharge/mongodb-github-action@1.10.0
37-
with:
38-
mongodb-version: ${{ matrix.mongodb-version }}
39-
4034
- name: Run Tests
41-
run: dotnet test
35+
run: dotnet test -p:GeneratePackageOnBuild=false
4236

4337
- name: Pack
4438
run: dotnet build -c Release -p:PackageVersion=${{ steps.gitversion.outputs.nuGetVersion }} -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
7.2.0
2+
* Fixed: MongoDB error handling for v7.x compatibility using error codes instead of string matching (#98, #99) - Thanks to [ntark](https://github.com/ntark)!
3+
* Added: Comprehensive unit tests for MongoDB error handling (#100)
4+
* Improved: CI workflow optimization to skip package generation during test runs
5+
16
7.1.0
27
* Fixed: Guid to BsonValue mapping error (#91)
38
* Fixed: RollingInterval collection naming with proper formatting (#95)

README.md

Lines changed: 145 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,16 @@
77
A Serilog sink that writes events as documents to [MongoDB](http://mongodb.org).
88

99
**Package** - [Serilog.Sinks.MongoDB](http://nuget.org/packages/serilog.sinks.mongodb)
10-
**Platforms** - .NET 4.7.2, .NET 6.0, .NET Standard 2.1
10+
**Platforms** - .NET 4.7.2, .NET 6.0+, .NET Standard 2.1
1111

1212
## Whats New
1313

14-
#### New in v7.x
15-
* Upgrade MongoDB.Driver to v3.0 - .NET Standard 2.0 support has been removed.
14+
See [CHANGES.md](CHANGES.md) for complete version history.
1615

17-
#### New in v6.x
18-
* Upgrade MongoDB.Driver to v2.28.0 (Thanks to [Memoyu](https://github.com/Memoyu))
19-
* Add trace context to LogEntry (Thanks to [fernandovmp](https://github.com/fernandovmp))
20-
21-
#### New in v5.x
22-
* Output structured MongoDB Bson logs by switching to `.MongoDBBson()` extensions. Existing `.MongoDB()` extensions will continue to work converting logs to Json and then to Bson.
23-
* Rolling Log Collection Naming (Thanks to [Revazashvili](https://github.com/Revazashvili) for the PR!). MongoDBBson sink only.
24-
* Expire TTL support. MongoDBBson sink only.
16+
#### New in v7.2
17+
* Fixed MongoDB v7.x compatibility - Error handling now uses error codes instead of string matching (#98, #99)
18+
* Added comprehensive unit tests for MongoDB error handling
19+
* Improved CI performance
2520

2621
## Installation
2722
Install the sink via NuGet Package Manager Console:
@@ -106,21 +101,156 @@ Keys and values are not case-sensitive. This is an example of configuring the Mo
106101
}
107102
},
108103
"WriteTo": [
109-
{
110-
"Name": "MongoDBBson",
111-
"Args": {
104+
{
105+
"Name": "MongoDBBson",
106+
"Args": {
112107
"databaseUrl": "mongodb://username:password@ip:port/dbName?authSource=admin",
113108
"collectionName": "logs",
114109
"cappedMaxSizeMb": "1024",
115110
"cappedMaxDocuments": "50000",
116111
"rollingInterval": "Month"
117112
}
118-
}
113+
}
119114
]
120115
}
121116
}
122117
```
123118

119+
## Advanced Configuration
120+
121+
### Authentication & Secure Connections
122+
123+
For password-protected MongoDB instances, Azure Cosmos DB, or SSL/TLS connections:
124+
125+
```csharp
126+
var log = new LoggerConfiguration()
127+
.WriteTo.MongoDBBson(cfg =>
128+
{
129+
var mongoDbSettings = new MongoClientSettings
130+
{
131+
UseTls = true,
132+
AllowInsecureTls = false, // set true only for dev/testing
133+
Credential = MongoCredential.CreateCredential("databaseName", "username", "password"),
134+
Server = new MongoServerAddress("your-server.com", 27017)
135+
};
136+
137+
var mongoDbInstance = new MongoClient(mongoDbSettings).GetDatabase("logs");
138+
cfg.SetMongoDatabase(mongoDbInstance);
139+
})
140+
.CreateLogger();
141+
```
142+
143+
**Azure Cosmos DB** (MongoDB API):
144+
```csharp
145+
var connectionString = "mongodb://cosmosdb-account:key@cosmosdb-account.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retrywrites=false";
146+
var log = new LoggerConfiguration()
147+
.WriteTo.MongoDBBson(connectionString)
148+
.CreateLogger();
149+
```
150+
151+
### TTL / Auto-Expiration
152+
153+
Automatically delete old logs using MongoDB's TTL feature:
154+
155+
```csharp
156+
var log = new LoggerConfiguration()
157+
.WriteTo.MongoDBBson(cfg =>
158+
{
159+
cfg.SetMongoUrl("mongodb://localhost/logs");
160+
cfg.SetExpireTTL(TimeSpan.FromDays(30)); // logs expire after 30 days
161+
})
162+
.CreateLogger();
163+
```
164+
165+
### Exclude Redundant Fields
166+
167+
Reduce storage costs by excluding the `MessageTemplate` field (the rendered message is still stored):
168+
169+
```csharp
170+
var log = new LoggerConfiguration()
171+
.WriteTo.MongoDBBson(cfg =>
172+
{
173+
cfg.SetMongoUrl("mongodb://localhost/logs");
174+
cfg.SetExcludeMessageTemplate(true); // saves storage space
175+
})
176+
.CreateLogger();
177+
```
178+
179+
### Rolling Collections
180+
181+
Create time-based collections (e.g., one per day/month):
182+
183+
```csharp
184+
var log = new LoggerConfiguration()
185+
.WriteTo.MongoDBBson(cfg =>
186+
{
187+
cfg.SetMongoUrl("mongodb://localhost/logs");
188+
cfg.SetCollectionName("log");
189+
cfg.SetRollingInterval(RollingInterval.Day); // creates: log-20251004, log-20251005, etc.
190+
})
191+
.CreateLogger();
192+
```
193+
194+
**Collection naming patterns:**
195+
- `RollingInterval.Day``log-yyyyMMdd` (e.g., `log-20251004`)
196+
- `RollingInterval.Month``log-yyyyMM` (e.g., `log-202510`)
197+
- `RollingInterval.Year``log-yyyy` (e.g., `log-2025`)
198+
199+
**Querying rolling collections:**
200+
```csharp
201+
// Query specific date range - you need to target the correct collection(s)
202+
var collectionName = $"log-{DateTime.UtcNow:yyyyMMdd}";
203+
var collection = database.GetCollection<BsonDocument>(collectionName);
204+
var todayLogs = collection.Find(Builders<BsonDocument>.Filter.Empty).ToList();
205+
```
206+
207+
## Migration Guide
208+
209+
### From Legacy `.MongoDB()` to `.MongoDBBson()`
210+
211+
The legacy `.MongoDB()` sink converts logs to JSON then to BSON. The newer `.MongoDBBson()` writes structured BSON directly for better performance and features.
212+
213+
**Legacy (still supported):**
214+
```csharp
215+
.WriteTo.MongoDB("mongodb://localhost/logs") // converts to JSON first
216+
```
217+
218+
**New Bson sink (recommended):**
219+
```csharp
220+
.WriteTo.MongoDBBson("mongodb://localhost/logs") // native BSON
221+
```
222+
223+
**MongoDBBson exclusive features:**
224+
- TTL/Expiration (`SetExpireTTL`)
225+
- Exclude message template (`SetExcludeMessageTemplate`)
226+
- Rolling collections (`SetRollingInterval`)
227+
- Better type mapping and performance
228+
229+
## Troubleshooting
230+
231+
### MongoDB Connection Issues
232+
**Problem:** Application hangs or fails when MongoDB is unavailable
233+
**Solution:** Ensure your MongoDB connection string includes appropriate timeouts:
234+
```csharp
235+
"mongodb://localhost/logs?connectTimeoutMS=3000&serverSelectionTimeoutMS=3000"
236+
```
237+
238+
### Type Mapping Errors
239+
**Problem:** `System.Guid cannot be mapped to BsonValue`
240+
**Solution:** Ensure you're using the latest version (v7.1+) which includes Guid mapping fixes.
241+
242+
### Capped Collections Not Created
243+
**Problem:** Capped collection configuration not working
244+
**Solution:** Ensure the collection doesn't already exist. Drop existing collection first:
245+
```csharp
246+
database.DropCollection("logs");
247+
// Then configure with capped settings
248+
```
249+
250+
### Rolling Collections Not Named Correctly
251+
**Problem:** Collection created without time format suffix
252+
**Solution:** Ensure you're using `MongoDBBson` sink (not legacy `MongoDB`) and v7.1+.
253+
124254
## Icon
125255

126256
[MongoDB](https://icons8.com/icon/74402/mongodb) icon by [Icons8](https://icons8.com)

src/Serilog.Sinks.MongoDB/Helpers/MongoDbHelpers.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ internal static void VerifyCollectionExists(
5858
{
5959
database.CreateCollection(collectionName, collectionCreationOptions);
6060
}
61-
catch (MongoCommandException e) when (e.ErrorMessage.Contains(
62-
"collection already exists",
63-
StringComparison.InvariantCultureIgnoreCase))
61+
catch (MongoCommandException e) when (e.CodeName == "NamespaceExists")
6462
{
6563
// handled
6664
}
@@ -89,8 +87,7 @@ internal static void VerifyExpireTTLSetup(
8987

9088
return;
9189
}
92-
catch (MongoCommandException ex) when (ex.ErrorMessage.Contains(
93-
"already exists with different options"))
90+
catch (MongoCommandException ex) when (ex.CodeName == "IndexOptionsConflict")
9491
{
9592
// handled -- just drop and recreate
9693
logCollection.Indexes.DropOne(ExpireTTLIndexName);

src/Serilog.Sinks.MongoDB/Serilog.Sinks.MongoDB.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
</PropertyGroup>
1010

1111
<PropertyGroup>
12-
<PackageVersion>7.1.0</PackageVersion>
12+
<PackageVersion>7.2.0</PackageVersion>
1313
<Authors>Kiran Makkapati, Jaben Cargman, Serilog Contributors</Authors>
14-
<Copyright>Copyright © Serilog Contributors 2014-2022</Copyright>
14+
<Copyright>Copyright © Serilog Contributors 2014-2025</Copyright>
1515
<Description>The MongoDB sink for Serilog</Description>
1616
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
1717
<PackageId>Serilog.Sinks.MongoDB</PackageId>
@@ -20,7 +20,7 @@
2020
<PackageTags>serilog, mongodb</PackageTags>
2121
<PackageReadmeFile>README.md</PackageReadmeFile>
2222
<PackageReleaseNotes>
23-
v7.1 - Bug fixes: Guid to BsonValue mapping (#91), RollingInterval collection naming (#95), SetRollingInterval method name correction (#97).
23+
v7.2 - MongoDB v7.x compatibility fix: Error handling now uses error codes instead of string matching (#98, #99). Comprehensive unit tests added (#100). CI improvements.
2424
</PackageReleaseNotes>
2525
</PropertyGroup>
2626

@@ -43,7 +43,7 @@
4343

4444
<ItemGroup>
4545
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
46-
<PackageReference Include="PolySharp" Version="1.14.1">
46+
<PackageReference Include="PolySharp" Version="1.15.0">
4747
<PrivateAssets>all</PrivateAssets>
4848
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4949
</PackageReference>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Global using directives
2+
3+
global using System.Diagnostics;
4+
5+
global using AwesomeAssertions;
6+
7+
global using EphemeralMongo;
8+
9+
global using Microsoft.Extensions.Configuration;
10+
11+
global using MongoDB.Bson;
12+
global using MongoDB.Bson.Serialization;
13+
global using MongoDB.Bson.Serialization.Serializers;
14+
global using MongoDB.Driver;
15+
16+
global using NSubstitute;
17+
18+
global using NUnit.Framework;
19+
20+
global using Serilog.Events;
21+
global using Serilog.Helpers;

test/Serilog.Sinks.MongoDB.Tests/LoggerConfigurationMongoDBExtensionsTests.cs

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,24 @@
1-
using FluentAssertions;
2-
3-
using Microsoft.Extensions.Configuration;
4-
5-
using MongoDB.Bson;
6-
using MongoDB.Bson.Serialization;
7-
using MongoDB.Bson.Serialization.Serializers;
8-
using MongoDB.Driver;
9-
10-
using NUnit.Framework;
11-
12-
using Serilog.Helpers;
13-
14-
namespace Serilog.Sinks.MongoDB.Tests;
1+
namespace Serilog.Sinks.MongoDB.Tests;
152

163
[TestFixture]
174
public class LoggerConfigurationMongoDbExtensionsTests
185
{
19-
[OneTimeSetUp]
20-
public void SetupMongo()
21-
{
22-
BsonSerializer.TryRegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
23-
}
24-
25-
private const string MongoConnectionString = "mongodb://localhost:27017";
6+
private static string MongoConnectionString => MongoTestFixture.ConnectionString;
267

278
private const string MongoDatabaseName = "mongodb-sink";
289

2910
private const string MongoCollectionName = "test";
3011

12+
private static IReadOnlyDictionary<string, string?> GetSerilogMongoConfiguration()
13+
{
14+
var databaseUrl = $"{MongoConnectionString}/{MongoDatabaseName}";
15+
16+
return new Dictionary<string, string?>
17+
{
18+
["Serilog:WriteTo:0:Args:databaseUrl"] = databaseUrl
19+
};
20+
}
21+
3122
private static void TestCollectionAndDocumentExists(RollingInterval? rollingInterval = null)
3223
{
3324
var (mongoClient, mongoDatabase) = GetDatabase();
@@ -90,6 +81,7 @@ public void Create_Collection_With_Rolling_Interval_From_Configuration()
9081
{
9182
var configuration = new ConfigurationBuilder()
9283
.AddJsonFile("serilog.json")
84+
.AddInMemoryCollection(GetSerilogMongoConfiguration())
9385
.Build();
9486

9587
var collectionName = RollingInterval.Month.GetCollectionName("test");

0 commit comments

Comments
 (0)