Skip to content

Comments

perf: cache default logger to avoid per-call reconstruction#72

Open
tylerbutler wants to merge 2 commits intomainfrom
fix/cache-default-logger
Open

perf: cache default logger to avoid per-call reconstruction#72
tylerbutler wants to merge 2 commits intomainfrom
fix/cache-default-logger

Conversation

@tylerbutler
Copy link
Owner

Summary

  • Cache the default logger built from global config, returning it directly on subsequent calls
  • Invalidate the cache when configure(), set_level(), or reset_config() is called
  • Pure internal optimization — no API changes

Before

Every call to birch.info(), birch.debug(), etc. would:

  1. Read persistent_term (Erlang) or module-level var (JS)
  2. Construct a new Logger via 4 builder calls
  3. Discard it after the log call

After

First call builds and caches the logger. Subsequent calls return the cached value in O(1). Cache is invalidated only when config changes.

Closes #60

Test plan

  • Erlang tests pass (246 passed)
  • JavaScript tests pass (242 passed)
  • All examples pass
  • Format check passes
  • Tests exercise reset_config() 60+ times, confirming cache invalidation works

@github-actions
Copy link

github-actions bot commented Feb 22, 2026

Changelog Preview

This PR adds the following changelog entries:

v0.3.1 - 2026-02-22

Performance

Cache default logger (#60)

The default logger is now cached and only rebuilt when configuration changes via `configure()`, `set_level()`, or `reset_config()`. Previously it was reconstructed on every log call.

README.md Outdated
}
```

> **Tip:** `import birch/meta as m` keeps metadata concise. All examples in this README use `m.` for brevity, but `meta.` works identically.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use GitHub formatted tips.

let worker_logger =
log.new("myapp.worker")
|> log.with_context([#("worker_id", "worker-1"), #("queue", "high-priority")])
|> log.with_context([meta.string("worker_id", "worker-1"), meta.string("queue", "high-priority")])
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would meta.str as an alias to meta.string be more less gleam like?

The default_logger() function was rebuilding a Logger from global
config on every log call (reading persistent_term, chaining 4
builder calls). Now the logger is cached and only rebuilt when
configure(), set_level(), or reset_config() is called.

Closes #60
@tylerbutler tylerbutler force-pushed the fix/cache-default-logger branch from 5cc5c72 to b766759 Compare February 22, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Default logger is recreated from global config on every log call

1 participant