# Log scopes in library project

**URL:** <https://ziggit.dev/t/log-scopes-in-library-project/17815>\
**Category:** Help\
**Tags:** standard-library\
**Created:** [October 3, 2026, 12:48pm UTC](https://ziggit.dev/t/log-scopes-in-library-project/17815 "2026-10-03T12:48:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![sinclairt](https://ziggit.dev/user_avatar/ziggit.dev/sinclairt/32/10347_2.png) [@sinclairt](https://ziggit.dev/u/sinclairt)\
**Post date:** [October 3, 2026, 12:48pm UTC](https://ziggit.dev/t/log-scopes-in-library-project/17815/1 "2026-10-03T12:48:20Z")

</div>

I’m working on a project that’s meant to be consumed as a library by other Zig projects. Since I want it to be straightforward for any consumers of my library to control logging from my library, I’m using a single log scope for the whole project.

But this is kind of a bummer, because I’d like to be able to turn on and off logging for different components in my codebase as I’m debugging. I’d prefer to have three or four different log scopes, one for each major component in my library.

Hierarchical log scopes (something like `my-library.subcomponent-a`, as in Python) would solve this problem. I could have my own little log scopes clustered under the main log scope that I can turn on and off, while downstream users of the library can silence _all_ logs in one go using the main log scope.

To my knowledge, Zig’s log scopes don’t work like that. So the best solution I’ve come up with is to have a Zig build CLI option that enables my more granular log scopes. When debugging I can set this to true. Otherwise, when that option is off, everything goes under one log scope.

Is there a better, more idiomatic solution?

---

<div class="post-metadata">

**Author:** ![lalinsky](https://ziggit.dev/user_avatar/ziggit.dev/lalinsky/32/3720_2.png) [@lalinsky](https://ziggit.dev/u/lalinsky)\
**Post date:** [October 3, 2026, 1:49pm UTC](https://ziggit.dev/t/log-scopes-in-library-project/17815/2 "2026-10-03T13:49:00Z")

</div>

I don’t think there is a better solution, but I’d also love if there was. I currently stick to one scope per library, to make it easier to control it in the app, but your build option idea makes sense to me, I’ll likely try using it myself.

---

<div class="post-metadata">

**Author:** ![pzittlau](https://ziggit.dev/letter_avatar_proxy/v4/letter/p/ecae2f/32.png) [@pzittlau](https://ziggit.dev/u/pzittlau)\
**Post date:** [October 3, 2026, 5:11pm UTC](https://ziggit.dev/t/log-scopes-in-library-project/17815/3 "2026-10-03T17:11:54Z")

</div>

I had that same problem and build [this](https://codeberg.org/pzittlau/tag_log) small, basically drop-in, for the standard library logging.

It has hierarchical tag-based logging. Scopes can be enabled, disabled and overridden as needed in `comptime` by just putting something at a higher priority(the first rule that matches is used).

There are only three real downsides compared to the one in the standard library:

- the compilation takes a bit longer as more things need to be evaluated
- the binary is a bit larger
- it’s not in the standard library…

* * *

I was thinking about proposing something like this for the standard library but I don’t quite know if it would fit.

---

<div class="post-metadata">

**Author:** ![mg979](https://ziggit.dev/letter_avatar_proxy/v4/letter/m/3e96dc/32.png) [@mg979](https://ziggit.dev/u/mg979)\
**Post date:** [October 3, 2026, 5:44pm UTC](https://ziggit.dev/t/log-scopes-in-library-project/17815/4 "2026-10-03T17:44:14Z")

</div>

I’m using something like this

```zig
pub const Log = struct {
    pub fn warn(
        comptime kind: LogKind,
        comptime fmt: []const u8,
        args: anytype,
    ) void {
        switch (kind)
        {
            .always => {},
            .collision => if (!C.debug.collision) return,
            .sky => if (!C.debug.sky) return,
            .climate => if (!C.debug.climate) return,
            .arenas => if (!C.debug.arenas) return,
        }
        std.log.warn(fmt, args);
    }

    pub fn info(
        comptime kind: LogKind,
        comptime fmt: []const u8,
        args: anytype,
    ) void {
        switch (kind)
        {
            .always => {},
            .collision => if (!C.debug.collision) return,
            .sky => if (!C.debug.sky) return,
            .climate => if (!C.debug.climate) return,
            .arenas => if (!C.debug.arenas) return,
        }
        std.log.info(fmt, args);
    }
};

```

but you could replace the constants with some runtime options (like from argument parsing) if you want something more dynamical
