Panes/src/log.zig

154 lines
4.0 KiB
Zig

const std = @import("std");
const fs = std.fs;
var log_level: Level = .Debug;
var writer: ?std.fs.File.Writer = null;
const Level = enum {
Debug,
Info,
Warn,
Error,
Disable,
};
pub fn init(log_file: []const u8, level: Level) !void {
log_level = level;
const file = try fs.cwd().createFile(log_file, .{});
writer = file.writer();
}
pub fn setLevel(level: Level) void {
log_level = level;
}
pub fn deinit() void {
if (writer) |w| {
w.context.close();
}
}
pub fn debug(comptime format: []const u8, args: anytype) void {
if (@intFromEnum(log_level) <= @intFromEnum(Level.Debug)) {
if (writer) |w| {
_ = w.write("[Debug] ") catch {};
std.fmt.format(w, format, args) catch {};
_ = w.writeByte('\n') catch {};
}
}
}
pub fn info(comptime format: []const u8, args: anytype) void {
if (@intFromEnum(log_level) <= @intFromEnum(Level.Info)) {
if (writer) |w| {
_ = w.write("\x1b[1m[Info] ") catch {};
std.fmt.format(w, format, args) catch {};
_ = w.write("\x1b[0m\n") catch {};
}
}
}
pub fn warn(comptime format: []const u8, args: anytype) void {
if (@intFromEnum(log_level) <= @intFromEnum(Level.Warn)) {
if (writer) |w| {
_ = w.write("\x1b[1;33m[Warn] ") catch {};
std.fmt.format(w, format, args) catch {};
_ = w.write("\x1b[0m\n") catch {};
}
}
}
pub fn err(comptime format: []const u8, args: anytype) void {
if (@intFromEnum(log_level) <= @intFromEnum(Level.Error)) {
if (writer) |w| {
_ = w.write("\x1b[1;31m[Error] ") catch {};
std.fmt.format(w, format, args) catch {};
_ = w.write("\x1b[0m\n") catch {};
}
}
}
test "debug" {
try init("test.log", .Debug);
setLevel(.Debug);
debug("Hello", .{});
info("Hello", .{});
warn("Hello", .{});
err("Hello", .{});
deinit();
const file = try fs.cwd().openFile("test.log", .{});
defer file.close();
const contents = try file.readToEndAlloc(std.testing.allocator, 1024 * 1024);
defer std.testing.allocator.free(contents);
try std.testing.expectEqualStrings("[Debug] Hello\n\x1b[1m[Info] Hello\x1b[0m\n\x1b[1;33m[Warn] Hello\x1b[0m\n\x1b[1;31m[Error] Hello\x1b[0m\n", contents);
try fs.cwd().deleteFile("test.log");
}
test "info" {
try init("test.log", .Info);
setLevel(.Info);
debug("Hello", .{});
info("Hello", .{});
warn("Hello", .{});
err("Hello", .{});
deinit();
const file = try fs.cwd().openFile("test.log", .{});
defer file.close();
const contents = try file.readToEndAlloc(std.testing.allocator, 1024 * 1024);
defer std.testing.allocator.free(contents);
try std.testing.expectEqualStrings("\x1b[1m[Info] Hello\x1b[0m\n\x1b[1;33m[Warn] Hello\x1b[0m\n\x1b[1;31m[Error] Hello\x1b[0m\n", contents);
try fs.cwd().deleteFile("test.log");
}
test "warn" {
try init("test.log", .Warn);
setLevel(.Warn);
debug("Hello", .{});
info("Hello", .{});
warn("Hello", .{});
err("Hello", .{});
deinit();
const file = try fs.cwd().openFile("test.log", .{});
defer file.close();
const contents = try file.readToEndAlloc(std.testing.allocator, 1024 * 1024);
defer std.testing.allocator.free(contents);
try std.testing.expectEqualStrings("\x1b[1;33m[Warn] Hello\x1b[0m\n\x1b[1;31m[Error] Hello\x1b[0m\n", contents);
try fs.cwd().deleteFile("test.log");
}
test "error" {
try init("test.log", .Error);
setLevel(.Error);
debug("Hello", .{});
info("Hello", .{});
warn("Hello", .{});
err("Hello", .{});
deinit();
const file = try fs.cwd().openFile("test.log", .{});
defer file.close();
const contents = try file.readToEndAlloc(std.testing.allocator, 1024 * 1024);
defer std.testing.allocator.free(contents);
try std.testing.expectEqualStrings("\x1b[1;31m[Error] Hello\x1b[0m\n", contents);
try fs.cwd().deleteFile("test.log");
}