Relatude Help

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.