srctree

Gregory Mullen parent f314535b 5a871f1c
make stats a bit prettier

inlinesplit
src/builtin-html/verse-stats.html added: 88, removed: 22, total 66
@@ -4,7 +4,6 @@
<title>Verse Stats</title>
<style>
.verse-stats-contents { display: block; width: 100%; }
.verse-stats-line { display: block; }
</style>
<link href="/static/main.css" rel="stylesheet">
</head>
@@ -15,10 +14,27 @@
<span>Mean Response Time: <MeanRespTime type="usize" /></span>
</div>
 
<div class="verse-stats-contents">
<table class="verse-stats-contents">
<tr>
<th>#</th>
<th>Time</th>
<th>IP Address</th>
<th>URI</th>
<th>Size</th>
<th>μseconds</th>
<th>User Agent</th>
</tr>
<For VerseStatsList>
<span class="verse-stats-line"><Number type="usize" /> : <Uri /> - <Time type="usize" /> - <Size type="usize" /> <Us type="usize" /></span>
<tr class="verse-stats-line<IsBot ornull/>">
<td><Number type="usize" /></td>
<td><Time type="usize" /></td>
<td><IpAddress /></td>
<td><Uri /></td>
<td><Size type="usize" /> </td>
<td><Us type="usize" /></td>
<td><With VerseUserAgent><Name /> <Version type="?usize" /></With></td>
</tr>
</For>
</div>
</table>
</body>
</html>
 
src/frame.zig added: 88, removed: 22, total 66
@@ -40,7 +40,7 @@ status: ?std.http.Status = null,
headers_done: bool = false,
 
/// Unstable API; may be altered or removed in the future
server: *align(8) const anyopaque,
server: if (false) *const Server else *align(8) const anyopaque,
 
const Frame = @This();
 
 
src/http.zig added: 88, removed: 22, total 66
@@ -97,8 +97,10 @@ pub fn once(http: *HTTP, sconn: net.Server.Connection) !void {
const lap = timer.lap();
if (srvr.stats) |*stats| {
stats.log(.{
.addr = req.remote_addr,
.uri = req.uri,
.us = lap / 1000,
.ua = req.user_agent,
});
}
}
 
src/stats.zig added: 88, removed: 22, total 66
@@ -3,7 +3,7 @@ pub const Stats = struct {
start_time: i64,
count: usize,
mean: Mean,
rows: [30]Line,
rows: [256]Line,
 
const Mean = struct {
time: [256]u64 = undefined,
@@ -31,33 +31,43 @@ pub const Stats = struct {
 
pub const Line = struct {
number: usize,
size: usize,
time: u64,
uri: Array,
addr: Addr,
size: usize,
uri: Uri,
us: usize,
ua: ?UserAgent,
 
const Array = std.BoundedArray(u8, 2048);
pub const Size = 2048;
// These are different because I haven't finalized the expected type
// and size yet.
const Uri = std.BoundedArray(u8, Size);
const Addr = std.BoundedArray(u8, Size);
pub const empty: Line = .{
.addr = .{},
.number = 0,
.size = 0,
.time = 0,
.uri = .{},
.ua = null,
.us = 0,
};
};
 
pub const Data = struct {
addr: []const u8,
uri: []const u8,
us: u64,
ua: ?UserAgent,
};
 
pub fn init(threaded: bool) Stats {
return .{
.mutex = if (threaded) .{} else null,
.start_time = std.time.timestamp(),
.count = 0,
.mean = .{},
.mutex = if (threaded) .{} else null,
.rows = @splat(.empty),
.start_time = std.time.timestamp(),
};
}
 
@@ -66,10 +76,12 @@ pub const Stats = struct {
defer if (stats.mutex) |*mx| mx.unlock();
 
stats.rows[stats.count % stats.rows.len] = .{
.addr = Line.Addr.fromSlice(data.addr[0..@min(data.addr.len, Line.Size)]) catch unreachable,
.number = stats.count,
.size = 0,
.time = @intCast(std.time.timestamp()),
.uri = Line.Array.fromSlice(data.uri[0..@min(data.uri.len, 2048)]) catch unreachable,
.uri = Line.Uri.fromSlice(data.uri[0..@min(data.uri.len, Line.Size)]) catch unreachable,
.ua = data.ua,
.us = data.us,
};
stats.count += 1;
@@ -93,8 +105,16 @@ pub const Endpoint = struct {
pub const stats = index;
 
pub fn index(f: *Frame) Router.Error!void {
var data: [30]S.VerseStatsList = @splat(
.{ .number = 0, .size = 0, .time = 0, .uri = "null", .us = 0 },
var data: [60]S.VerseStatsList = @splat(
.{
.ip_address = "",
.number = 0,
.size = 0,
.time = 0,
.uri = "null",
.verse_user_agent = null,
.us = 0,
},
);
var count: usize = 0;
var uptime = std.time.timestamp();
@@ -104,15 +124,37 @@ pub const Endpoint = struct {
count = active.count;
uptime -|= active.start_time;
mean_time = active.mean.mean(@truncate(count));
for (0..30) |i| {
for (0..data.len) |i| {
if (i >= count) break;
const idx = count - i - 1;
const src = &active.rows[idx % active.rows.len];
const ua: ?S.VerseUserAgent = if (src.ua) |sua|
switch (sua.resolved) {
.bot => |b| .{
.name = @tagName(b.name),
.version = 0,
},
.browser => |b| .{
.name = @tagName(b.name),
.version = b.version,
},
.script => |s| .{ .name = @tagName(s), .version = null },
.unknown => .{ .name = "[unknown]", .version = null },
}
else
null;
 
data[i] = .{
.ip_address = src.addr.slice(),
.number = src.number,
.size = src.size,
.time = src.time,
.uri = src.uri.slice(),
.verse_user_agent = ua orelse .{
.name = "[No User Agent Provided]",
.version = 0,
},
.is_bot = if (src.ua) |sua| if (sua.resolved == .bot) " bot" else null else null,
.us = src.us,
};
}
@@ -133,3 +175,4 @@ pub const Endpoint = struct {
const std = @import("std");
const Frame = @import("frame.zig");
const Server = @import("server.zig");
const UserAgent = @import("user-agent.zig");
 
src/user-agent.zig added: 88, removed: 22, total 66
@@ -204,7 +204,10 @@ pub const Browser = struct {
version: u32,
version_string: []const u8 = "",
 
pub const unknown: Browser = .{ .name = .unknown, .version = 0 };
pub const unknown: Browser = .{
.name = .unknown,
.version = 0,
};
 
pub const Name = enum {
brave,
 
src/zwsgi.zig added: 88, removed: 22, total 66
@@ -121,8 +121,10 @@ pub fn once(z: *const zWSGI, acpt: net.Server.Connection) !void {
);
if (srvr.stats) |*stats| {
stats.log(.{
.addr = request.remote_addr,
.uri = request.uri,
.us = lap,
.ua = request.user_agent,
});
}
}