Replace std.log with a structured logger

Outputs in logfmt in release and a "pretty" print in debug mode. The format
along with the log level will become arguments to the binary at some point in
the future.
This commit is contained in:
Karl Seguin
2025-05-25 19:23:53 +08:00
parent e9920caa69
commit 2feba3182a
31 changed files with 792 additions and 325 deletions

View File

@@ -25,6 +25,7 @@ const posix = std.posix;
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
const log = @import("log.zig");
const IO = @import("runtime/loop.zig").IO;
const Completion = IO.Completion;
const AcceptError = IO.AcceptError;
@@ -38,8 +39,6 @@ const CDP = @import("cdp/cdp.zig").CDP;
const TimeoutCheck = std.time.ns_per_ms * 100;
const log = std.log.scoped(.server);
const MAX_HTTP_REQUEST_SIZE = 2048;
// max message size
@@ -67,7 +66,7 @@ const Server = struct {
}
fn queueAccept(self: *Server) void {
log.info("accepting new conn...", .{});
log.debug(.server, "accepting connection", .{});
self.loop.io.accept(
*Server,
self,
@@ -84,7 +83,7 @@ const Server = struct {
) void {
std.debug.assert(completion == &self.accept_completion);
self.doCallbackAccept(result) catch |err| {
log.err("accept error: {any}", .{err});
log.err(.server, "accept error", .{ .err = err });
self.queueAccept();
};
}
@@ -97,7 +96,13 @@ const Server = struct {
const client = try self.allocator.create(Client);
client.* = Client.init(socket, self);
client.start();
log.info("client connected", .{});
if (log.enabled(.server, .info)) {
var address: std.net.Address = undefined;
var socklen: posix.socklen_t = @sizeOf(net.Address);
try std.posix.getsockname(socket, &address.any, &socklen);
log.info(.server, "client connected", .{ .ip = address });
}
}
fn releaseClient(self: *Server, client: *Client) void {
@@ -250,7 +255,7 @@ pub const Client = struct {
}
const size = result catch |err| {
log.err("read error: {any}", .{err});
log.err(.server, "read error", .{ .err = err });
self.close();
return;
};
@@ -313,7 +318,7 @@ pub const Client = struct {
error.InvalidVersionHeader => self.writeHTTPErrorResponse(400, "Invalid websocket version"),
error.InvalidConnectionHeader => self.writeHTTPErrorResponse(400, "Invalid connection header"),
else => {
log.err("error processing HTTP request: {any}", .{err});
log.err(.server, "http 500", .{ .err = err });
self.writeHTTPErrorResponse(500, "Internal Server Error");
},
}
@@ -594,6 +599,7 @@ pub const Client = struct {
if (result) |_| {
if (now().since(self.last_active) >= self.server.timeout) {
log.info(.server, "connection timeout", .{});
if (self.mode == .websocket) {
self.send(null, &CLOSE_TIMEOUT) catch {};
}
@@ -601,7 +607,7 @@ pub const Client = struct {
return;
}
} else |err| {
log.err("timeout error: {any}", .{err});
log.err(.server, "timeout error", .{ .err = err });
}
self.queueTimeout();
@@ -650,7 +656,7 @@ pub const Client = struct {
}
const sent = result catch |err| {
log.info("send error: {any}", .{err});
log.warn(.server, "send error", .{ .err = err });
self.close();
return;
};
@@ -1036,6 +1042,7 @@ pub fn run(
// accept an connection
server.queueAccept();
log.info(.server, "running", .{ .address = address });
// infinite loop on I/O events, either:
// - cmd from incoming connection on server socket