@@ -3,6 +3,7 @@ pub const Stats = struct {
start_time: i64,
count: usize,
mean: Mean,
rows: [30]Line,
const Mean = struct {
time: [256]u64 = undefined,
@@ -28,6 +29,23 @@ pub const Stats = struct {
}
};
pub const Line = struct {
number: usize,
size: usize,
time: u64,
uri: Array,
us: usize,
const Array = std.BoundedArray(u8, 2048);
pub const empty: Line = .{
.number = 0,
.size = 0,
.time = 0,
.uri = .{},
.us = 0,
};
};
pub const Data = struct {
uri: []const u8,
us: u64,
@@ -39,6 +57,7 @@ pub const Stats = struct {
.start_time = std.time.timestamp(),
.count = 0,
.mean = .{},
.rows = @splat(.empty),
};
}
@@ -46,42 +65,74 @@ pub const Stats = struct {
if (stats.mutex) |*mx| mx.lock();
defer if (stats.mutex) |*mx| mx.unlock();
stats.rows[stats.count % stats.rows.len] = .{
.number = stats.count,
.size = 0,
.time = @intCast(std.time.timestamp()),
.uri = Line.Array.fromSlice(data.uri[0..@min(data.uri.len, 2048)]) catch unreachable,
.us = data.us,
};
stats.count += 1;
stats.mean.time[stats.mean.idx] = data.us;
stats.mean.idx +%= 1;
return;
}
};
pub var active_stats: ?*Stats = null;
pub const Endpoint = struct {
//const EP = @import("endpoint.zig");
const Router = @import("router.zig");
const PageData = @import("template.zig").PageData;
const S = @import("template.zig").Structs;
pub const verse_name = .stats;
pub const verse_routes = [_]Router.Match{};
const StatsPage = PageData("builtin-html/stats.html");
pub const stats = index;
pub fn index(f: *Frame) Router.Error!void {
var data: [30]S.StatsList = @splat(.{ .uri = "null", .time = "never", .size = "unknown" });
var data: [30]S.StatsList = @splat(.{
.number = 0,
.size = 0,
.time = 0,
.uri = "null",
.us = 0,
});
var count: usize = 0;
var uptime = std.time.timestamp();
var mean_time: u64 = 0;
if (active_stats) |active| {
if (f.server.stats) |active| {
count = active.count;
uptime -|= active.start_time;
mean_time = active.mean.mean(@truncate(count));
for (&data, &active.rows) |*dst, *src| {
dst.* = .{
.number = src.number,
.size = src.size,
.time = src.time,
.uri = src.uri.slice(),
.us = src.us,
};
}
}
var first = data[0..@min(count % data.len, data.len)];
var last = data[count % data.len .. @min(count, data.len)];
if (count > data.len) {
last = first;
first = data[count % data.len .. @min(count, data.len)];
}
const page = StatsPage.init(.{
.uptime = @intCast(uptime),
.count = count,
.mean_resp_time = mean_time,
.stats_list = data[0..@min(count, data.len)],
.stats_list = first,
.stats_list_last = @ptrCast(last),
});
return f.sendPage(&page);
}
@@ -92,4 +143,3 @@ pub const Endpoint = struct {
const std = @import("std");
const Server = @import("server.zig");
const Frame = @import("frame.zig");
const Router = @import("router.zig");