It is convenient to use a logging function that automatically prints the object from which the log call was made. Here, we extend the native Any object (from which all objects in Kotlin derive).
e.g. Call the following function from someObject:
this.log(someString, someOtherObject)
will show the following in LogCat:
applicatioName => someObject => someString, someOtherObject
// we extract the name of this object (derived from Any) from its simpleName member,
// or its fullName if simpleName is empty (or is equal to the object's Companion
// name because we called in a static method)
val Any.logClassTag: String
get() {
val simpleName = this::class.java.getSimpleName()
if(
simpleName.isEmpty() ||
simpleName.equals("Companion")
) {
val fullName = this::class.java.getName()
return fullName.split(".").lastOrNull() ?: fullName
}
return simpleName
}
// This general purpose method takes a variable number of arguments, and adds the
// name of the calling object. Note that it requires spread operator (*) to pass
// the contents of the vararg "values", not values itself
fun Any.log(vararg values: Any?) {
globalLog(this.logClassTag, *values)
}
// define an identifying tag that can be used to filter LogCat for the current app
// e.g. use the current flavor name if it is defined
private val identifier
get() = BuildConfig.FLAVOR
// we define a general log function that formats the variable number of arguments
// together with the calling object tag and an application identifier
fun globalLog(tag: String, vararg values: Any?) {
val identifierAndTag = identifier + " => " + tag + " => "
when(values.size) {
0 -> return
else -> {
Log.d(
identifierAndTag ,
values.mapNotNull {
if (it is String) {
when(it.isEmpty()) {
true -> "<EMPTY>"
false -> it
}
}
else
it.toString()
}.joinToString(" "))
}
}
}
// we can further extend Any with methods that include predefined tags, which
// can be filtered in LogCat to show only "ERROR" or "EXCEPTION"
fun Any.error(vararg values: Any?) {
globalLog(this.logClassTag + " " + "ERROR", *values)
}
fun Any.exception(e: Exception, vararg values: Any?) {
globalLog(this.logClassTag + " " + "EXCEPTION", e.message, *values)
e.printStackTrace()
}