Using now kmp-log
This commit is contained in:
parent
4330675e78
commit
0ac6059306
|
@ -63,6 +63,8 @@ kotlin {
|
|||
dependencies {
|
||||
api project(":multiplatform-utils")
|
||||
|
||||
implementation("net.codinux.log:kmp-log:1.1.2")
|
||||
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1"
|
||||
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion"
|
||||
|
|
|
@ -2,6 +2,7 @@ package net.dankito.banking.fints
|
|||
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.datetime.LocalDate
|
||||
import net.codinux.log.logger
|
||||
import net.dankito.banking.fints.messages.MessageBuilder
|
||||
import net.dankito.banking.fints.messages.MessageBuilderResult
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrens
|
||||
|
@ -17,7 +18,6 @@ import net.dankito.banking.fints.response.segments.*
|
|||
import net.dankito.banking.fints.tan.FlickerCodeDecoder
|
||||
import net.dankito.banking.fints.tan.TanImageDecoder
|
||||
import net.dankito.banking.fints.util.TanMethodSelector
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
import net.dankito.utils.multiplatform.extensions.millisSinceEpochAtEuropeBerlin
|
||||
import net.dankito.utils.multiplatform.extensions.minusDays
|
||||
import net.dankito.utils.multiplatform.extensions.todayAtEuropeBerlin
|
||||
|
@ -36,9 +36,7 @@ open class FinTsJobExecutor(
|
|||
protected open val tanMethodSelector: TanMethodSelector = TanMethodSelector()
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(FinTsJobExecutor::class)
|
||||
}
|
||||
private val log by logger()
|
||||
|
||||
|
||||
open suspend fun getAnonymousBankInfo(context: JobContext): BankResponse {
|
||||
|
@ -426,7 +424,7 @@ open class FinTsJobExecutor(
|
|||
}
|
||||
|
||||
protected open fun automaticallyRetrieveIfUserEnteredDecoupledTan(context: JobContext, tanChallenge: TanChallenge) {
|
||||
log.info("automaticallyRetrieveIfUserEnteredDecoupledTan() called for $tanChallenge")
|
||||
log.info { "automaticallyRetrieveIfUserEnteredDecoupledTan() called for $tanChallenge" }
|
||||
}
|
||||
|
||||
protected open suspend fun handleEnterTanResult(context: JobContext, enteredTanResult: EnterTanResult, tanResponse: TanResponse,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.dankito.banking.fints
|
||||
|
||||
import net.codinux.log.logger
|
||||
import net.dankito.banking.fints.messages.MessageBuilder
|
||||
import net.dankito.banking.fints.messages.MessageBuilderResult
|
||||
import net.dankito.banking.fints.model.*
|
||||
|
@ -11,7 +12,6 @@ import net.dankito.banking.fints.webclient.IWebClient
|
|||
import net.dankito.banking.fints.webclient.KtorWebClient
|
||||
import net.dankito.banking.fints.webclient.WebClientResponse
|
||||
import net.dankito.utils.multiplatform.extensions.getAllExceptionMessagesJoined
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
|
||||
|
||||
open class RequestExecutor(
|
||||
|
@ -20,15 +20,13 @@ open class RequestExecutor(
|
|||
protected open val base64Service: IBase64Service = PureKotlinBase64Service()
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(RequestExecutor::class)
|
||||
}
|
||||
private val log by logger()
|
||||
|
||||
|
||||
open suspend fun getAndHandleResponseForMessage(message: MessageBuilderResult, context: JobContext, tanRequiredCallback: suspend (TanResponse, BankResponse) -> BankResponse): BankResponse {
|
||||
if (message.createdMessage == null) {
|
||||
log.error("Could not create FinTS message to be sent to bank. isJobAllowed ${message.isJobAllowed}, isJobVersionSupported = ${message.isJobVersionSupported}," +
|
||||
"allowedVersions = ${message.allowedVersions}, supportedVersions = ${message.supportedVersions}.")
|
||||
log.error { "Could not create FinTS message to be sent to bank. isJobAllowed ${message.isJobAllowed}, isJobVersionSupported = ${message.isJobVersionSupported}," +
|
||||
"allowedVersions = ${message.allowedVersions}, supportedVersions = ${message.supportedVersions}." }
|
||||
return BankResponse(false, messageThatCouldNotBeCreated = message, internalError = "Could not create FinTS message to be sent to bank") // TODO: translate
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package net.dankito.banking.fints.log
|
||||
|
||||
import net.codinux.log.Logger
|
||||
import net.codinux.log.LoggerFactory
|
||||
import net.codinux.log.logger
|
||||
import net.dankito.banking.fints.model.BankData
|
||||
import net.dankito.banking.fints.model.MessageLogEntry
|
||||
import net.dankito.banking.fints.model.MessageLogEntryType
|
||||
import net.dankito.utils.multiplatform.log.Logger
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
import net.dankito.utils.multiplatform.extensions.getInnerException
|
||||
import net.dankito.utils.multiplatform.extensions.nthIndexOf
|
||||
import net.dankito.utils.multiplatform.extensions.toStringWithTwoDigits
|
||||
|
@ -21,7 +22,7 @@ open class MessageLogCollector {
|
|||
|
||||
private const val NewLine = "\r\n"
|
||||
|
||||
private val log = LoggerFactory.getLogger(MessageLogCollector::class)
|
||||
private val log by logger()
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate
|
||||
|
||||
import kotlinx.datetime.LocalDate
|
||||
import net.codinux.log.logger
|
||||
import net.dankito.banking.fints.messages.Existenzstatus
|
||||
import net.dankito.banking.fints.messages.datenelemente.basisformate.NumerischesDatenelement
|
||||
import net.dankito.utils.multiplatform.extensions.toStringWithMinDigits
|
||||
import net.dankito.utils.multiplatform.extensions.toStringWithTwoDigits
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,7 @@ open class Datum(date: Int?, existenzstatus: Existenzstatus) : NumerischesDatene
|
|||
const val HbciDateFormatString = "yyyyMMdd"
|
||||
|
||||
|
||||
private val log = LoggerFactory.getLogger(Datum::class)
|
||||
private val log by logger()
|
||||
|
||||
|
||||
fun format(date: LocalDate): String { // create HbciDateFormatString
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate
|
||||
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
import net.codinux.log.logger
|
||||
import net.dankito.utils.multiplatform.extensions.of
|
||||
import net.dankito.banking.fints.messages.Existenzstatus
|
||||
import net.dankito.banking.fints.messages.datenelemente.basisformate.ZiffernDatenelement
|
||||
import net.dankito.utils.multiplatform.extensions.toStringWithTwoDigits
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,7 @@ open class Uhrzeit(time: Int?, existenzstatus: Existenzstatus) : ZiffernDatenele
|
|||
const val HbciTimeFormatString = "HHmmss"
|
||||
|
||||
|
||||
private val log = LoggerFactory.getLogger(Uhrzeit::class)
|
||||
private val log by logger()
|
||||
|
||||
|
||||
fun format(time: LocalDateTime): String { // parse to HbciTimeFormatString
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.dankito.banking.fints.response
|
|||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
import kotlinx.datetime.atTime
|
||||
import net.codinux.log.logger
|
||||
import net.dankito.banking.fints.log.IMessageLogAppender
|
||||
import net.dankito.banking.fints.messages.Separators
|
||||
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Datum
|
||||
|
@ -24,7 +25,6 @@ import net.dankito.banking.fints.model.Money
|
|||
import net.dankito.banking.fints.response.segments.*
|
||||
import net.dankito.banking.fints.util.MessageUtils
|
||||
import net.dankito.utils.multiplatform.extensions.getAllExceptionMessagesJoined
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
|
||||
|
||||
open class ResponseParser(
|
||||
|
@ -40,11 +40,10 @@ open class ResponseParser(
|
|||
const val AufsetzpunktResponseCode = 3040
|
||||
|
||||
const val SupportedTanMethodsForUserResponseCode = 3920
|
||||
|
||||
|
||||
private val log = LoggerFactory.getLogger(ResponseParser::class)
|
||||
}
|
||||
|
||||
private val log by logger()
|
||||
|
||||
|
||||
open fun parse(response: String): BankResponse {
|
||||
try {
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
package net.dankito.banking.fints.tan
|
||||
|
||||
import net.codinux.log.logger
|
||||
import net.dankito.banking.fints.model.HHDVersion
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
|
||||
|
||||
open class FlickerCodeDecoder {
|
||||
|
||||
companion object {
|
||||
val ContainsOtherSymbolsThanFiguresPattern = Regex("\\D")
|
||||
|
||||
|
||||
private val log = LoggerFactory.getLogger(FlickerCodeDecoder::class)
|
||||
}
|
||||
|
||||
private val log by logger()
|
||||
|
||||
|
||||
open fun decodeChallenge(challengeHHD_UC: String, hhdVersion: HHDVersion): FlickerCode {
|
||||
try {
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
package net.dankito.banking.fints.tan
|
||||
|
||||
import io.ktor.utils.io.core.toByteArray
|
||||
import net.codinux.log.logger
|
||||
import net.dankito.banking.fints.messages.HbciCharset
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
|
||||
|
||||
open class TanImageDecoder {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(TanImageDecoder::class)
|
||||
}
|
||||
private val log by logger()
|
||||
|
||||
|
||||
open fun decodeChallenge(challengeHHD_UC: String): TanImage {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.dankito.banking.fints.transactions
|
||||
|
||||
import net.codinux.log.logger
|
||||
import net.dankito.banking.fints.log.IMessageLogAppender
|
||||
import net.dankito.banking.fints.model.*
|
||||
import net.dankito.banking.fints.transactions.mt940.IMt940Parser
|
||||
|
@ -8,8 +9,6 @@ import net.dankito.banking.fints.transactions.mt940.model.AccountStatement
|
|||
import net.dankito.banking.fints.transactions.mt940.model.Balance
|
||||
import net.dankito.banking.fints.transactions.mt940.model.Transaction
|
||||
import net.dankito.banking.fints.transactions.mt940.model.StatementLine
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
open class Mt940AccountTransactionsParser(
|
||||
|
@ -17,9 +16,7 @@ open class Mt940AccountTransactionsParser(
|
|||
override var logAppender: IMessageLogAppender? = null
|
||||
) : IAccountTransactionsParser {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(Mt940AccountTransactionsParser::class)
|
||||
}
|
||||
private val log by logger()
|
||||
|
||||
|
||||
override fun parseTransactions(transactionsString: String, bank: BankData, account: AccountData): List<AccountTransaction> {
|
||||
|
|
|
@ -2,13 +2,13 @@ package net.dankito.banking.fints.transactions.mt940
|
|||
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.Month
|
||||
import net.codinux.log.logger
|
||||
import net.dankito.utils.multiplatform.extensions.todayAtEuropeBerlin
|
||||
import net.dankito.banking.fints.log.IMessageLogAppender
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
import net.dankito.banking.fints.transactions.mt940.model.*
|
||||
import net.dankito.utils.multiplatform.DateFormatter
|
||||
import net.dankito.utils.multiplatform.extensions.isUpperCase
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
|
||||
|
||||
/*
|
||||
|
@ -75,11 +75,10 @@ open class Mt940Parser(
|
|||
const val SepaReferenceKey = "SVWZ+"
|
||||
const val DeviantOriginatorKey = "ABWA+"
|
||||
const val DeviantRecipientKey = "ABWE+"
|
||||
|
||||
|
||||
private val log = LoggerFactory.getLogger(Mt940Parser::class)
|
||||
}
|
||||
|
||||
private val log by logger()
|
||||
|
||||
|
||||
/**
|
||||
* Parses a whole MT 940 statements string, that is one that ends with a "-" line.
|
||||
|
|
|
@ -6,17 +6,13 @@ import io.ktor.client.request.setBody
|
|||
import io.ktor.client.statement.bodyAsText
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.contentType
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.cancel
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
import net.codinux.log.logger
|
||||
|
||||
|
||||
open class KtorWebClient : IWebClient {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(KtorWebClient::class)
|
||||
}
|
||||
private val log by logger()
|
||||
|
||||
|
||||
protected val client = HttpClient {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package net.dankito.banking.fints.extensions
|
||||
|
||||
import net.dankito.utils.multiplatform.extensions.platformSpecificQualifiedName
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.test.assertEquals
|
||||
|
@ -66,7 +65,7 @@ fun <T : Any?> assertContains(collection: Collection<T>, vararg items: T) {
|
|||
inline fun <reified T : Throwable> assertThrows(action: () -> Unit) {
|
||||
try {
|
||||
action()
|
||||
fail("action() didn't throw any exception. Expected was ${T::class.platformSpecificQualifiedName}")
|
||||
fail("action() didn't throw any exception. Expected was ${T::class.simpleName}")
|
||||
} catch (throwable: Throwable) {
|
||||
assertTrue(throwable is T)
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package net.dankito.utils.multiplatform
|
||||
|
||||
|
||||
expect class Thread() {
|
||||
|
||||
companion object {
|
||||
|
||||
val current: Thread
|
||||
|
||||
fun printCurrentThreadStackTrace()
|
||||
|
||||
}
|
||||
|
||||
|
||||
val threadName: String
|
||||
|
||||
fun printStackTrace()
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.extensions
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
/**
|
||||
* On some platforms like JavaScript [KClass.qualifiedName] is not supported.
|
||||
* On these [KClass.simpleName] is returned, on all others [KClass.qualifiedName].
|
||||
*/
|
||||
expect val KClass<*>.platformSpecificQualifiedName: String
|
|
@ -1,10 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
|
||||
open class ConsoleLogger(name: String) : LoggerBase(name) {
|
||||
|
||||
override fun log(level: LogLevel, message: String) {
|
||||
println(createLogOutput(level, message))
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
|
||||
expect class DefaultLoggerFactory() {
|
||||
|
||||
fun createDefaultLoggerFactory(): ILoggerFactory
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
|
||||
interface ILoggerFactory {
|
||||
|
||||
fun getLogger(name: String): Logger
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
|
||||
enum class LogLevel(val priority: Int) {
|
||||
|
||||
None(0),
|
||||
|
||||
Fatal(1),
|
||||
|
||||
Error(2),
|
||||
|
||||
Warn(3),
|
||||
|
||||
Info(4),
|
||||
|
||||
Debug(5),
|
||||
|
||||
Trace(6)
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
|
||||
open class LogToConsoleLoggerFactory : ILoggerFactory {
|
||||
|
||||
override fun getLogger(name: String): Logger {
|
||||
return ConsoleLogger(name)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
|
||||
interface Logger {
|
||||
|
||||
val name: String
|
||||
|
||||
|
||||
val isFatalEnabled: Boolean
|
||||
|
||||
val isErrorEnabled: Boolean
|
||||
|
||||
val isWarnEnabled: Boolean
|
||||
|
||||
val isInfoEnabled: Boolean
|
||||
|
||||
val isDebugEnabled: Boolean
|
||||
|
||||
val isTraceEnabled: Boolean
|
||||
|
||||
|
||||
fun fatal(message: String, exception: Throwable? = null, vararg arguments: Any)
|
||||
|
||||
fun fatal(exception: Throwable? = null, vararg arguments: Any, message: () -> String)
|
||||
|
||||
|
||||
fun error(message: String, exception: Throwable? = null, vararg arguments: Any)
|
||||
|
||||
fun error(exception: Throwable? = null, vararg arguments: Any, message: () -> String)
|
||||
|
||||
|
||||
fun warn(message: String, exception: Throwable? = null, vararg arguments: Any)
|
||||
|
||||
fun warn(exception: Throwable? = null, vararg arguments: Any, message: () -> String)
|
||||
|
||||
fun info(message: String, exception: Throwable? = null, vararg arguments: Any)
|
||||
|
||||
fun info(exception: Throwable? = null, vararg arguments: Any, message: () -> String)
|
||||
|
||||
|
||||
fun debug(message: String, exception: Throwable? = null, vararg arguments: Any)
|
||||
|
||||
fun debug(exception: Throwable? = null, vararg arguments: Any, message: () -> String)
|
||||
|
||||
|
||||
fun trace(message: String, exception: Throwable? = null, vararg arguments: Any)
|
||||
|
||||
fun trace(exception: Throwable? = null, vararg arguments: Any, message: () -> String)
|
||||
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
import net.dankito.utils.multiplatform.DateFormatter
|
||||
import net.dankito.utils.multiplatform.Thread
|
||||
import net.dankito.utils.multiplatform.extensions.nowAtSystemDefaultTimeZone
|
||||
|
||||
|
||||
abstract class LoggerBase(
|
||||
override val name: String,
|
||||
open var level: LogLevel = LogLevel.Info
|
||||
) : Logger {
|
||||
|
||||
companion object {
|
||||
private val DateFormatter = DateFormatter("HH:mm:ss.SSS")
|
||||
}
|
||||
|
||||
|
||||
abstract fun log(level: LogLevel, message: String)
|
||||
|
||||
|
||||
override val isFatalEnabled get() = isEnabled(LogLevel.Fatal)
|
||||
|
||||
override val isErrorEnabled get() = isEnabled(LogLevel.Error)
|
||||
|
||||
override val isWarnEnabled get() = isEnabled(LogLevel.Warn)
|
||||
|
||||
override val isInfoEnabled get() = isEnabled(LogLevel.Info)
|
||||
|
||||
override val isDebugEnabled get() = isEnabled(LogLevel.Debug)
|
||||
|
||||
override val isTraceEnabled get() = isEnabled(LogLevel.Trace)
|
||||
|
||||
open fun isEnabled(level: LogLevel) = level.priority <= this.level.priority
|
||||
|
||||
|
||||
override fun fatal(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
logIfEnabled(LogLevel.Fatal, exception, { message }, *arguments)
|
||||
}
|
||||
|
||||
override fun fatal(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
logIfEnabled(LogLevel.Fatal, exception, message, *arguments)
|
||||
}
|
||||
|
||||
|
||||
override fun error(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
logIfEnabled(LogLevel.Error, exception, { message }, *arguments)
|
||||
}
|
||||
|
||||
override fun error(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
logIfEnabled(LogLevel.Error, exception, message, *arguments)
|
||||
}
|
||||
|
||||
|
||||
override fun warn(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
logIfEnabled(LogLevel.Warn, exception, { message }, *arguments)
|
||||
}
|
||||
|
||||
override fun warn(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
logIfEnabled(LogLevel.Warn, exception, message, *arguments)
|
||||
}
|
||||
|
||||
|
||||
override fun info(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
logIfEnabled(LogLevel.Info, exception, { message }, *arguments)
|
||||
}
|
||||
|
||||
override fun info(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
logIfEnabled(LogLevel.Info, exception, message, *arguments)
|
||||
}
|
||||
|
||||
|
||||
override fun debug(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
logIfEnabled(LogLevel.Debug, exception, { message }, *arguments)
|
||||
}
|
||||
|
||||
override fun debug(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
logIfEnabled(LogLevel.Debug, exception, message, *arguments)
|
||||
}
|
||||
|
||||
|
||||
override fun trace(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
logIfEnabled(LogLevel.Trace, exception, { message }, *arguments)
|
||||
}
|
||||
|
||||
override fun trace(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
logIfEnabled(LogLevel.Trace, exception, message, *arguments)
|
||||
}
|
||||
|
||||
|
||||
open fun logIfEnabled(level: LogLevel, exception: Throwable? = null, message: () -> String, vararg arguments: Any) {
|
||||
if (isEnabled(level)) {
|
||||
log(level, createMessage(exception, message(), *arguments))
|
||||
}
|
||||
}
|
||||
|
||||
open fun createMessage(exception: Throwable?, message: String, vararg arguments: Any): String {
|
||||
if (exception != null) {
|
||||
return "$message: $exception\n${exception.stackTraceToString()}"
|
||||
}
|
||||
|
||||
return message // really, there's not String.format() ?! // TODO: add arguments and exception
|
||||
}
|
||||
|
||||
|
||||
protected open fun createLogOutput(level: LogLevel, message: String): String {
|
||||
return "${DateFormatter.format(LocalDateTime.nowAtSystemDefaultTimeZone())} [$level] ${Thread.current.threadName} $name - $message"
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
class LoggerFactory {
|
||||
|
||||
companion object {
|
||||
|
||||
var loggerFactory: ILoggerFactory = createDefaultLoggerFactory()
|
||||
|
||||
private fun createDefaultLoggerFactory(): ILoggerFactory {
|
||||
return DefaultLoggerFactory().createDefaultLoggerFactory()
|
||||
}
|
||||
|
||||
|
||||
fun getLogger(name: String): Logger {
|
||||
return loggerFactory.getLogger(name)
|
||||
}
|
||||
|
||||
fun getLogger(kClass: KClass<*>): Logger {
|
||||
return getLogger(kClass.simpleName ?: kClass.toString()) // TODO: use qualifiedName on JVM
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.os
|
||||
|
||||
|
||||
expect class OsHelper actual constructor() {
|
||||
|
||||
val osType: OsType
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.os
|
||||
|
||||
|
||||
enum class OsType {
|
||||
|
||||
JVM,
|
||||
|
||||
Android,
|
||||
|
||||
iOS,
|
||||
|
||||
JavaScript, // TODO: differenciate between Browser and NodeJS
|
||||
|
||||
Native // TODO: get if running on Linux, Windows or macOs
|
||||
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package net.dankito.utils.multiplatform
|
||||
|
||||
import platform.Foundation.NSOperationQueue
|
||||
import platform.Foundation.NSThread
|
||||
|
||||
|
||||
actual class Thread(private val thread: NSThread) {
|
||||
|
||||
actual companion object {
|
||||
|
||||
actual val current: Thread
|
||||
get() = Thread(NSThread.currentThread)
|
||||
|
||||
|
||||
actual fun printCurrentThreadStackTrace() {
|
||||
Thread.current.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
actual constructor() : this(NSThread())
|
||||
|
||||
|
||||
actual val threadName: String
|
||||
get() {
|
||||
thread.name?.let { name ->
|
||||
if (name.isNotBlank()) {
|
||||
return name
|
||||
}
|
||||
}
|
||||
|
||||
return thread.description
|
||||
?: NSOperationQueue.currentQueue?.underlyingQueue?.description
|
||||
?: "Could not retrieve thread's name"
|
||||
}
|
||||
|
||||
|
||||
actual fun printStackTrace() {
|
||||
println("Stack trace of $threadName")
|
||||
|
||||
NSThread.callStackSymbols.forEach { callStackSymbol ->
|
||||
println(callStackSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.extensions
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* On some platforms like JavaScript [KClass.qualifiedName] is not supported.
|
||||
* On these [KClass.simpleName] is returned, on all others [KClass.qualifiedName].
|
||||
*/
|
||||
actual val KClass<*>.platformSpecificQualifiedName: String
|
||||
get() = this.qualifiedName ?: this.simpleName ?: "ClassNameNotFound" // should actually never occur
|
|
@ -1,12 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
|
||||
actual class DefaultLoggerFactory {
|
||||
|
||||
actual fun createDefaultLoggerFactory(): ILoggerFactory {
|
||||
// i cannot recommend using NSLog from Kotlin, has many bugs (e.g. cutting messages, printing non Ansi characters in Ansi messages, ...)
|
||||
// return NSLogLoggerFactory()
|
||||
return LogToConsoleLoggerFactory()
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
import platform.Foundation.NSLog
|
||||
|
||||
|
||||
open class NSLogLogger(name: String) : LoggerBase(name) {
|
||||
|
||||
override fun log(level: LogLevel, message: String) {
|
||||
NSLog(createLogOutput(level, message))
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
|
||||
open class NSLogLoggerFactory : ILoggerFactory {
|
||||
|
||||
override fun getLogger(name: String): Logger {
|
||||
return NSLogLogger(name)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.os
|
||||
|
||||
|
||||
actual class OsHelper {
|
||||
|
||||
|
||||
actual val osType = OsType.iOS
|
||||
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package net.dankito.utils.multiplatform
|
||||
|
||||
actual class Thread actual constructor() {
|
||||
|
||||
actual companion object {
|
||||
|
||||
actual val current: Thread
|
||||
get() = Thread()
|
||||
|
||||
actual fun printCurrentThreadStackTrace() {
|
||||
Thread.current.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
actual val threadName = "main"
|
||||
|
||||
actual fun printStackTrace() {
|
||||
// TODO: find a better way
|
||||
Exception("Nothing happened, just to print the stack trace").printStackTrace()
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.extensions
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* On some platforms like JavaScript [KClass.qualifiedName] is not supported.
|
||||
* On these [KClass.simpleName] is returned, on all others [KClass.qualifiedName].
|
||||
*/
|
||||
actual val KClass<*>.platformSpecificQualifiedName: String
|
||||
get() = this.simpleName // on JavaScript qualifiedName is not supported
|
||||
?: "ClassNameNotFound" // should actually never occur
|
|
@ -1,9 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
actual class DefaultLoggerFactory actual constructor() {
|
||||
|
||||
actual fun createDefaultLoggerFactory(): ILoggerFactory {
|
||||
return LogToConsoleLoggerFactory()
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.os
|
||||
|
||||
actual class OsHelper actual constructor() {
|
||||
|
||||
actual val osType = OsType.JavaScript
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package net.dankito.utils.multiplatform
|
||||
|
||||
|
||||
actual class Thread(private val thread: java.lang.Thread) : java.lang.Thread() {
|
||||
|
||||
actual companion object {
|
||||
|
||||
actual val current: Thread
|
||||
get() = Thread(currentThread())
|
||||
|
||||
|
||||
actual fun printCurrentThreadStackTrace() {
|
||||
Thread.current.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
actual constructor() : this(java.lang.Thread())
|
||||
|
||||
|
||||
actual val threadName: String
|
||||
get() = thread.name
|
||||
|
||||
|
||||
actual fun printStackTrace() {
|
||||
println("Stack trace of $threadName")
|
||||
|
||||
thread.stackTrace.forEachIndexed { index, stackTraceElement ->
|
||||
println("[$index] $stackTraceElement")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.extensions
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* On some platforms like JavaScript [KClass.qualifiedName] is not supported.
|
||||
* On these [KClass.simpleName] is returned, on all others [KClass.qualifiedName].
|
||||
*/
|
||||
actual val KClass<*>.platformSpecificQualifiedName: String
|
||||
get() = this.qualifiedName ?: this.simpleName ?: "ClassNameNotFound" // should actually never occur
|
|
@ -1,24 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
|
||||
actual class DefaultLoggerFactory {
|
||||
|
||||
actual fun createDefaultLoggerFactory(): ILoggerFactory {
|
||||
if (isClassAvailable("org.slf4j.Logger")) {
|
||||
return Slf4jLoggerFactory()
|
||||
}
|
||||
|
||||
return LogToConsoleLoggerFactory()
|
||||
}
|
||||
|
||||
private fun isClassAvailable(qualifiedClassName: String): Boolean {
|
||||
try {
|
||||
Class.forName(qualifiedClassName)
|
||||
|
||||
return true
|
||||
} catch (ignored: Exception) { }
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
import net.dankito.utils.multiplatform.os.OsHelper
|
||||
|
||||
|
||||
open class Slf4jLogger(protected val slf4jLogger: org.slf4j.Logger, protected val osHelper: OsHelper = OsHelper()) : Logger {
|
||||
|
||||
companion object {
|
||||
|
||||
const val MaxLogCatMessageLength = 4 * 1024
|
||||
|
||||
}
|
||||
|
||||
|
||||
override val name: String
|
||||
get() = slf4jLogger.name
|
||||
|
||||
|
||||
override val isFatalEnabled: Boolean
|
||||
get() = isErrorEnabled
|
||||
|
||||
override val isErrorEnabled: Boolean
|
||||
get() = slf4jLogger.isErrorEnabled
|
||||
|
||||
override val isWarnEnabled: Boolean
|
||||
get() = slf4jLogger.isWarnEnabled
|
||||
|
||||
override val isInfoEnabled: Boolean
|
||||
get() = slf4jLogger.isInfoEnabled
|
||||
|
||||
override val isDebugEnabled: Boolean
|
||||
get() = slf4jLogger.isDebugEnabled
|
||||
|
||||
override val isTraceEnabled: Boolean
|
||||
get() = slf4jLogger.isTraceEnabled
|
||||
|
||||
|
||||
override fun fatal(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
error(message, exception, arguments)
|
||||
}
|
||||
|
||||
override fun fatal(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
error(exception, *arguments, message = message)
|
||||
}
|
||||
|
||||
|
||||
override fun error(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
log(exception, arguments, { message }, { msg, args -> slf4jLogger.error(msg, *args) } )
|
||||
}
|
||||
|
||||
override fun error(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
log(exception, arguments, message, { msg, args -> slf4jLogger.error(msg, *args) } )
|
||||
}
|
||||
|
||||
|
||||
override fun warn(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
log(exception, arguments, { message }, { msg, args -> slf4jLogger.warn(msg, *args) } )
|
||||
}
|
||||
|
||||
override fun warn(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
log(exception, arguments, message, { msg, args -> slf4jLogger.warn(msg, *args) } )
|
||||
}
|
||||
|
||||
|
||||
override fun info(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
log(exception, arguments, { message }, { msg, args -> slf4jLogger.info(msg, *args) } )
|
||||
}
|
||||
|
||||
override fun info(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
log(exception, arguments, message, { msg, args -> slf4jLogger.info(msg, *args) } )
|
||||
}
|
||||
|
||||
|
||||
override fun debug(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
log(exception, arguments, { message }, { msg, args -> slf4jLogger.debug(msg, *args) } )
|
||||
}
|
||||
|
||||
override fun debug(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
log(exception, arguments, message, { msg, args -> slf4jLogger.debug(msg, *args) } )
|
||||
}
|
||||
|
||||
|
||||
override fun trace(message: String, exception: Throwable?, vararg arguments: Any) {
|
||||
log(exception, arguments, { message }, { msg, args -> slf4jLogger.trace(msg, *args) } )
|
||||
}
|
||||
|
||||
override fun trace(exception: Throwable?, vararg arguments: Any, message: () -> String) {
|
||||
log(exception, arguments, message, { msg, args -> slf4jLogger.trace(msg, *args) } )
|
||||
}
|
||||
|
||||
|
||||
protected open fun log(exception: Throwable?, arguments: Array<out Any>, messageCreator: () -> String,
|
||||
logOnLevel: (String, Array<out Any>) -> Unit) {
|
||||
|
||||
val message = messageCreator()
|
||||
|
||||
val args = determineArguments(exception, arguments)
|
||||
|
||||
if (osHelper.isRunningOnAndroid && message.length > MaxLogCatMessageLength) {
|
||||
var index = 0
|
||||
// as LogCat only prints at maximum 4076 bytes per message, break up message in multiple strings
|
||||
message.chunked(MaxLogCatMessageLength - 5).forEach { chunk -> // -5 to also log index
|
||||
logOnLevel("[${index++}] $chunk", args)
|
||||
}
|
||||
}
|
||||
else {
|
||||
logOnLevel(message, args)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun determineArguments(exception: Throwable?, arguments: Array<out Any>): Array<out Any> {
|
||||
return if (exception != null) {
|
||||
if (arguments.isEmpty()) {
|
||||
arrayOf(exception)
|
||||
} else {
|
||||
val argumentsIncludingException: MutableList<Any> = mutableListOf(exception)
|
||||
argumentsIncludingException.addAll(0, arguments.toList())
|
||||
|
||||
argumentsIncludingException.toTypedArray()
|
||||
}
|
||||
} else {
|
||||
arguments
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
|
||||
open class Slf4jLoggerFactory : ILoggerFactory {
|
||||
|
||||
override fun getLogger(name: String): Logger {
|
||||
return Slf4jLogger(LoggerFactory.getLogger(name))
|
||||
}
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.os
|
||||
|
||||
|
||||
actual open class OsHelper {
|
||||
|
||||
|
||||
actual val osType: OsType
|
||||
get() {
|
||||
return if (isRunningOnAndroid) {
|
||||
OsType.Android
|
||||
}
|
||||
else {
|
||||
OsType.JVM
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open val isRunningOnAndroid: Boolean = determineIsRunningOnAndroid()
|
||||
|
||||
|
||||
protected open fun determineIsRunningOnAndroid(): Boolean {
|
||||
try {
|
||||
Class.forName("android.app.Activity")
|
||||
return true
|
||||
} catch (ex: Exception) { }
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package net.dankito.utils.multiplatform
|
||||
|
||||
|
||||
actual class Thread {
|
||||
|
||||
actual companion object {
|
||||
|
||||
actual val current: Thread
|
||||
get() = Thread()
|
||||
|
||||
|
||||
actual fun printCurrentThreadStackTrace() {
|
||||
Thread.current.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
actual val threadName: String
|
||||
get() = "main"
|
||||
|
||||
|
||||
actual fun printStackTrace() {
|
||||
// TODO: find a better way
|
||||
Exception("Nothing happened, just to print the stack trace").printStackTrace()
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.extensions
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* On some platforms like JavaScript [KClass.qualifiedName] is not supported.
|
||||
* On these [KClass.simpleName] is returned, on all others [KClass.qualifiedName].
|
||||
*/
|
||||
actual val KClass<*>.platformSpecificQualifiedName: String
|
||||
get() = this.qualifiedName ?: this.simpleName ?: "ClassNameNotFound" // should actually never occur
|
|
@ -1,9 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.log
|
||||
|
||||
actual class DefaultLoggerFactory actual constructor() {
|
||||
|
||||
actual fun createDefaultLoggerFactory(): ILoggerFactory {
|
||||
return LogToConsoleLoggerFactory()
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package net.dankito.utils.multiplatform.os
|
||||
|
||||
actual class OsHelper actual constructor() {
|
||||
|
||||
actual val osType = OsType.Native
|
||||
|
||||
}
|
Loading…
Reference in New Issue