mirror of
https://github.com/jetzig-framework/jetzig.git
synced 2025-05-14 14:06:08 +00:00
Fix development logger colors on Windows
This commit is contained in:
parent
e4da5bc9c8
commit
bed91b2131
@ -29,7 +29,7 @@ pub const codes = .{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Map color codes generated by `std.io.tty.Config.setColor` back to `std.io.tty.Color`. Used by
|
/// Map color codes generated by `std.io.tty.Config.setColor` back to `std.io.tty.Color`. Used by
|
||||||
/// `jetzig.loggers.LogQueue.writeWindows` to parse escape codes so they can be passed to
|
/// `jetzig.util.writeAnsi` to parse escape codes so they can be passed to
|
||||||
/// `std.io.tty.Config.setColor` (using Windows API to set console color mode).
|
/// `std.io.tty.Config.setColor` (using Windows API to set console color mode).
|
||||||
const ansi_colors = .{
|
const ansi_colors = .{
|
||||||
.{ "30", .black },
|
.{ "30", .black },
|
||||||
|
@ -57,7 +57,8 @@ pub fn log(
|
|||||||
|
|
||||||
const formatted_level = colorizedLogLevel(level);
|
const formatted_level = colorizedLogLevel(level);
|
||||||
|
|
||||||
try self.logWriter(level).print(
|
try self.print(
|
||||||
|
level,
|
||||||
"{s: >5} [{s}] {s}\n",
|
"{s: >5} [{s}] {s}\n",
|
||||||
.{ formatted_level, iso8601, output },
|
.{ formatted_level, iso8601, output },
|
||||||
);
|
);
|
||||||
@ -93,7 +94,7 @@ pub fn logRequest(self: DevelopmentLogger, request: *const jetzig.http.Request)
|
|||||||
|
|
||||||
const formatted_level = if (self.stdout_colorized) colorizedLogLevel(.INFO) else @tagName(.INFO);
|
const formatted_level = if (self.stdout_colorized) colorizedLogLevel(.INFO) else @tagName(.INFO);
|
||||||
|
|
||||||
try self.logWriter(.INFO).print("{s: >5} [{s}] [{s}/{s}/{s}]{s}{s}{s}{s}{s}{s}{s}{s}{s}{s} {s}\n", .{
|
try self.print(.INFO, "{s: >5} [{s}] [{s}/{s}/{s}]{s}{s}{s}{s}{s}{s}{s}{s}{s}{s} {s}\n", .{
|
||||||
formatted_level,
|
formatted_level,
|
||||||
iso8601,
|
iso8601,
|
||||||
formatted_duration,
|
formatted_duration,
|
||||||
@ -118,7 +119,7 @@ pub fn logSql(self: *const DevelopmentLogger, event: jetzig.jetquery.events.Even
|
|||||||
// from multiple threads. JSON logger etc. write in one call and the log queue prevents
|
// from multiple threads. JSON logger etc. write in one call and the log queue prevents
|
||||||
// clobbering, but this is not the case here.
|
// clobbering, but this is not the case here.
|
||||||
const formatted_level = if (self.stdout_colorized) colorizedLogLevel(.INFO) else @tagName(.INFO);
|
const formatted_level = if (self.stdout_colorized) colorizedLogLevel(.INFO) else @tagName(.INFO);
|
||||||
try self.logWriter(.INFO).print("{s} [database] ", .{formatted_level});
|
try self.print(.INFO, "{s} [database] ", .{formatted_level});
|
||||||
try self.printSql(event.sql orelse "");
|
try self.printSql(event.sql orelse "");
|
||||||
|
|
||||||
var duration_buf: [256]u8 = undefined;
|
var duration_buf: [256]u8 = undefined;
|
||||||
@ -128,7 +129,8 @@ pub fn logSql(self: *const DevelopmentLogger, event: jetzig.jetquery.events.Even
|
|||||||
self.stdout_colorized,
|
self.stdout_colorized,
|
||||||
) else "";
|
) else "";
|
||||||
|
|
||||||
try self.logWriter(.INFO).print(
|
try self.print(
|
||||||
|
.INFO,
|
||||||
std.fmt.comptimePrint(" [{s}]\n", .{jetzig.colors.cyan("{s}")}),
|
std.fmt.comptimePrint(" [{s}]\n", .{jetzig.colors.cyan("{s}")}),
|
||||||
.{formatted_duration},
|
.{formatted_duration},
|
||||||
);
|
);
|
||||||
@ -233,7 +235,7 @@ fn printSql(self: *const DevelopmentLogger, sql: []const u8) !void {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try self.logWriter(.INFO).print("{s}", .{stream.getWritten()});
|
try self.print(.INFO, "{s}", .{stream.getWritten()});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn logError(self: *const DevelopmentLogger, err: anyerror) !void {
|
pub fn logError(self: *const DevelopmentLogger, err: anyerror) !void {
|
||||||
@ -249,12 +251,41 @@ pub fn logError(self: *const DevelopmentLogger, err: anyerror) !void {
|
|||||||
try self.log(.ERROR, "Encountered Error: {s}", .{@errorName(err)});
|
try self.log(.ERROR, "Encountered Error: {s}", .{@errorName(err)});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn logWriter(self: DevelopmentLogger, comptime level: jetzig.loggers.LogLevel) std.fs.File.Writer {
|
fn logFile(self: DevelopmentLogger, comptime level: jetzig.loggers.LogLevel) std.fs.File {
|
||||||
const target = comptime jetzig.loggers.logTarget(level);
|
const target = comptime jetzig.loggers.logTarget(level);
|
||||||
return switch (target) {
|
return switch (target) {
|
||||||
.stdout => self.stdout,
|
.stdout => self.stdout,
|
||||||
.stderr => self.stderr,
|
.stderr => self.stderr,
|
||||||
}.writer();
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn logWriter(self: DevelopmentLogger, comptime level: jetzig.loggers.LogLevel) std.fs.File.Writer {
|
||||||
|
return self.logFile(level).writer();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print(
|
||||||
|
self: DevelopmentLogger,
|
||||||
|
comptime level: jetzig.loggers.LogLevel,
|
||||||
|
comptime template: []const u8,
|
||||||
|
args: anytype,
|
||||||
|
) !void {
|
||||||
|
const log_writer = self.logWriter(level);
|
||||||
|
const count = std.fmt.count(template, args);
|
||||||
|
const buf_size = 4096;
|
||||||
|
if (count <= buf_size) {
|
||||||
|
var buf: [buf_size]u8 = undefined;
|
||||||
|
var stream = std.io.fixedBufferStream(&buf);
|
||||||
|
const writer = stream.writer();
|
||||||
|
try writer.print(template, args);
|
||||||
|
try jetzig.util.writeAnsi(self.logFile(level), log_writer, stream.getWritten());
|
||||||
|
} else {
|
||||||
|
const buf = try self.allocator.alloc(u8, count);
|
||||||
|
defer self.allocator.free(buf);
|
||||||
|
var stream = std.io.fixedBufferStream(buf);
|
||||||
|
const writer = stream.writer();
|
||||||
|
try writer.print(template, args);
|
||||||
|
try jetzig.util.writeAnsi(self.logFile(level), log_writer, stream.getWritten());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn colorizedLogLevel(comptime level: LogLevel) []const u8 {
|
inline fn colorizedLogLevel(comptime level: LogLevel) []const u8 {
|
||||||
|
@ -164,7 +164,6 @@ pub const Reader = struct {
|
|||||||
var stdout_written = false;
|
var stdout_written = false;
|
||||||
var stderr_written = false;
|
var stderr_written = false;
|
||||||
var file: std.fs.File = undefined;
|
var file: std.fs.File = undefined;
|
||||||
var colorize = false;
|
|
||||||
|
|
||||||
while (try self.queue.popFirst()) |event| {
|
while (try self.queue.popFirst()) |event| {
|
||||||
self.queue.writer.mutex.lock();
|
self.queue.writer.mutex.lock();
|
||||||
@ -175,14 +174,12 @@ pub const Reader = struct {
|
|||||||
stdout_written = true;
|
stdout_written = true;
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
file = self.stdout_file;
|
file = self.stdout_file;
|
||||||
colorize = self.queue.stdout_colorize;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.stderr => {
|
.stderr => {
|
||||||
stderr_written = true;
|
stderr_written = true;
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
file = self.stderr_file;
|
file = self.stderr_file;
|
||||||
colorize = self.queue.stderr_colorize;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -199,7 +196,7 @@ pub const Reader = struct {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try jetzig.util.writeAnsi(file, writer, event.message[0..event.len]);
|
try writer.writeAll(event.message[0..event.len]);
|
||||||
|
|
||||||
self.queue.writer.position -= 1;
|
self.queue.writer.position -= 1;
|
||||||
|
|
||||||
@ -270,26 +267,6 @@ fn initPool(allocator: std.mem.Allocator, T: type) std.heap.MemoryPool(T) {
|
|||||||
return std.heap.MemoryPool(T).initPreheated(allocator, max_pool_len) catch @panic("OOM");
|
return std.heap.MemoryPool(T).initPreheated(allocator, max_pool_len) catch @panic("OOM");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn writeWindows(file: std.fs.File, writer: anytype, event: Event) !void {
|
|
||||||
var info: std.os.windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
|
|
||||||
_ = std.os.windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info);
|
|
||||||
|
|
||||||
var it = std.mem.tokenizeSequence(u8, event.message[0..event.len], "\x1b[");
|
|
||||||
while (it.next()) |token| {
|
|
||||||
if (std.mem.indexOfScalar(u8, token, 'm')) |index| {
|
|
||||||
if (index > 0 and index + 1 < token.len) {
|
|
||||||
if (jetzig.colors.windows_map.get(token[0..index])) |color| {
|
|
||||||
try std.os.windows.SetConsoleTextAttribute(file.handle, color);
|
|
||||||
try writer.writeAll(token[index + 1 ..]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Fallback
|
|
||||||
try writer.writeAll(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test "print to stdout and stderr" {
|
test "print to stdout and stderr" {
|
||||||
var log_queue = LogQueue.init(std.testing.allocator);
|
var log_queue = LogQueue.init(std.testing.allocator);
|
||||||
defer log_queue.deinit();
|
defer log_queue.deinit();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user