Skip to content

Commit

Permalink
own class for java logging
Browse files Browse the repository at this point in the history
  • Loading branch information
MFlisar committed Jan 18, 2019
1 parent ea18321 commit b462b48
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 122 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package com.michaelflisar.lumberjack.demo;

import com.michaelflisar.lumberjack.L;
import com.michaelflisar.lumberjack.L2;

public class JavaTest
{
public static void test()
{
L.d(new Throwable());
// USE L2 in JAVA code, otherwise callstack won't be correct because of missing inlining functionality in java!
L2.d(new Throwable(), "JAVA 1 - ERROR");

L.d("JAVA 1 - Test message");
L.d("JAVA 2 - Test message with arg: %d", 500);
L.e(new Throwable("ERROR"), "JAVA 3 - Test error");
L2.d("JAVA 2 - Test message");
L2.d("JAVA 3 - Test message with arg: %d", 500);
L2.e(new Throwable("ERROR"), "JAVA 4 - Test error");

L.tag("CUSTOM-TAG").d("JAVA 4 - Test message with custom tag");
L2.tag("CUSTOM-TAG").d("JAVA 5 - Test message with custom tag");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {

// Test 1: a few simple test messages
L.d { "1 - Main activity created" }
L.d { "2a - Test message - count: $count" } // kotlin style args
L.d("2b - Test message - count: %d", count) // java style args - non lazy!!!
L.d { "2 - Test message - count: $count" }
L.e(Throwable("ERROR"), { "3 - Test error" })
L.tag("CUSTOM-TAG").d { "4 - Test message with custom tag" }

Expand Down
95 changes: 0 additions & 95 deletions library/src/main/java/com/michaelflisar/lumberjack/L.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ object L {
}
}

@JvmStatic
fun tag(tag: String): L {
Timber.tag(tag)
return L
Expand All @@ -37,147 +36,53 @@ object L {
// log functions - lazy
// --------------

@JvmStatic
inline fun v(t: Throwable? = null, message: () -> String) = log { Timber.v(t, message()) }

@JvmStatic
inline fun v(t: Throwable?) = log { Timber.v(t) }

@JvmStatic
inline fun v(message: () -> String) = log { Timber.v(message()) }

@JvmStatic
inline fun d(t: Throwable? = null, message: () -> String) = log { Timber.d(t, message()) }

@JvmStatic
inline fun d(t: Throwable?) = log { Timber.d(t) }

@JvmStatic
inline fun d(message: () -> String) = log { Timber.d(message()) }

@JvmStatic
inline fun i(t: Throwable? = null, message: () -> String) = log { Timber.i(t, message()) }

@JvmStatic
inline fun i(t: Throwable?) = log { Timber.i(t) }

@JvmStatic
inline fun i(message: () -> String) = log { Timber.i(message()) }

@JvmStatic
inline fun w(t: Throwable? = null, message: () -> String) = log { Timber.w(t, message()) }

@JvmStatic
inline fun w(t: Throwable?) = log { Timber.w(t) }

@JvmStatic
inline fun w(message: () -> String) = log { Timber.w(message()) }

@JvmStatic
inline fun e(t: Throwable? = null, message: () -> String) = log { Timber.e(t, message()) }

@JvmStatic
inline fun e(t: Throwable?) = log { Timber.e(t) }

@JvmStatic
inline fun e(message: () -> String) = log { Timber.e(message()) }

@JvmStatic
inline fun wtf(t: Throwable? = null, message: () -> String) = log { Timber.wtf(t, message()) }

@JvmStatic
inline fun wtf(t: Throwable?) = log { Timber.wtf(t) }

@JvmStatic
inline fun wtf(message: () -> String) = log { Timber.wtf(message()) }

// --------------
// log functions - NON lazy for usage in java code (backwards compatibility, usage with java libraries)
// --------------

@JvmStatic
inline fun v(t: Throwable? = null, message: String, vararg args: Any) = log { Timber.v(t, message, args) }

@JvmStatic
inline fun v(message: String, vararg args: Any) = log { Timber.v(message, args) }

@JvmStatic
inline fun v(message: String) = log { Timber.v(message) }

@JvmStatic
inline fun d(t: Throwable? = null, message: String, vararg args: Any) = log { Timber.d(t, message, args) }

@JvmStatic
inline fun d(t: Throwable? = null, message: String) = log { Timber.d(t, message) }

@JvmStatic
inline fun d(message: String, vararg args: Any) = log { Timber.d(message, args) }

@JvmStatic
inline fun d(message: String) = log { Timber.d(message) }

@JvmStatic
inline fun i(t: Throwable? = null, message: String, vararg args: Any) = log { Timber.i(t, message, args) }

@JvmStatic
inline fun i(t: Throwable? = null, message: String) = log { Timber.i(t, message) }

@JvmStatic
inline fun i(message: String, vararg args: Any) = log { Timber.i(message, args) }

@JvmStatic
inline fun i(message: String) = log { Timber.i(message) }

@JvmStatic
inline fun w(t: Throwable? = null, message: String, vararg args: Any) = log { Timber.w(t, message, args) }

@JvmStatic
inline fun w(t: Throwable? = null, message: String) = log { Timber.w(t, message) }

@JvmStatic
inline fun w(message: String, vararg args: Any) = log { Timber.w(message, args) }

@JvmStatic
inline fun w(message: String) = log { Timber.w(message) }

@JvmStatic
inline fun e(t: Throwable? = null, message: String, vararg args: Any) = log { Timber.e(t, message, args) }

@JvmStatic
inline fun e(t: Throwable? = null, message: String) = log { Timber.e(t, message) }

@JvmStatic
inline fun e(message: String, vararg args: Any) = log { Timber.e(message, args) }

@JvmStatic
inline fun e(message: String) = log { Timber.e(message) }

@JvmStatic
inline fun wtf(t: Throwable? = null, message: String, vararg args: Any) = log { Timber.wtf(t, message, args) }

@JvmStatic
inline fun wtf(t: Throwable? = null, message: String) = log { Timber.wtf(t, message) }

@JvmStatic
inline fun wtf(message: String, vararg args: Any) = log { Timber.wtf(message, args) }

@JvmStatic
inline fun wtf(message: String) = log { Timber.wtf(message) }

// --------------
// timber forward functions
// --------------

@JvmStatic
inline fun asTree(): Timber.Tree = Timber.asTree()

@JvmStatic
inline fun plant(tree: Timber.Tree) = Timber.plant(tree)

@JvmStatic
inline fun uproot(tree: Timber.Tree) = Timber.uproot(tree)

@JvmStatic
inline fun uprootAll() = Timber.uprootAll()

// --------------
Expand Down
125 changes: 125 additions & 0 deletions library/src/main/java/com/michaelflisar/lumberjack/L2.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package com.michaelflisar.lumberjack

import timber.log.BaseTree
import timber.log.Timber

/*
this class is meant for usage in JAVA only, as functions can't be inlined there
and the callstack index to find the interesting callers class is different because of not inlining the functions!
*/
object L2 {

@JvmStatic
fun tag(tag: String): L2 {
Timber.tag(tag)
return L2
}

@JvmStatic
fun v(t: Throwable?) = L2.log { Timber.v(t) }

@JvmStatic
fun v(t: Throwable? = null, message: String, vararg args: Any) = L2.log { Timber.v(t, message, *args) }

@JvmStatic
fun v(message: String, vararg args: Any) = L2.log { Timber.v(message, *args) }

@JvmStatic
fun v(message: String) = L2.log { Timber.v(message) }

@JvmStatic
fun d(t: Throwable?) = L2.log { Timber.d(t) }

@JvmStatic
fun d(t: Throwable? = null, message: String, vararg args: Any) = L2.log { Timber.d(t, message, *args) }

@JvmStatic
fun d(t: Throwable? = null, message: String) = L2.log { Timber.d(t, message) }

@JvmStatic
fun d(message: String, vararg args: Any) = L2.log { Timber.d(message, *args) }

@JvmStatic
fun d(message: String) = L2.log { Timber.d(message) }

@JvmStatic
fun i(t: Throwable?) = L2.log { Timber.i(t) }

@JvmStatic
fun i(t: Throwable? = null, message: String, vararg args: Any) = L2.log { Timber.i(t, message, *args) }

@JvmStatic
fun i(t: Throwable? = null, message: String) = L2.log { Timber.i(t, message) }

@JvmStatic
fun i(message: String, vararg args: Any) = L2.log { Timber.i(message, *args) }

@JvmStatic
fun i(message: String) = L2.log { Timber.i(message) }

@JvmStatic
fun w(t: Throwable?) = L2.log { Timber.w(t) }

@JvmStatic
fun w(t: Throwable? = null, message: String, vararg args: Any) = L2.log { Timber.w(t, message, *args) }

@JvmStatic
fun w(t: Throwable? = null, message: String) = L2.log { Timber.w(t, message) }

@JvmStatic
fun w(message: String, vararg args: Any) = L2.log { Timber.w(message, *args) }

@JvmStatic
fun w(message: String) = L2.log { Timber.w(message) }

@JvmStatic
fun e(t: Throwable?) = L2.log { Timber.e(t) }

@JvmStatic
fun e(t: Throwable? = null, message: String, vararg args: Any) = L2.log { Timber.e(t, message, *args) }

@JvmStatic
fun e(t: Throwable? = null, message: String) = L2.log { Timber.e(t, message) }

@JvmStatic
fun e(message: String, vararg args: Any) = L2.log { Timber.e(message, *args) }

@JvmStatic
fun e(message: String) = L2.log { Timber.e(message) }

@JvmStatic
fun wtf(t: Throwable?) = L2.log { Timber.wtf(t) }

@JvmStatic
fun wtf(t: Throwable? = null, message: String, vararg args: Any) = L2.log { Timber.wtf(t, message, *args) }

@JvmStatic
fun wtf(t: Throwable? = null, message: String) = L2.log { Timber.wtf(t, message) }

@JvmStatic
fun wtf(message: String, vararg args: Any) = L2.log { Timber.wtf(message, *args) }

@JvmStatic
fun wtf(message: String) = L2.log { Timber.wtf(message) }

// --------------
// helper function
// --------------

fun log(logBlock: () -> Unit) {
if (L.enabled && Timber.treeCount() > 0) {
setCallStackCorrection(4)
logBlock()
}
}

private fun setCallStackCorrection(correction: Int) {
val forest = Timber.forest()
var i = 0
for (tree in forest) {
if (tree is BaseTree) {
tree.setCallStackCorrection(correction)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,4 @@ class StackData(private val className: String, private val simpleFileName: Strin
fun getStackTag() = "$simpleClassName:$line $methodName"

fun getLink() = "$simpleFileName:$line"

fun appendLink(source: String): String {
val lines = source.split("\r\n|\r|\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
if (lines.size <= 1)
return "$source (${getLink()})"
else {
lines[0] = lines[0] + " (" + getLink() + ")"
val builder = StringBuilder()
for (s in lines)
builder.append(s).append("\n")
return builder.toString()
}// this makes sure that links always works, like for example if pretty print for collections is enabled
}
}
28 changes: 24 additions & 4 deletions library/src/main/java/timber/log/BaseTree.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,36 @@ abstract class BaseTree : Timber.Tree() {
internal val CALL_STACK_INDEX = 6
}

private val callStackCorrection = ThreadLocal<Int>()

protected lateinit var lastStackData: StackData

fun getCallStackCorrection(): Int? {
val correction = callStackCorrection.get()
if (correction != null) {
callStackCorrection.remove()
}
return correction
}

fun setCallStackCorrection(value: Int) {
callStackCorrection.set(value)
}

internal override fun getTag(): String? {
// 1) return default tag if one exists

// 1) get stack data
var callStackCorrection = getCallStackCorrection() ?: 0
lastStackData = StackData.create(CALL_STACK_INDEX + callStackCorrection)

// 2) return default tag if one exists
val tag = super.getTag()
if (tag != null) {
return tag
}

// 2) create a custom tag for the logs => we use the
val stackData = StackData.create(CALL_STACK_INDEX)
return "[${stackData.getStackTag()}]"
// 3) create a custom tag for the logs => we use the
return "[${lastStackData.getStackTag()}]"
}

protected fun formatLine(tag: String?, message: String) = "[$tag]: $message"
Expand Down
3 changes: 1 addition & 2 deletions library/src/main/java/timber/log/ConsoleTree.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ class ConsoleTree(val appendClickableLink: Boolean = true) : BaseTree() {
}

private fun appendLink(message: String): String {
val stackData = StackData.create(CALL_STACK_INDEX)
val link = stackData.getLink()
val link = lastStackData.getLink()
val lines = message.split("\r\n|\r|\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
if (lines.size <= 1) {
return message + " (" + link + ")"
Expand Down

0 comments on commit b462b48

Please sign in to comment.