SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/util/LogCategory.kt

219 lines
6.6 KiB
Kotlin

package jp.juggler.subwaytooter.util
import android.content.ContentValues
import android.content.res.Resources
import java.util.Collections
import java.util.IdentityHashMap
import jp.juggler.subwaytooter.table.LogData
class LogCategory(private val category : String) {
companion object {
/**
* Caption for labeling causative exception stack traces
*/
private const val CAUSE_CAPTION = "Caused by: "
/**
* Caption for labeling suppressed exception stack traces
*/
private const val SUPPRESSED_CAPTION = "Suppressed: "
}
private val cv = ContentValues()
// fun addLog(level : Int, message : String) {
// synchronized(cv) {
// LogData.insert(cv, System.currentTimeMillis(), level, category, message)
// }
// }
fun e(fmt : String, vararg args : Any?) {
val message = if( args.isEmpty() ) fmt else String.format(fmt, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_ERROR, category, message)
}
}
fun w(fmt : String, vararg args : Any?) {
val message = if( args.isEmpty() ) fmt else String.format(fmt, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_WARNING, category, message)
}
}
fun i(fmt : String, vararg args : Any?) {
val message = if( args.isEmpty() ) fmt else String.format(fmt, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_INFO, category, message)
}
}
fun v(fmt : String, vararg args : Any?) {
val message = if( args.isEmpty() ) fmt else String.format(fmt, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_VERBOSE, category, message)
}
}
fun d(fmt : String, vararg args : Any?) {
val message = if( args.isEmpty() ) fmt else String.format(fmt, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_DEBUG, category, message)
}
}
fun h(fmt : String, vararg args : Any?) {
val message = if( args.isEmpty() ) fmt else String.format(fmt, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_HEARTBEAT, category, message)
}
}
fun f(fmt : String, vararg args : Any?) {
val message = if( args.isEmpty() ) fmt else String.format(fmt, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_FLOOD, category, message)
}
}
////////////////////////
// getString()
fun e(res : Resources, string_id : Int, vararg args : Any?) {
val fmt = res.getString(string_id, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_ERROR, category, fmt)
}
}
fun w(res : Resources, string_id : Int, vararg args : Any?) {
val fmt = res.getString(string_id, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_WARNING, category, fmt)
}
}
fun i(res : Resources, string_id : Int, vararg args : Any?) {
val fmt = res.getString(string_id, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_INFO, category, fmt)
}
}
fun v(res : Resources, string_id : Int, vararg args : Any?) {
val fmt = res.getString(string_id, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_VERBOSE, category, fmt)
}
}
fun d(res : Resources, string_id : Int, vararg args : Any?) {
val fmt = res.getString(string_id, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_DEBUG, category, fmt)
}
}
fun h(res : Resources, string_id : Int, vararg args : Any?) {
val fmt = res.getString(string_id, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_HEARTBEAT, category, fmt)
}
}
fun f(res : Resources, string_id : Int, vararg args : Any?) {
val fmt = res.getString(string_id, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_FLOOD, category, fmt)
}
}
////////////////////////
// exception
fun e(ex : Throwable, fmt : String, vararg args : Any?) {
val message = if( args.isEmpty() ) fmt else String.format(fmt, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_ERROR, category, message + String.format(":%s %s", ex.javaClass.simpleName, ex.message))
}
}
fun e(ex : Throwable, res : Resources, string_id : Int, vararg args : Any?) {
val message = res.getString(string_id, *args)
synchronized(cv) {
LogData.insert(cv, System.currentTimeMillis(), LogData.LEVEL_ERROR, category, message + String.format(":%s %s", ex.javaClass.simpleName, ex.message))
}
}
fun trace(ex : Throwable) {
//// ex.printStackTrace();
// Guard against malicious overrides of Throwable.equals by
// using a Set with identity equality semantics.
val dejaVu = Collections.newSetFromMap(IdentityHashMap<Throwable, Boolean>())
dejaVu.add(ex)
// Print our stack trace
e(ex.toString())
val trace = ex.stackTrace
for(traceElement in trace) {
e("\tat " + traceElement)
}
// Print suppressed exceptions, if any
for(se in ex.suppressed)
printEnclosedStackTrace(se, trace, SUPPRESSED_CAPTION, "\t", dejaVu)
// Print cause, if any
val ourCause = ex.cause
if(ourCause != null)
printEnclosedStackTrace(ourCause, trace, CAUSE_CAPTION, "", dejaVu)
}
/**
* Print our stack trace as an enclosed exception for the specified
* stack trace.
*/
private fun printEnclosedStackTrace(
ex : Throwable, enclosingTrace : Array<StackTraceElement>, caption : String, prefix : String, dejaVu : MutableSet<Throwable>
) {
if(dejaVu.contains(ex)) {
e("\t[CIRCULAR REFERENCE:$ex]")
} else {
dejaVu.add(ex)
// Compute number of frames in common between this and enclosing trace
val trace = ex.stackTrace
var m = trace.size - 1
var n = enclosingTrace.size - 1
while(m >= 0 && n >= 0 && trace[m] == enclosingTrace[n]) {
m --
n --
}
val framesInCommon = trace.size - 1 - m
// Print our stack trace
e(prefix + caption + ex)
for(i in 0 .. m)
e(prefix + "\tat " + trace[i])
if(framesInCommon != 0)
e("$prefix\t... $framesInCommon more")
// Print suppressed exceptions, if any
for(ex2 in ex.suppressed)
printEnclosedStackTrace(ex2, trace, SUPPRESSED_CAPTION, prefix + "\t", dejaVu)
// Print cause, if any
val ourCause = ex.cause
if(ourCause != null)
printEnclosedStackTrace(ourCause, trace, CAUSE_CAPTION, prefix, dejaVu)
}
}
}