Code
·
64 lines
·
2702 bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
namespace VanDerHeijden.Logging.MongoDb;
/// <summary>
/// Represents a single log entry stored in MongoDB.
/// </summary>
public class LogEntry
{
/// <summary>Gets or sets the MongoDB document identifier.</summary>
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; } = ObjectId.GenerateNewId().ToString();
/// <summary>Gets or sets the UTC timestamp when the log entry was created.</summary>
public DateTime Timestamp { get; set; }
/// <summary>Gets or sets the log level (e.g. <c>"Information"</c>, <c>"Error"</c>).</summary>
public string Level { get; set; } = string.Empty;
/// <summary>Gets or sets the logger category name.</summary>
public string Category { get; set; } = string.Empty;
/// <summary>Gets or sets the formatted log message.</summary>
public string Message { get; set; } = string.Empty;
/// <summary>Gets or sets the string representation of an associated exception, or <see langword="null"/> if none.</summary>
public string? Exception { get; set; }
/// <summary>Gets or sets the request path (e.g. <c>"/api/users"</c>), or <see langword="null"/> outside an HTTP context.</summary>
public string? Path { get; set; }
/// <summary>Gets or sets the HTTP method (e.g. <c>"GET"</c>), or <see langword="null"/> outside an HTTP context.</summary>
public string? Method { get; set; }
/// <summary>Gets or sets the client IP address, or <see langword="null"/> outside an HTTP context.</summary>
public string? ClientIp { get; set; }
/// <summary>Gets or sets the Referer header value, or <see langword="null"/> outside an HTTP context.</summary>
public string? Referer { get; set; }
/// <summary>Gets or sets the User-Agent header value, or <see langword="null"/> outside an HTTP context.</summary>
public string? UserAgent { get; set; }
}
/// <summary>
/// Writes batches of <see cref="LogEntry"/> documents to a MongoDB collection using <c>InsertManyAsync</c>.
/// </summary>
/// <param name="collection">The MongoDB collection that receives log entries.</param>
public sealed class MongoDbLogWriter(IMongoCollection<LogEntry> collection) : IBatchedLogWriter<LogEntry>
{
/// <summary>
/// Inserts all entries in the batch into the MongoDB collection.
/// </summary>
/// <param name="entries">The log entries to insert.</param>
/// <param name="ct">A token that can cancel the operation.</param>
public async Task WriteBatchAsync(List<LogEntry> entries, CancellationToken ct) =>
await collection.InsertManyAsync(entries, cancellationToken: ct);
/// <inheritdoc/>
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
}