prefect server in zig
at f511403a2b901063559cd17995b45527418e76c6 102 lines 3.0 kB view raw
1const std = @import("std"); 2const posix = std.posix; 3 4pub const Level = enum(u8) { 5 debug = 10, 6 info = 20, 7 warning = 30, 8 err = 40, 9 critical = 50, 10 11 pub fn fromString(s: []const u8) Level { 12 if (std.ascii.eqlIgnoreCase(s, "DEBUG")) return .debug; 13 if (std.ascii.eqlIgnoreCase(s, "INFO")) return .info; 14 if (std.ascii.eqlIgnoreCase(s, "WARNING") or std.ascii.eqlIgnoreCase(s, "WARN")) return .warning; 15 if (std.ascii.eqlIgnoreCase(s, "ERROR")) return .err; 16 if (std.ascii.eqlIgnoreCase(s, "CRITICAL")) return .critical; 17 return .warning; 18 } 19 20 pub fn name(self: Level) []const u8 { 21 return switch (self) { 22 .debug => "DEBUG", 23 .info => "INFO", 24 .warning => "WARNING", 25 .err => "ERROR", 26 .critical => "CRITICAL", 27 }; 28 } 29}; 30 31var server_level: Level = .warning; 32 33pub fn init() void { 34 if (posix.getenv("PREFECT_SERVER_LOGGING_LEVEL")) |level_str| { 35 server_level = Level.fromString(level_str); 36 } else if (posix.getenv("PREFECT_LOGGING_LEVEL")) |level_str| { 37 server_level = Level.fromString(level_str); 38 } 39} 40 41pub fn setLevel(level: Level) void { 42 server_level = level; 43} 44 45pub fn getLevel() Level { 46 return server_level; 47} 48 49fn getTimestamp(buf: *[12]u8) []const u8 { 50 const ms_total = std.time.milliTimestamp(); 51 const ms: u64 = @intCast(@mod(ms_total, 1000)); 52 const epoch_secs: u64 = @intCast(@divFloor(ms_total, 1000)); 53 const secs_today = epoch_secs % 86400; 54 const hours = secs_today / 3600; 55 const mins = (secs_today % 3600) / 60; 56 const secs = secs_today % 60; 57 58 return std.fmt.bufPrint(buf, "{d:0>2}:{d:0>2}:{d:0>2}.{d:0>3}", .{ 59 hours, mins, secs, ms, 60 }) catch "00:00:00.000"; 61} 62 63fn writeStderr(data: []const u8) void { 64 const stderr = std.fs.File.stderr(); 65 stderr.writeAll(data) catch {}; 66} 67 68pub fn log(level: Level, component: []const u8, comptime fmt: []const u8, args: anytype) void { 69 if (@intFromEnum(level) < @intFromEnum(server_level)) return; 70 71 var ts_buf: [12]u8 = undefined; 72 const ts = getTimestamp(&ts_buf); 73 74 var buf: [4096]u8 = undefined; 75 const len = (std.fmt.bufPrint(&buf, "{s} | {s: <8} | {s} - " ++ fmt ++ "\n", .{ 76 ts, 77 level.name(), 78 component, 79 } ++ args) catch return).len; 80 81 writeStderr(buf[0..len]); 82} 83 84pub fn debug(component: []const u8, comptime fmt: []const u8, args: anytype) void { 85 log(.debug, component, fmt, args); 86} 87 88pub fn info(component: []const u8, comptime fmt: []const u8, args: anytype) void { 89 log(.info, component, fmt, args); 90} 91 92pub fn warn(component: []const u8, comptime fmt: []const u8, args: anytype) void { 93 log(.warning, component, fmt, args); 94} 95 96pub fn err(component: []const u8, comptime fmt: []const u8, args: anytype) void { 97 log(.err, component, fmt, args); 98} 99 100pub fn critical(component: []const u8, comptime fmt: []const u8, args: anytype) void { 101 log(.critical, component, fmt, args); 102}