Reputation: 1836
Is possible log the current line number and method name using the Timber library?
Expected LogCat result:
ismaeldivita.myapp I/[L:22] [M:onResume] [C:HomeActivity]: Praise the log!
Upvotes: 21
Views: 8949
Reputation: 193
Extending on Ugurcan Yildirim answer so it handles lambda method names as well
@Override
protected String createStackElementTag(@NonNull StackTraceElement element) {
String mName=element.getMethodName();
if(mName.startsWith("lambda$")){
String[] frames = mName.split("\\$");
if(frames.length>2){
mName = frames[0] + "$"+ frames[1];
}
}
String x = String.format("(%s:%s)#%s",element.getFileName(),element.getLineNumber(),mName);
return x;
}
Without above fix for logs where methodName returns e.g. lambda$onCreate$8$com-swiftthoughts-wordkons-ActivityStartJoinGame
the debug log appears on log cat as
[
With above changes it appears as expected
Upvotes: 0
Reputation: 3798
I use this class.
object Logg {
private fun tag(): String? {
return Thread.currentThread().stackTrace[4].let {
val link = "(${it.fileName}:${it.lineNumber})"
val path = "App# ${it.className.substringAfterLast(".")}.${it.methodName}"
if (path.length + link.length > 80) {
"${path.take(80 - link.length)}...${link}"
} else {
"$path$link"
}
}
}
fun v(msg: String?) {
Log.v(tag(), "💜 $msg")
}
fun d(msg: String?) {
Log.d(tag(), "💙 $msg")
}
fun i(msg: String?) {
Log.i(tag(), "💚 $msg")
}
fun w(msg: String?) {
Log.w(tag(), "💛 $msg")
}
fun w(e: Throwable?) {
Log.w(tag(), "💛 ${e?.localizedMessage}")
e?.printStackTrace()
}
fun w(e: Exception?) {
Log.w(tag(), "💛 ${e?.localizedMessage}")
e?.printStackTrace()
}
fun w(e: LinkageError?) {
Log.w(tag(), "💛 ${e?.localizedMessage}")
e?.printStackTrace()
}
fun e(msg: String?) {
Log.e(tag(), "💔 $msg")
}
fun e(e: Throwable?) {
Log.e(tag(), "💔 ${e?.localizedMessage}")
e?.printStackTrace()
}
fun e(e: java.lang.Exception?) {
Log.e(tag(), "💔 ${e?.localizedMessage}")
e?.printStackTrace()
}
}
How to use:
Logg.e("====== log here ==========")
Result:
Upvotes: 2
Reputation: 860
That is how i solved it in my Application class using Kotlin:
class App : Application() {
override fun onCreate() {
super.onCreate()
initLogger()
}
private fun initLogger() {
if (BuildConfig.DEBUG) {
Timber.plant(object : Timber.DebugTree() {
override fun createStackElementTag(element: StackTraceElement): String? {
return "(${element.fileName}:${element.lineNumber})#${element.methodName}"
}
})
}
}
Upvotes: 6
Reputation: 76922
improving on Ismael Di Vita answer so it displays in logcat as a hyperlink like this.
public class MyDebugTree extends Timber.DebugTree {
@Override
protected String createStackElementTag(StackTraceElement element) {
return String.format("(%s:%s)#%s",
element.getFileName(),
element.getLineNumber(),
element.getMethodName());
}
}
or for kotlin
class LineNumberDebugTree : Timber.DebugTree() {
override fun createStackElementTag(element: StackTraceElement): String? {
return "(${element.fileName}:${element.lineNumber})#${element.methodName}"
}
}
Note: use element.fileName instead of element.className so it works in kotlin for logging outside a class
from my utils lib
Upvotes: 37
Reputation: 31
You can also use my library https://github.com/farhad2161/betterlog
It will show the method name where logs happened.
The output will be something like this
e/MYTAG: [com.kia.betterlogapp.MainActivity.writeDummyLog][label1]I am error message
Upvotes: -5
Reputation: 1836
Answering my own question.
Just create a new DebugTree class
public class MyDebugTree extends Timber.DebugTree {
@Override
protected String createStackElementTag(StackTraceElement element) {
return String.format("[L:%s] [M:%s] [C:%s]",
element.getLineNumber(),
element.getMethodName(),
super.createStackElementTag(element));
}
}
And plant your Tree in Timber:
public class App extends Application {
@Override
public void onCreate(){
super.onCreate();
if (BuildConfig.DEBUG) {
Timber.plant(new MyDebugTree());
} else {
//TODO plant your Production Tree
}
}
}
Upvotes: 44