Relatude Help

32.5 Reading a log

Each log has a page under Logs, with the Record and Statistics switches at the top and five views. Graphs, Entries and Analyse share one time range: a range ending now (5 minutes to 12 months), two moments you type in, or an interval you pick on a graph.

View What it shows
Graphs Summary tiles and a graph per statistic. Click an interval to see its entries. Each graph downloads as CSV.
Entries The entries of the range, with a search over all of them. Open an entry to see what was recorded around it. Download writes TSV, CSV or JSON lines.
Analyse How one column's values are spread, read from the entries: percentiles and a histogram for numbers, the most common values for text, maps for positions (§32.8). It reads the newest 200,000 entries of the range by default.
Definition The form, the JSON file, and C# code that records into the log.
Data Try it out: record a test entry, or up to a million made-up ones, to see the graphs before the application records anything. Clean up: delete entries or statistics, rebuild the statistics, write to disk. The log's files, each with a download.

The Entries search takes terms like these. All terms must match, and case is ignored unless you ask to match it:

timeout                  "timeout" anywhere in the entry
get*nodes                * matches any run of characters, ? exactly one
"could not open"         a phrase
error -shutdown          "error" somewhere and "shutdown" nowhere
status:500               a term in one column

From code, db.CustomLogs.LogStore is the ILogStore behind the page, with the same reads:

using Relatude.DB.Logging.Statistics;   // IntervalType

var store = db.CustomLogs.LogStore;
var to = DateTime.UtcNow;
var from = to.AddDays(-1);

// the newest 100 entries of the last day, and how many the range holds
var newest = store.ExtractLog("requests", from, to, skip: 0, take: 100, orderByDescendingDates: true, out var inRange);
// the same search as the Entries view
var failed = store.SearchLog("requests", "status:5??", from, to, 0, 100, true, out var failures);
// entries per hour
var perHour = store.AnalyseRows("requests", IntervalType.Hour, from, to, estimateNowInterval: false, fillInBlanks: true);
// distinct users per day, over 30 days
var users = store.AnalyseEstimatedUniqueCounts("requests", "user", IntervalType.Day, from.AddDays(-29), to, false, true);

Nothing is indexed: a search reads every entry in its range, so the range sets the cost. Only the page you ask for is held in memory.