✨ Modern Logging Lessons from Python, Android & Beyond: Why server-side Java and Kotlin frameworks should borrow more from modern logging approaches found in other ecosystems.
Server-side Java has a long history — and a lot of baggage. When it comes to logging, most teams still default to familiar names like SLF4J, Logback, or Log4j. They’re powerful, performant, and battle-tested.
But they’re also noisy, clunky, and verbose.
Meanwhile, other ecosystems — especially Python, Android, and Kotlin’s own functional libraries — have been quietly reinventing what logging can feel like.
This post makes the case that server-side Kotlin is overdue for a more expressive, ergonomic, and developer-friendly logging approach.
? The State of Logging in Java/Kotlin
Most Spring or backend Kotlin apps use this kind of pattern:
private val logger = LoggerFactory.getLogger(MyService::class.java)
fun doWork() {
logger.info("Starting work")
logger.debug("Fetching data for id={}", id)
}
It works well — but it’s noisy.
- The logger is always injected manually
- The messages are flat strings with placeholders
- MDC (context) is an afterthought, not a first-class pattern
- There’s no expressiveness beyond
INFO
,WARN
, etc.
Now compare that to modern libraries in other ecosystems.
? What Timber Taught Us (Android)
Timber is a logging library in Android, known for:
- Auto-tagging logs with the calling class name
- Replacing
Log.d(TAG, ...)
withTimber.d(...)
- Minimal boilerplate
It shows that logs don’t have to be painful. Logging should get out of your way..
? Python’s Loguru: Logging Without the Pain
Loguru in Python shows what happens when logging is reimagined from scratch:
from loguru import logger
logger.info("Hello")
logger.bind(user="abc123").info("User logged in")
It’s:
- Very simple to start using
- Supports structured context
- Decorates logs with helpful symbols and rich output
No config. No boilerplate. Just expressive logs.
? Functional Kotlin & DSLs
Frameworks like Ktor, Arrow, and Compose embrace the power of DSLs. They make code feel like it describes what you’re doing, not just how.
So why not logging?
LOG_DB log "Fetched 3 rows"
LOG_HANDLER logAt (warn to "Slow response")
This kind of clarity is achievable — but absent from mainstream server-side Java/Kotlin frameworks.
? Enter emoji-logger
Inspired by all of the above, I built emoji-logger as a Kotlin-native logging utility that:
- Wraps SLF4J but gives you expressive emoji symbols
- Resolves loggers automatically using stack inspection
- Supports coroutine-aware MDC blocks
- Feels modern, declarative, and fun
You still get the power of Logback — but with a logging API that feels like Kotlin.
? Time to Rethink What Logging Could Be
Other ecosystems are moving fast:
- Python logs are structured and bindable
- Android logs are auto-tagged
- JS logs are console-rich and context aware
Why are we still writing boilerplate in Kotlin?
Let’s rethink logs — not just as text, but as developer experience.
emoji-logger is my attempt to bring those ideas to the server-side JVM world.
If you’ve ever wanted your logs to be cleaner, richer, or just more you, give it a try.
? Check out the GitHub project
And let me know what you’d want logging to look like in the next generation of Kotlin frameworks.
— Rob