Dynamic logging for Java — minimal source changes, maximum visibility.
CloG (clogger) retrofits structured logging onto existing Java codebases without touching their source. Drop in a Guice module or attach a Java agent, point it at your packages via config, and get entry/exit logging, MDC context propagation, arg capture, and call-stack filtering — for free.
Born from necessity on a large legacy OMS codebase with essentially no logging.
// install the module — nothing else needed
Guice.createInjector(new CloggerGuiceModule(), yourModules...);# clogger.conf
clogger {
mode = dev
rules = [
{
match = "com.yourco.handlers.*"
log = [entry, exit, duration]
capture-args = true
}
]
}java -javaagent:clogger-agent.jar -jar yourapp.jarSame clogger.conf — no source changes required.
- Zero source changes — Guice module or
-javaagentonly - MDC context propagation — every log statement in the call stack carries message context automatically
- Stacked MDC — nested intercepted calls restore parent context correctly on exit
- Arg capture — opt-in, logs method arguments on entry
- Call-stack filtering — only log when called from a matching frame (
requires,excludes) - Duration logging — ms elapsed per method
- Zero allocation on hot path — Byte Buddy
Adviceinlines bytecode; no proxy objects - HOCON config — human-friendly config with env var overrides
@NoAlloc— own annotation to document allocation-free methods; bridgeable to Error Prone
| Module | Purpose |
|---|---|
clogger-api |
Interfaces and @NoAlloc annotation |
clogger-core |
Shared logic, config, MDC stack |
clogger-guice |
Guice AbstractModule integration |
clogger-agent |
Java agent + Byte Buddy instrumentation |
clogger-guice-sample |
Runnable Guice demo |
clogger-agent-sample |
Runnable agent demo (no DI) |
- Java 17+
- SLF4J 2.x + any backend (Logback, Log4j2)
- Guice 7.x (Guice module only)
CloG = Claude + Greg. Built with Claude Code.