Fancy logger hopefully
This commit is contained in:
parent
864322bd88
commit
954b62d4a0
1 changed files with 129 additions and 8 deletions
|
|
@ -6,6 +6,24 @@ const log = std.log;
|
||||||
pub const Level = log.Level;
|
pub const Level = log.Level;
|
||||||
pub const Scope = @Type(.EnumLiteral);
|
pub const Scope = @Type(.EnumLiteral);
|
||||||
|
|
||||||
|
pub const Color = enum {
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
yellow,
|
||||||
|
blue,
|
||||||
|
magenta,
|
||||||
|
cyan,
|
||||||
|
white,
|
||||||
|
default,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ScopeModifier = struct {
|
||||||
|
scope: Scope,
|
||||||
|
color: ?Color = .default,
|
||||||
|
bright: bool = false,
|
||||||
|
rename: ?[]const u8 = null,
|
||||||
|
};
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
const Globals = struct {
|
const Globals = struct {
|
||||||
|
|
@ -14,13 +32,25 @@ const Globals = struct {
|
||||||
enableFileOutput: bool = false,
|
enableFileOutput: bool = false,
|
||||||
outputFile: ?std.fs.File = null,
|
outputFile: ?std.fs.File = null,
|
||||||
|
|
||||||
|
additionalScopes: std.ArrayList(ScopeModifier),
|
||||||
|
|
||||||
fn arena(self: *Globals) std.heap.ArenaAllocator {
|
fn arena(self: *Globals) std.heap.ArenaAllocator {
|
||||||
return std.heap.ArenaAllocator.init(self.allocator);
|
return std.heap.ArenaAllocator.init(self.allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initOrGetFile(self: *Globals) !std.fs.File {
|
||||||
|
if (self.outputFile) |file| {
|
||||||
|
return file;
|
||||||
|
} else {
|
||||||
|
return error.NoFileSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn init(allocator: Allocator) !Globals {
|
fn init(allocator: Allocator) !Globals {
|
||||||
return .{
|
return .{
|
||||||
allocator,
|
.allocator = allocator,
|
||||||
|
|
||||||
|
.additionalScopes = std.ArrayList(ScopeModifier).init(allocator),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,6 +59,8 @@ const Globals = struct {
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.additionalScopes.deinit();
|
||||||
|
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -67,6 +99,14 @@ pub const config = struct {
|
||||||
unreachable; // logging is not initialized
|
unreachable; // logging is not initialized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn addScope(modifier: ScopeModifier) !void {
|
||||||
|
if (core) |*globals| {
|
||||||
|
try globals.additionalScopes.append(modifier);
|
||||||
|
} else {
|
||||||
|
unreachable; // logging is not initialized
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(allocator: Allocator) !void {
|
pub fn init(allocator: Allocator) !void {
|
||||||
|
|
@ -79,6 +119,8 @@ pub fn deinit() void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var longestScopeYet: usize = 0;
|
||||||
|
|
||||||
/// If using this log function, you *must* call `init` before any logging occurs.
|
/// If using this log function, you *must* call `init` before any logging occurs.
|
||||||
/// Otherwise, it will complain. A lot.
|
/// Otherwise, it will complain. A lot.
|
||||||
pub fn logFn(comptime level: Level, comptime scope: Scope, comptime format: []const u8, args: anytype) void {
|
pub fn logFn(comptime level: Level, comptime scope: Scope, comptime format: []const u8, args: anytype) void {
|
||||||
|
|
@ -87,18 +129,97 @@ pub fn logFn(comptime level: Level, comptime scope: Scope, comptime format: []co
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get() !*Globals {
|
||||||
|
return &core orelse error.NotInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
fn logFnImpl(comptime level: Level, comptime scope: Scope, comptime format: []const u8, args: anytype) !void {
|
fn logFnImpl(comptime level: Level, comptime scope: Scope, comptime format: []const u8, args: anytype) !void {
|
||||||
var arena = core.?.arena();
|
const globals = try get();
|
||||||
|
var arena = globals.arena();
|
||||||
const c = cham.initRuntime(.{
|
const c = cham.initRuntime(.{
|
||||||
.allocator = arena.allocator(),
|
.allocator = arena.allocator(),
|
||||||
});
|
});
|
||||||
|
defer {
|
||||||
_ = c;
|
c.deinit();
|
||||||
|
arena.deinit();
|
||||||
_ = level;
|
}
|
||||||
_ = scope;
|
|
||||||
_ = format;
|
var scopeLen = 4;
|
||||||
_ = args;
|
const scopeText = switch (scope) {
|
||||||
|
.default => "main",
|
||||||
return error.NotImplemented;
|
.gpa => gpaBlock: {
|
||||||
|
const gpa = "General Purpose Allocator";
|
||||||
|
scopeLen = gpa;
|
||||||
|
|
||||||
|
break :gpaBlock try c.redBright().fmt("{s}", .{gpa});
|
||||||
|
},
|
||||||
|
|
||||||
|
else => elseBlock: {
|
||||||
|
for (globals.additionalScopes.items) |modifier| {
|
||||||
|
if (modifier.scope == scope) {
|
||||||
|
const text = blk: {
|
||||||
|
if (modifier.rename) |rename| {
|
||||||
|
break :blk rename;
|
||||||
|
} else {
|
||||||
|
break :blk @tagName(scope);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
scopeLen = text.len;
|
||||||
|
|
||||||
|
if (modifier.color) |color| {
|
||||||
|
switch (color) {
|
||||||
|
.default => break :elseBlock text,
|
||||||
|
.blue => break :elseBlock try c.blue().fmt("{s}", .{text}),
|
||||||
|
.green => break :elseBlock try c.green().fmt("{s}", .{text}),
|
||||||
|
.red => break :elseBlock try c.red().fmt("{s}", .{text}),
|
||||||
|
.white => break :elseBlock try c.white().fmt("{s}", .{text}),
|
||||||
|
.yellow => break :elseBlock try c.yellow().fmt("{s}", .{text}),
|
||||||
|
.magenta => break :elseBlock try c.magenta().fmt("{s}", .{text}),
|
||||||
|
.cyan => break :elseBlock try c.cyan().fmt("{s}", .{text}),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break :elseBlock text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
longestScopeYet = std.math.max(longestScopeYet, scopeLen);
|
||||||
|
|
||||||
|
const levelText = switch (level) {
|
||||||
|
.debug => try c.gray().fmt("{s: >5}", .{"DEBUG"}),
|
||||||
|
.info => try c.white().fmt("{s: >5}", .{"INFO"}),
|
||||||
|
.warn => try c.yellow().fmt("{s: >5}", .{"WARN"}),
|
||||||
|
.err => try c.red().fmt("{s: >5}", .{"ERROR"}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const paddingLen = longestScopeYet - scopeLen;
|
||||||
|
|
||||||
|
const padding = try arena.allocator().alloc(u8, paddingLen);
|
||||||
|
for (padding) |*p| p.* = ' ';
|
||||||
|
|
||||||
|
const prefix = try std.fmt.allocPrint(arena.allocator(), "[{s}] [{s}{s}]", .{
|
||||||
|
levelText,
|
||||||
|
padding,
|
||||||
|
scopeText,
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = try std.fmt.allocPrint(arena.allocator(), format, args);
|
||||||
|
|
||||||
|
if (globals.enableFileOutput) {
|
||||||
|
var file = try globals.initOrGetFile();
|
||||||
|
var writer = file.writer().any();
|
||||||
|
|
||||||
|
nosuspend try writer.print("{s} {s}\n", .{
|
||||||
|
prefix,
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
nosuspend std.debug.print("{s} {s}\n", .{
|
||||||
|
prefix,
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue