Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
import timber.log.Timber
import kotlin.reflect.KProperty
class MyClass {
// This will automatically have the TAG "MyClass"
private val log by timber()
fun logSomething() {
log.w(Exception(), "World")
* Use this delegate to have easy access to Timber logging in your class.
* Add `private val log by timber()` to your class. It will automatically use your class name as a tag,
* trim it to 23 characters and replace Fragment with Frag and ViewModel to VM by default if it is too long,
* finally, just truncating the class name if needed.
* If the default option is not good enough, you can pass in a custom tag.
inline fun <reified T : Any> T.timber(tag: String? = null) = TimberLoggerProperty<T>(tag)
class TimberLoggerProperty<T : Any>(private val tag: String? = null) : ReadOnlyProperty<T, TimberLogger> {
@Volatile var logger: TimberLogger? = null
override fun getValue(thisRef: T, property: KProperty<*>): TimberLogger {
logger?.let { return it }
logger = TimberLogger(thisRef, tag)
return logger!!
class TimberLogger(thisRef: Any, tag: String? = null) : Timber.Tree() {
private val tag = tag ?: thisRef.toTag()
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
Timber.tag(tag ?: this.tag).log(priority, t, message)
private fun Any.toTag(): String {
val str =
.run { if (endsWith("Impl")) substring(0, length - 4) else this }
if (str.length <= 23) {
return str
return str
.replace("Fragment", "Frag")
.replace("ViewModel", "VM")
.replace("Controller", "Ctrl")
.replace("Manager", "Mgr")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment