ajalt / timberkt Goto Github PK
View Code? Open in Web Editor NEWEasy Android logging with Kotlin and Timber
License: Apache License 2.0
Easy Android logging with Kotlin and Timber
License: Apache License 2.0
The Timber
object only supports lambda syntax: Timber.d { "some string" }
. Even though it's effectively the same thing, it should also support the same syntax as the original Timber
: Timber.d("some string")
.
For example replace:
@JvmStatic inline fun i(t: Throwable? = null, message: () -> String) = log { Timber.i(t, message()) }
with
@JvmOverloads @JvmStatic inline fun i(t: Throwable? = null, message: () -> String) = log { Timber.i(t, message()) }
Currently, we have to pass null explicitly in Java
If com.github.ajalt.timberkt.Timber
is imported in the class you wish to plant the Timber.DebugTree
, then you have to use a qualified import e.g. Timber.plant(timber.log.Timber.DebugTree())
.
It would be nice if com.github.ajalt.timberkt.Timber
contained a function to return timber.log.Timber.DebugTree
so that the code could read Timber.plant(Timber.DebugTree())
.
Hi,
hope find you well with this cold call.
I am an author of mocking framework for Kotlin
I see you are using mockito-kotlin.
I just want you to be aware that there is solution that fully supports Kotlin and ask to try it in your new/current projects.
I can help you if you answer to this issue.
Thanks and please star it
I am using an object that is containing an optional exception inside (http response), but that is nullable and I cannot use your wrapper around Timber for logging this optional exception.
Wouldn't it be better if the throwable was nullable and simply call Timber.e(msg)
if it as null?
inline fun e(t: Throwable? = null, message: () -> String) = log { if (t==null) Timber.e(message()) else Timber.e(t, message()) }
I think that even without with the null check we would be safe since the throwable
in the Tree is nullable.
Lazy evaluation of the message is one of the selling points of TimberKt, BUT...
Currently TimberKt doesn't care if a tag is loggable or not. It evaluates the message string and lets Timber do the dirty work. The message evaluation happens always, including cases when the log would be discarded.
if (Timber.treeCount() > 0)
is just not good enough for this case.
Example: I have a CrashlyticsTree
that logs just warnings and errors to Crashlytics. However, all log messages are evaluated just so that debug, info, and verbose could be dropped later.
class CrashlyticsTree : Timber.Tree() {
override fun isLoggable(tag: String?, priority: Int): Boolean = priority >= Log.WARN
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
Crashlytics.log(message)
t?.let { Crashlytics.logException(it) }
}
}
Another example: Logging that's controlled at runtime. With a permanently attached tree.
class AndroidTree : Timber.Tree() {
override fun isLoggable(priority: Int): Boolean = Log.isLoggable("ASDF", priority)
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
// ...
}
}
or something like this
class AndroidTree(private val prefs: SharedPreferences) : Timber.Tree() {
override fun isLoggable(priority: Int): Boolean = prefs.getBoolean("log", false)
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
// ...
}
}
Wrap the message lambda in a object that's only evaluated when timber gets to format the output.
private class MessageWrapper internal constructor(messageProvider: () -> String) {
private val message by lazy(LazyThreadSafetyMode.NONE) { messageProvider() }
override fun toString(): String = message
}
inline fun td1(throwable: Throwable? = null, noinline message: () -> String) {
Timber.d(throwable, "%s", MessageWrapper(message))
}
inline fun td1(throwable: Throwable) {
Timber.d(throwable)
}
inline fun td1(noinline message: () -> String) {
Timber.d("%s", MessageWrapper(message))
}
This could be made more efficient maybe with inline classes or whatnot... Current cost of this is one extra wrapper object and one extra lazy delegate object per call.
Well... totally copy Timber into TimberKt and adapt prepareLog
method for Kotlin use style.
private void prepareLog(int priority, Throwable t, String message, Object... args) {
// Consume tag even when message is not loggable so that next message is correctly tagged.
String tag = getTag();
if (!isLoggable(tag, priority)) {
return;
}
if (message != null && message.length() == 0) {
message = null;
}
if (message == null) {
if (t == null) {
return; // Swallow message if it's null and there's no throwable.
}
message = getStackTraceString(t);
} else {
if (args != null && args.length > 0) {
message = formatMessage(message, args);
}
if (t != null) {
message += "\n" + getStackTraceString(t);
}
}
log(priority, tag, message, t);
}
private fun prepareLog(priority: Int, t: Throwable?, messageProvider: () -> String?) {
// ...
}
so can i get rid of my Timber java logger in gradle and use yours ? I still have java and new kotlin files. i have a subclass of the timber tree i am using. can i swap it for yours and it will work in java calls as well ?
can i do this:
Timber.plant(timber.log.Timber.DebugTree())
I noticed that the extension methods in timberkt are on Timber's Tree class: Timber.Tree.d(...)
Why is this the case? Why aren't they on the Timber
class directly? Because of this I have to import your Timber object instead of using the regular Timber class. Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.