A Serilog sink that writes events as documents to MongoDB.
Package - Serilog.Sinks.MongoDB Platforms - .NET 4.7.2, .NET 6.0+, .NET Standard 2.1
- Upgrade MongoDB.Driver to v3.0 - .NET Standard 2.0 support has been removed.
- Upgrade MongoDB.Driver to v2.28.0 (Thanks to Memoyu)
- Add trace context to LogEntry (Thanks to fernandovmp)
- 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. - Rolling Log Collection Naming (Thanks to Revazashvili for the PR!). MongoDBBson sink only.
- Expire TTL support. MongoDBBson sink only.
Install the sink via NuGet Package Manager Console:
Install-Package Serilog.Sinks.MongoDB
or via the .NET CLI:
dotnet add package Serilog.Sinks.MongoDB
In the examples below, the sink is writing to the database logs
with structured Bson. The default collection name is log
, but a custom collection can be supplied with the optional CollectionName
parameter. The database and collection will be created if they do not exist.
using Serilog;
// use BSON structured logs
var log = new LoggerConfiguration()
.WriteTo.MongoDBBson("mongodb://mymongodb/logs")
.CreateLogger();
log.Information("This is a test log message");
// capped collection using BSON structured logs
var log = new LoggerConfiguration()
.WriteTo.MongoDBBson("mongodb://mymongodb/logs", cfg =>
{
// optional configuration options:
cfg.SetCollectionName("log");
cfg.SetBatchPeriod(TimeSpan.FromSeconds(1));
// create capped collection that is max 100mb
cfg.SetCreateCappedCollection(100);
})
.CreateLogger();
// create sink instance with custom mongodb settings.
var log = new LoggerConfiguration()
.WriteTo.MongoDBBson(cfg =>
{
// custom MongoDb configuration
var mongoDbSettings = new MongoClientSettings
{
UseTls = true,
AllowInsecureTls = true,
Credential = MongoCredential.CreateCredential("databaseName", "username", "password"),
Server = new MongoServerAddress("127.0.0.1")
};
var mongoDbInstance = new MongoClient(mongoDbSettings).GetDatabase("serilog");
// sink will use the IMongoDatabase instance provided
cfg.SetMongoDatabase(mongoDbInstance);
cfg.SetRollingInterval(RollingInterval.Month);
})
.CreateLogger();
Keys and values are not case-sensitive. This is an example of configuring the MongoDB sink arguments from Appsettings.json:
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Error",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "MongoDBBson",
"Args": {
"databaseUrl": "mongodb://username:password@ip:port/dbName?authSource=admin",
"collectionName": "logs",
"cappedMaxSizeMb": "1024",
"cappedMaxDocuments": "50000",
"rollingInterval": "Month"
}
}
]
}
}
For password-protected MongoDB instances, Azure Cosmos DB, or SSL/TLS connections:
var log = new LoggerConfiguration()
.WriteTo.MongoDBBson(cfg =>
{
var mongoDbSettings = new MongoClientSettings
{
UseTls = true,
AllowInsecureTls = false, // set true only for dev/testing
Credential = MongoCredential.CreateCredential("databaseName", "username", "password"),
Server = new MongoServerAddress("your-server.com", 27017)
};
var mongoDbInstance = new MongoClient(mongoDbSettings).GetDatabase("logs");
cfg.SetMongoDatabase(mongoDbInstance);
})
.CreateLogger();
Azure Cosmos DB (MongoDB API):
var connectionString = "mongodb://cosmosdb-account:[email protected]:10255/?ssl=true&replicaSet=globaldb&retrywrites=false";
var log = new LoggerConfiguration()
.WriteTo.MongoDBBson(connectionString)
.CreateLogger();
Automatically delete old logs using MongoDB's TTL feature:
var log = new LoggerConfiguration()
.WriteTo.MongoDBBson(cfg =>
{
cfg.SetMongoUrl("mongodb://localhost/logs");
cfg.SetExpireTTL(TimeSpan.FromDays(30)); // logs expire after 30 days
})
.CreateLogger();
Reduce storage costs by excluding the MessageTemplate
field (the rendered message is still stored):
var log = new LoggerConfiguration()
.WriteTo.MongoDBBson(cfg =>
{
cfg.SetMongoUrl("mongodb://localhost/logs");
cfg.SetExcludeMessageTemplate(true); // saves storage space
})
.CreateLogger();
Create time-based collections (e.g., one per day/month):
var log = new LoggerConfiguration()
.WriteTo.MongoDBBson(cfg =>
{
cfg.SetMongoUrl("mongodb://localhost/logs");
cfg.SetCollectionName("log");
cfg.SetRollingInterval(RollingInterval.Day); // creates: log-20251004, log-20251005, etc.
})
.CreateLogger();
Collection naming patterns:
RollingInterval.Day
→log-yyyyMMdd
(e.g.,log-20251004
)RollingInterval.Month
→log-yyyyMM
(e.g.,log-202510
)RollingInterval.Year
→log-yyyy
(e.g.,log-2025
)
Querying rolling collections:
// Query specific date range - you need to target the correct collection(s)
var collectionName = $"log-{DateTime.UtcNow:yyyyMMdd}";
var collection = database.GetCollection<BsonDocument>(collectionName);
var todayLogs = collection.Find(Builders<BsonDocument>.Filter.Empty).ToList();
The legacy .MongoDB()
sink converts logs to JSON then to BSON. The newer .MongoDBBson()
writes structured BSON directly for better performance and features.
Legacy (still supported):
.WriteTo.MongoDB("mongodb://localhost/logs") // converts to JSON first
New Bson sink (recommended):
.WriteTo.MongoDBBson("mongodb://localhost/logs") // native BSON
MongoDBBson exclusive features:
- TTL/Expiration (
SetExpireTTL
) - Exclude message template (
SetExcludeMessageTemplate
) - Rolling collections (
SetRollingInterval
) - Better type mapping and performance
Problem: Application hangs or fails when MongoDB is unavailable Solution: Ensure your MongoDB connection string includes appropriate timeouts:
"mongodb://localhost/logs?connectTimeoutMS=3000&serverSelectionTimeoutMS=3000"
Problem: System.Guid cannot be mapped to BsonValue
Solution: Ensure you're using the latest version (v7.1+) which includes Guid mapping fixes.
Problem: Capped collection configuration not working Solution: Ensure the collection doesn't already exist. Drop existing collection first:
database.DropCollection("logs");
// Then configure with capped settings
Problem: Collection created without time format suffix
Solution: Ensure you're using MongoDBBson
sink (not legacy MongoDB
) and v7.1+.