This commit is contained in:
Bob Farrell 2024-05-09 21:30:11 +01:00
parent 63b4265131
commit b39653b90f
5 changed files with 61 additions and 37 deletions

View File

@ -101,15 +101,16 @@ pub fn runtimeWhite(allocator: std.mem.Allocator, message: []const u8) ![]const
return try runtimeWrap(allocator, codes.white, message);
}
pub fn duration(allocator: std.mem.Allocator, delta: i64) ![]const u8 {
var buf: [1024]u8 = undefined;
const formatted_duration = try std.fmt.bufPrint(&buf, "{}", .{std.fmt.fmtDurationSigned(delta)});
if (delta < 1000000) {
return try runtimeGreen(allocator, formatted_duration);
} else if (delta < 5000000) {
return try runtimeYellow(allocator, formatted_duration);
} else {
return try runtimeRed(allocator, formatted_duration);
}
pub fn duration(buf: *[256]u8, delta: i64) ![]const u8 {
const code = if (delta < 1000000)
codes.green
else if (delta < 5000000)
codes.yellow
else
codes.red;
return try std.fmt.bufPrint(
buf,
"{s}{s}m{}{s}{s}m",
.{ codes.escape, code, std.fmt.fmtDurationSigned(delta), codes.escape, codes.reset },
);
}

View File

@ -22,9 +22,9 @@ pub fn init(
return .{
.allocator = allocator,
.level = level,
.log_queue = log_queue,
.stdout_colorized = true, // TODO
.stderr_colorized = true, // TODO
.log_queue = log_queue, // TODO: stdout/stderr queues
.stdout_colorized = log_queue.is_tty,
.stderr_colorized = log_queue.is_tty,
};
}
@ -40,9 +40,9 @@ pub fn log(
const output = try std.fmt.allocPrint(self.allocator, message, args);
defer self.allocator.free(output);
const timestamp = Timestamp.init(std.time.timestamp(), self.allocator);
const iso8601 = try timestamp.iso8601();
defer self.allocator.free(iso8601);
const timestamp = Timestamp.init(std.time.timestamp());
var timestamp_buf: [256]u8 = undefined;
const iso8601 = try timestamp.iso8601(&timestamp_buf);
const colorized = switch (level) {
.TRACE, .DEBUG, .INFO => self.stdout_colorized,
@ -59,15 +59,15 @@ pub fn log(
/// Log a one-liner including response status code, path, method, duration, etc.
pub fn logRequest(self: DevelopmentLogger, request: *const jetzig.http.Request) !void {
var duration_buf: [256]u8 = undefined;
const formatted_duration = if (self.stdout_colorized)
try jetzig.colors.duration(self.allocator, jetzig.util.duration(request.start_time))
try jetzig.colors.duration(&duration_buf, jetzig.util.duration(request.start_time))
else
try std.fmt.allocPrint(
self.allocator,
try std.fmt.bufPrint(
&duration_buf,
"{}",
.{std.fmt.fmtDurationSigned(jetzig.util.duration(request.start_time))},
);
defer self.allocator.free(formatted_duration);
const status: jetzig.http.status_codes.TaggedStatusCode = switch (request.response.status_code) {
inline else => |status_code| @unionInit(
@ -82,14 +82,19 @@ pub fn logRequest(self: DevelopmentLogger, request: *const jetzig.http.Request)
else
status.getFormatted(.{});
const message = try std.fmt.allocPrint(self.allocator, "[{s}/{s}/{s}] {s}", .{
const timestamp = Timestamp.init(std.time.timestamp());
var timestamp_buf: [256]u8 = undefined;
const iso8601 = try timestamp.iso8601(&timestamp_buf);
const writer = self.log_queue.writer;
try writer.print("{s: >5} [{s}] [{s}/{s}/{s}] {s}\n", .{
if (self.stdout_colorized) colorizedLogLevel(.INFO) else @tagName(.INFO),
iso8601,
formatted_duration,
request.fmtMethod(self.stdout_colorized),
formatted_status,
request.path.path,
});
defer self.allocator.free(message);
try self.log(.INFO, "{s}", .{message});
}
fn colorizedLogLevel(comptime level: LogLevel) []const u8 {

View File

@ -54,9 +54,9 @@ pub fn log(
const output = try std.fmt.allocPrint(self.allocator, message, args);
defer self.allocator.free(output);
const timestamp = Timestamp.init(std.time.timestamp(), self.allocator);
const iso8601 = try timestamp.iso8601();
defer self.allocator.free(iso8601);
const timestamp = Timestamp.init(std.time.timestamp());
var timestamp_buf: [256]u8 = undefined;
const iso8601 = try timestamp.iso8601(&timestamp_buf);
const file = self.getFile(level);
const writer = file.writer();
@ -80,9 +80,9 @@ pub fn logRequest(self: *const JsonLogger, request: *const jetzig.http.Request)
const duration = jetzig.util.duration(request.start_time);
const timestamp = Timestamp.init(std.time.timestamp(), self.allocator);
const iso8601 = try timestamp.iso8601();
defer self.allocator.free(iso8601);
const timestamp = Timestamp.init(std.time.timestamp());
var timestamp_buf: [256]u8 = undefined;
const iso8601 = try timestamp.iso8601(&timestamp_buf);
const status = switch (request.response.status_code) {
inline else => |status_code| @unionInit(

View File

@ -8,6 +8,9 @@ condition: *std.Thread.Condition,
condition_mutex: *std.Thread.Mutex,
writer: *Writer = undefined,
reader: *Reader = undefined,
pool: std.ArrayList(*List.Node),
position: usize,
is_tty: bool = undefined,
const LogQueue = @This();
@ -21,6 +24,8 @@ pub fn init(allocator: std.mem.Allocator) !LogQueue {
.condition = try allocator.create(std.Thread.Condition),
.condition_mutex = try allocator.create(std.Thread.Mutex),
.read_write_mutex = try allocator.create(std.Thread.Mutex),
.pool = std.ArrayList(*List.Node).init(allocator),
.position = 0,
};
}
@ -29,6 +34,7 @@ pub fn setFile(self: *LogQueue, file: std.fs.File) !void {
self.writer.* = Writer{ .file = file, .queue = self };
self.reader = try self.allocator.create(Reader);
self.reader.* = Reader{ .file = file, .queue = self };
self.is_tty = file.isTty();
}
pub const Writer = struct {
@ -71,9 +77,17 @@ pub fn append(self: *LogQueue, message: []const u8) !void {
self.read_write_mutex.lock();
defer self.read_write_mutex.unlock();
const node = try self.allocator.create(List.Node);
const node = if (self.position >= self.pool.items.len) blk: {
self.position += 1;
break :blk try self.allocator.create(List.Node);
} else blk: {
self.position += 1;
break :blk self.pool.items[self.position - 1];
};
node.* = .{ .data = message };
self.list.append(node);
self.condition.signal();
}
@ -83,7 +97,12 @@ pub fn popFirst(self: *LogQueue) !?[]const u8 {
if (self.list.popFirst()) |node| {
const value = node.data;
self.allocator.destroy(node);
self.position -= 1;
if (self.position < self.pool.items.len) {
self.pool.items[self.position] = node;
} else {
try self.pool.append(node);
}
return value;
} else {
return null;

View File

@ -3,7 +3,6 @@ const std = @import("std");
const Self = @This();
timestamp: i64,
allocator: std.mem.Allocator,
const constants = struct {
pub const seconds_in_day: i64 = 60 * 60 * 24;
@ -12,18 +11,18 @@ const constants = struct {
pub const epoch_year: i64 = 1970;
};
pub fn init(timestamp: i64, allocator: std.mem.Allocator) Self {
return .{ .allocator = allocator, .timestamp = timestamp };
pub fn init(timestamp: i64) Self {
return .{ .timestamp = timestamp };
}
pub fn iso8601(self: *const Self) ![]const u8 {
pub fn iso8601(self: *const Self, buf: *[256]u8) ![]const u8 {
const u32_year: u32 = @intCast(self.year());
const u32_month: u32 = @intCast(self.month());
const u32_day_of_month: u32 = @intCast(self.dayOfMonth());
const u32_hour: u32 = @intCast(self.hour());
const u32_minute: u32 = @intCast(self.minute());
const u32_second: u32 = @intCast(self.second());
return try std.fmt.allocPrint(self.allocator, "{d:0>4}-{d:0>2}-{d:0>2} {d:0>2}:{d:0>2}:{d:0>2}", .{
return try std.fmt.bufPrint(buf, "{d:0>4}-{d:0>2}-{d:0>2} {d:0>2}:{d:0>2}:{d:0>2}", .{
u32_year,
u32_month,
u32_day_of_month,