Set debug level at runtime

Hello, I set my log level like this in my main.zig:

pub const std_options = .{
    .log_level = .info,
};

I would like to set the debug level depedning on cli arguments however. Can this be achieved with the built-in logger?

i don’t think so. (one advantage of setting the log level at compile time is that the logging code can be omitted by the compiler entirely when its conditions are not met.)

however, writing your own logging function is pretty painless!

1 Like

It’s not an issue to recompile for me, but when I distribute games & similar stuff, I add a debug toggle, so regular people can report issues with more context, without rebuilding. I can work around this either by using a 3rd party lib, or making a launcher which rebuilds the software.

What @alanza was referring to is something like this, where you can write a custom logging function wrapping the default one to take care of checking against the runtime selected log level:

const std = @import("std");

pub const std_options: std.Options = .{
    .logFn = logFn,
    .log_level = .debug,
};

var log_level = std.log.default_level;

fn logFn(
    comptime message_level: std.log.Level,
    comptime scope: @TypeOf(.enum_literal),
    comptime format: []const u8,
    args: anytype,
) void {
    if (@intFromEnum(message_level) <= @intFromEnum(log_level)) {
        std.log.defaultLog(message_level, scope, format, args);
    }
}

pub fn main() !void {
    var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena_state.deinit();
    const arena = arena_state.allocator();
    const args = try std.process.argsAlloc(arena);
    if (args.len >= 2) {
        log_level = std.meta.stringToEnum(std.log.Level, args[1]) orelse {
            std.log.err("unknown log level: {s}", .{args[1]});
            std.process.exit(1);
        };
    }

    std.log.err("err", .{});
    std.log.warn("warn", .{});
    std.log.info("info", .{});
    std.log.debug("debug", .{});
}

The log_level selected in std_options here is the highest (most debug-y) level of log you want to make available in your build, since it controls the comptime filtering of logs; anything higher than that level will not even make it to logFn.

8 Likes