Kotlin Log库推荐

2018-11-29  本文已影响25人  老鱼的储物柜

在练习Kotlin项目中,把原来Android项目中封装的Log库改了一下

可以打印String、XML、JSON等多种类型的数据

使用方式

在application中做初始化操作
    override fun onCreate() {
        super.onCreate()
        INSTANCE = this

        //Initialize the logger
        initLogger(BuildConfig.DEBUG, "Rain")
    }
loge("哈哈哈哈哈哈")
loge("Rain","哈哈哈哈")
package com.rain.commonsdk.logger

import android.app.Application
import android.text.TextUtils
import android.util.Log
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.io.StringReader
import java.io.StringWriter
import javax.xml.transform.OutputKeys
import javax.xml.transform.TransformerFactory
import javax.xml.transform.stream.StreamResult
import javax.xml.transform.stream.StreamSource


private var TAG = "Entrepreneurial"
private var LOG_DEBUG = true
private val LINE_SEPARATOR: String = System.getProperty("line.separator")
const val VERBOSE = 2
const val DEBUG = 3
const val INFO = 4
const val WARN = 5
const val ERROR = 6
const val ASSERT = 7
const val JSON = 8
const val XML = 9
const val JSON_INDENT = 4

fun Application.initLogger(isDebug: Boolean, tag: String) {
    TAG = tag
    LOG_DEBUG = isDebug
}

fun logv(msg: String) = log(VERBOSE, null, msg)

fun logv(tag: String, msg: String) = log(VERBOSE, tag, msg)

fun logd(msg: String) = log(DEBUG, null, msg)

fun logd(tag: String, msg: String) = log(DEBUG, tag, msg)

fun logi(vararg msg: Any) {
    val sb = StringBuilder()
    for (obj in msg) {
        sb.append(obj)
        sb.append(",")
    }
    log(INFO, null, sb.toString())
}

fun logw(msg: String) = log(WARN, null, msg)

fun logw(tag: String, msg: String) = log(WARN, tag, msg)

fun loge(msg: String) = log(ERROR, null, msg)

fun loge(tag: String, msg: String) = log(ERROR, tag, msg)

fun loga(msg: String) = log(ASSERT, null, msg)

fun loga(tag: String, msg: String) = log(ASSERT, tag, msg)

fun logJson(json: String) = log(JSON, null, json)

fun logjson(tag: String, json: String) = log(JSON, tag, json)

fun logXml(xml: String) = log(XML, null, xml)

fun logXml(tag: String, xml: String) = log(XML, tag, xml)

private fun log(logType: Int, tagStr: String?, objects: Any) {
    val contents = wrapperContent(tagStr, objects)
    val tag = contents[0]
    val msg = contents[1]
    val headString = contents[2]
    if (LOG_DEBUG) {
        when (logType) {
            VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT -> printDefault(logType, tag, headString + msg)
            JSON -> printJson(tag, msg, headString)
            XML -> printXml(tag, msg, headString)
            else -> {
            }
        }
    }
}

fun printDefault(type: Int, tag: String, msg: String) {
    var tag = tag
    if (TextUtils.isEmpty(tag)) {
        tag = TAG
    }
    var index = 0
    val maxLength = 3900
    val countOfSub = msg.length / maxLength

    if (countOfSub > 0) {  // The log is so long
        for (i in 0 until countOfSub) {
            val sub = msg.substring(index, index + maxLength)
            printSub(type, tag, sub)
            index += maxLength
        }
        printSub(type, tag, msg.substring(index, msg.length))
    } else {
        printSub(type, tag, msg)
    }

}

private fun printSub(type: Int, tag: String?, sub: String) {
    var tag = tag
    if (tag == null) {
        tag = TAG
    }
    printLine(tag, true)
    when (type) {
        VERBOSE -> Log.v(tag, sub)
        DEBUG -> Log.d(tag, sub)
        INFO -> Log.i(tag, sub)
        WARN -> Log.w(tag, sub)
        ERROR -> Log.e(tag, sub)
        ASSERT -> Log.wtf(tag, sub)
    }
    printLine(tag, false)
}

private fun printJson(tag: String, json: String, headString: String) {
    var tag = tag
    if (TextUtils.isEmpty(json)) {
        logd("Empty/Null json content")
        return
    }
    if (TextUtils.isEmpty(tag)) {
        tag = TAG
    }
    var message: String

    message = try {
        when {
            json.startsWith("{") -> {
                val jsonObject = JSONObject(json)
                jsonObject.toString(JSON_INDENT)
            }
            json.startsWith("[") -> {
                val jsonArray = JSONArray(json)
                jsonArray.toString(JSON_INDENT)
            }
            else -> json
        }
    } catch (e: JSONException) {
        json
    }

    printLine(tag, true)
    message = headString + LINE_SEPARATOR + message
    val lines = message.split(LINE_SEPARATOR.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
    for (line in lines) {
        Log.d(tag, "|$line")
    }
    printLine(tag, false)
}

private fun printXml(tag: String, xml: String?, headString: String) {
    var tag = tag
    var xml = xml
    if (TextUtils.isEmpty(tag)) {
        tag = TAG
    }
    if (xml != null) {
        try {
            val xmlInput = StreamSource(StringReader(xml))
            val xmlOutput = StreamResult(StringWriter())
            val transformer = TransformerFactory.newInstance().newTransformer()
            transformer.setOutputProperty(OutputKeys.INDENT, "yes")
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2")
            transformer.transform(xmlInput, xmlOutput)
            xml = xmlOutput.writer.toString().replaceFirst(">", ">\n")
        } catch (e: Exception) {
            e.printStackTrace()
        }

        xml = headString + "\n" + xml
    } else {
        xml = headString + "Log with null object"
    }

    printLine(tag, true)
    val lines = xml.split(LINE_SEPARATOR.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
    for (line in lines) {
        if (!TextUtils.isEmpty(line)) {
            Log.d(tag, "|$line")
        }
    }
    printLine(tag, false)
}

private fun wrapperContent(tag: String?, vararg objects: Any): Array<String> {
    var tag = tag
    if (TextUtils.isEmpty(tag)) {
        tag = TAG
    }
    val stackTrace = Thread.currentThread().stackTrace
    val targetElement = stackTrace[5]
    var className = targetElement.className
    val classNameInfo = className.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
    if (classNameInfo.isNotEmpty()) {
        className = classNameInfo[classNameInfo.size - 1] + ".java"
    }
    val methodName = targetElement.methodName
    var lineNumber = targetElement.lineNumber
    if (lineNumber < 0) {
        lineNumber = 0
    }
    val methodNameShort = methodName.substring(0, 1).toUpperCase() + methodName.substring(1)
    val msg = if (objects == null) "Log with null object" else getObjectsString(*objects)
    val headString = "[($className:$lineNumber)#$methodNameShort ] "
    return arrayOf(tag!!, msg, headString)
}

fun getObjectsString(vararg objects: Any): String {

    if (objects.size > 1) {
        val stringBuilder = StringBuilder()
        stringBuilder.append("\n")
        for (i in objects.indices) {
            val `object` = objects[i]
            if (`object` == null) {
                stringBuilder.append("param").append("[").append(i).append("]").append(" = ").append("null").append("\n")
            } else {
                stringBuilder.append("param").append("[").append(i).append("]").append(" = ").append(`object`.toString()).append("\n")
            }
        }
        return stringBuilder.toString()
    } else {
        val `object` = objects[0]
        return `object`?.toString()
    }
}

private fun printLine(tag: String, isTop: Boolean) {
    if (isTop) {
        Log.d(tag, "╔═══════════════════════════════════════════════════════════════════════════════════════")
    } else {
        Log.d(tag, "╚═══════════════════════════════════════════════════════════════════════════════════════")
    }
}
上一篇 下一篇

猜你喜欢

热点阅读