milestone 25: client names learned over reverse dns
Gates / test (push) Successful in 2m58s
Gates / frontend (push) Successful in 3m57s
Gates / test-aarch64 (push) Successful in 8m20s
Gates / package (push) Successful in 7m27s
Gates / container (push) Successful in 17s
CI / gates (push) Successful in 19m9s

This commit is contained in:
2026-08-15 11:18:44 +02:00
parent c428bc2398
commit 3c794b645b
20 changed files with 2638 additions and 36 deletions
+19
View File
@@ -24,6 +24,7 @@ const std = @import("std");
const Allocator = std.mem.Allocator;
const cert_store = @import("../server/cert_store.zig");
const client_names = @import("../server/client_names.zig");
const clients = @import("../server/clients.zig");
const dns_cache = @import("../cache/dns_cache.zig");
const dns_handler = @import("../server/handler.zig");
@@ -122,6 +123,7 @@ pub const Sample = struct {
cache: ?CacheSample = null,
limiter: ?LimiterSample = null,
tracker: ?TrackerSample = null,
client_names: ?client_names.Resolver.Stats = null,
retention: ?retention_mod.Stats = null,
blocklist: ?BlocklistSample = null,
disk: ?DiskSample = null,
@@ -193,6 +195,8 @@ pub fn collect(state: *server.WebState, io: std.Io, arena: Allocator) Allocator.
.pending_clients = tracker.pendingClients(io),
};
if (state.client_names) |names| sample.client_names = names.snapshotStats(io);
if (state.retention) |retention| sample.retention = retention.snapshotStats();
if (state.manager) |manager| {
@@ -340,6 +344,10 @@ pub fn render(w: *std.Io.Writer, sample: Sample) std.Io.Writer.Error!void {
);
}
if (sample.client_names) |names| {
try counterGroup(w, "nxdns_client_names_", "Learned client name counter", names);
}
if (sample.retention) |retention| {
try counterGroup(w, "nxdns_retention_", "Query log retention counter", retention);
}
@@ -594,6 +602,7 @@ fn writeLabelValue(w: *std.Io.Writer, value: []const u8) std.Io.Writer.Error!voi
// tests
// ---------------------------------------------------------------------------
const local_tables = @import("../server/local_tables.zig");
const logger_mod = @import("../storage/logger.zig");
const testing = std.testing;
@@ -645,6 +654,7 @@ test "a full sample renders the whole exposition, byte for byte" {
.stats = .{ .tracked = 4, .flushed = 3, .dropped_full = 0, .pruned = 1, .flush_failures = 0 },
.pending_clients = 2,
},
.client_names = .{ .attempted = 6, .answered = 3, .nxdomain = 1, .no_zone = 2, .invalid = 0, .failed = 0, .read_failures = 0, .write_failures = 1 },
.retention = .{ .passes = 7, .rows_pruned = 100, .checkpoints = 7, .vacuums = 1 },
.blocklist = .{ .refreshes_gated = 2, .generation = 4 },
.disk = .{
@@ -681,6 +691,9 @@ test "a full sample renders the whole exposition, byte for byte" {
try testing.expect(std.mem.containsAtLeast(u8, text, 1, "nxdns_dns_rate_limit_tracked_clients 3\n"));
try testing.expect(std.mem.containsAtLeast(u8, text, 1, "nxdns_clients_dropped_full_total 0\n"));
try testing.expect(std.mem.containsAtLeast(u8, text, 1, "nxdns_clients_pending 2\n"));
try testing.expect(std.mem.containsAtLeast(u8, text, 1, "nxdns_client_names_no_zone_total 2\n"));
try testing.expect(std.mem.containsAtLeast(u8, text, 1, "nxdns_client_names_answered_total 3\n"));
try testing.expect(std.mem.containsAtLeast(u8, text, 1, "nxdns_client_names_write_failures_total 1\n"));
try testing.expect(std.mem.containsAtLeast(u8, text, 1, "nxdns_retention_rows_pruned_total 100\n"));
try testing.expect(std.mem.containsAtLeast(u8, text, 1, "nxdns_blocklist_refreshes_gated_total 2\n"));
try testing.expect(std.mem.containsAtLeast(u8, text, 1, "nxdns_blocklist_generation 4\n"));
@@ -1242,12 +1255,17 @@ test "collect reads the live counters of the components it is given" {
var tracker: clients.Tracker = .init(30);
var retention: retention_mod.Retention = .init(.{});
var tables: local_tables.LocalTables = .empty;
var names: client_names.Resolver = .init(&tables);
names.stats.no_zone = 4;
names.stats.attempted = 4;
var state: server.WebState = .{
.gpa = testing.allocator,
.handler = &handler,
.logger = &query_logger,
.tracker = &tracker,
.client_names = &names,
.retention = &retention,
};
@@ -1263,6 +1281,7 @@ test "collect reads the live counters of the components it is given" {
try testing.expectEqual(@as(u64, 3), sample.limiter.?.stats.refused);
try testing.expectEqual(@as(u64, 90), sample.logger.rows_written);
try testing.expectEqual(@as(u64, 0), sample.tracker.?.pending_clients);
try testing.expectEqual(@as(u64, 4), sample.client_names.?.no_zone);
try testing.expectEqual(@as(u64, 0), sample.retention.?.passes);
try testing.expectEqual(@as(?BlocklistSample, null), sample.blocklist);
try testing.expectEqual(@as(usize, 0), sample.upstreams.len);