32.2 Recording from the application
db.CustomLogs is the store's ICustomLogs. There are four ways to record, each one entry per call:
// property-value pairs, timestamped now
db.CustomLogs.Record("requests",
("path", ctx.Request.Path.Value), ("status", 200), ("duration", sw.Elapsed.TotalMilliseconds));
// an object: its public properties are matched to the columns, ignoring case
db.CustomLogs.RecordObject("requests",
new { Path = "/products", Status = 200, Duration = 12.5, Position = new GeoCoordinate(59.9139, 10.7522) });
// a dictionary, with a time of its own
db.CustomLogs.Record("requests", new Dictionary<string, object?> { ["path"] = "/cart" }, timestampUtc: startedUtc);
// an entry, when the timestamp and the values are built elsewhere
db.CustomLogs.Record("requests", new LogEntry { Timestamp = startedUtc, Values = { ["status"] = 404 } });Recording is cheap. A log that does not exist or is switched off costs a dictionary lookup, and
Record returns false when no log has the key. Entries are buffered and written to disk every 30
seconds, or sooner when a megabyte is waiting. Record(key, entry, flushToDisk: true) writes one
entry at once, and db.CustomLogs.FlushToDiskNow() writes everything waiting.
Values are converted to their column's type when you record them:
| Column type | What converts into it |
|---|---|
| Text | Anything. Numbers and dates are written the same on every server (1.5, ISO 8601 in UTC), bytes as base64 |
| Whole number | Integer types (a long is clamped to the int range), enums, bool as 1/0, rounded double and decimal, numeric text |
| Decimal number | Any number, bool, TimeSpan as milliseconds, numeric text; not NaN or infinity |
| Date and time | DateTime (stored in UTC; an unspecified kind counts as UTC), DateTimeOffset, DateOnly, ISO text |
| Duration | TimeSpan, TimeOnly, a number of milliseconds, text such as 00:01:30 |
| Bytes | byte[], Memory<byte>, ArraySegment<byte>, text as UTF-8 |
| Position | GeoCoordinate, text such as 59.91, 10.75, a (latitude, longitude) tuple or a two-element array (§32.8) |
A value that is null, or does not convert, is left out of the entry rather than recorded as a zero the statistics would count. Values under keys the log does not declare are kept as they are, so a column added later can read them. Timestamps are stored in UTC.