Skip to content

Commit

Permalink
expose Logger interface through EudiWalletConfig so implementor can p…
Browse files Browse the repository at this point in the history
…ass custom Logger implementations; changed the Logger interface; If no custom logger implementation is set, then library will use the default
  • Loading branch information
vkanellopoulos committed Jul 23, 2024
1 parent c661b02 commit 49e354b
Show file tree
Hide file tree
Showing 12 changed files with 116 additions and 25 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ the following options:
default value is null.
- `openId4VciConfig` method allows you to specify the configuration for OpenID4VCI. The default
value is null.
- `logger` method allows you to specify the logger. If the logger is not provided, the default
logger will be used.
- `logLevel` method allows you to specify the log level for the default logger. The default value
is `Logger.LEVEL_ERROR`.

The following example shows how to initialize the library:

Expand All @@ -153,11 +157,16 @@ import eu.europa.ec.eudi.wallet.EudiWallet
import eu.europa.ec.eudi.wallet.EudiWalletConfig
import eu.europa.ec.eudi.wallet.Logger
import java.security.cert.X509Certificate

val logger = Logger { record: Logger.Record ->
// log the record
}
val storageDir = applicationContext.noBackupFilesDir
val verifierApiUri = "https://verifier-api-uri"
val config = EudiWalletConfig.Builder(applicationContext)
// set the log level for the default logger
.logLevel(Logger.LEVEL_DEBUG)
// or set a custom logger
.logger(logger)
.ktorHttpClientFactory {
// Provide your own Ktor HttpClient.
// This will be used for OpenId4VCI and OpenId4VP communication.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import eu.europa.ec.eudi.wallet.document.sample.SampleDocumentManager
import eu.europa.ec.eudi.wallet.internal.getCertificate
import eu.europa.ec.eudi.wallet.internal.mainExecutor
import eu.europa.ec.eudi.wallet.issue.openid4vci.*
import eu.europa.ec.eudi.wallet.logging.Logger
import eu.europa.ec.eudi.wallet.transfer.openid4vp.OpenId4VpCBORResponse
import eu.europa.ec.eudi.wallet.transfer.openid4vp.OpenId4VpCBORResponseGeneratorImpl
import eu.europa.ec.eudi.wallet.transfer.openid4vp.OpenId4vpManager
Expand Down Expand Up @@ -77,9 +76,7 @@ object EudiWallet {
private var transferMode: TransferMode? = null

private val logger by lazy {
requireInit {
Logger(_config)
}
requireInit { _config.logger }
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ class EudiWalletConfig private constructor(builder: Builder) {
*/
val logLevel: Int = builder.logLevel

/**
* The logger. If no [Logger] instance is provided and [logLevel] is not [Logger.OFF], then the default will be used
*/
val logger: Logger? = builder.logger ?: Logger(this).takeUnless { builder.logLevel == Logger.OFF }

/**
* Ktor http client factory
*/
Expand Down Expand Up @@ -202,6 +207,7 @@ class EudiWalletConfig private constructor(builder: Builder) {
var verifyMsoPublicKey: Boolean = true
var openId4VpConfig: OpenId4VpConfig? = null
var openId4VciConfig: OpenId4VciConfig? = null
var logger: Logger? = null
var logLevel: Int = Logger.LEVEL_ERROR
var ktorHttpClientFactory: (() -> HttpClient)? = null

Expand Down Expand Up @@ -366,6 +372,15 @@ class EudiWalletConfig private constructor(builder: Builder) {
this.openId4VciConfig = OpenId4VciConfig.Builder().apply(block).build()
}

/**
* Set a logger
* @param logger The logger
* @return [EudiWalletConfig.Builder]
*/
fun logger(logger: Logger) = apply {
this.logger = logger
}

/**
* Set the debug logging level.
* The default value is [LogLevel.OFF].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import eu.europa.ec.eudi.openid4vci.AuthorizedRequest
import eu.europa.ec.eudi.openid4vci.Issuer
import eu.europa.ec.eudi.wallet.issue.openid4vci.OpenId4VciManager.Companion.TAG
import eu.europa.ec.eudi.wallet.logging.Logger
import eu.europa.ec.eudi.wallet.logging.d
import eu.europa.ec.eudi.wallet.logging.e
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.cancellation.CancellationException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import eu.europa.ec.eudi.wallet.document.DocumentManager
import eu.europa.ec.eudi.wallet.document.StoreDocumentResult
import eu.europa.ec.eudi.wallet.issue.openid4vci.OpenId4VciManager.Companion.TAG
import eu.europa.ec.eudi.wallet.logging.Logger
import eu.europa.ec.eudi.wallet.logging.d
import org.bouncycastle.util.encoders.Hex
import java.util.*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import eu.europa.ec.eudi.wallet.document.UnsignedDocument
import eu.europa.ec.eudi.wallet.issue.openid4vci.IssueEvent.Companion.documentFailed
import eu.europa.ec.eudi.wallet.issue.openid4vci.OpenId4VciManager.Companion.TAG
import eu.europa.ec.eudi.wallet.logging.Logger
import eu.europa.ec.eudi.wallet.logging.d
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.suspendCancellableCoroutine
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import eu.europa.ec.eudi.wallet.document.DocumentManager
import eu.europa.ec.eudi.wallet.document.UnsignedDocument
import eu.europa.ec.eudi.wallet.issue.openid4vci.OpenId4VciManager.Companion.TAG
import eu.europa.ec.eudi.wallet.logging.Logger
import eu.europa.ec.eudi.wallet.logging.d
import eu.europa.ec.eudi.wallet.logging.e
import org.bouncycastle.util.io.pem.PemObject
import org.bouncycastle.util.io.pem.PemWriter
import java.io.StringWriter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,21 @@ import eu.europa.ec.eudi.wallet.EudiWalletConfig
import eu.europa.ec.eudi.wallet.logging.Logger.Companion.LEVEL_DEBUG
import eu.europa.ec.eudi.wallet.logging.Logger.Companion.LEVEL_ERROR
import eu.europa.ec.eudi.wallet.logging.Logger.Companion.LEVEL_INFO
import java.time.Instant


interface Logger {
fun interface Logger {

@Level
val level: Int
fun log(level: Int, tag: String, message: String, throwable: Throwable? = null)
data class Record(
@Level val level: Int,
val instant: Instant = Instant.now(),
val message: String,
val thrown: Throwable? = null,
val sourceClassName: String? = null,
val sourceMethod: String? = null,
)

fun d(tag: String, message: String) = log(LEVEL_DEBUG, tag, message)
fun i(tag: String, message: String) = log(LEVEL_INFO, tag, message)
fun e(tag: String, message: String, throwable: Throwable? = null) = log(LEVEL_ERROR, tag, message, throwable)
fun log(record: Record)

companion object {
const val OFF = 0
Expand All @@ -51,19 +55,16 @@ interface Logger {
}

class LoggerImpl(val config: EudiWalletConfig, private val maxLogSize: Int = 1000) : Logger {
override val level: Int = config.logLevel
override fun log(level: Int, tag: String, message: String, throwable: Throwable?) {
splitMessage(message).forEachIndexed { i, m ->
override fun log(record: Logger.Record) {
val tag = record.sourceClassName ?: ""
splitMessage(record.message).forEachIndexed { i, m ->
when {
level == LEVEL_ERROR && config.logLevel >= LEVEL_ERROR && i == 0 && throwable != null -> Log.e(
tag,
m,
throwable
)
record.level == LEVEL_ERROR && config.logLevel >= LEVEL_ERROR && i == 0 && record.thrown != null ->
Log.e(tag, m, record.thrown)

level == LEVEL_ERROR && config.logLevel >= LEVEL_ERROR -> Log.e(tag, m)
level == LEVEL_INFO && config.logLevel >= LEVEL_INFO -> Log.i(tag, m)
level == LEVEL_DEBUG && config.logLevel >= LEVEL_DEBUG -> Log.d(tag, m)
record.level == LEVEL_ERROR && config.logLevel >= LEVEL_ERROR -> Log.e(tag, m)
record.level == LEVEL_INFO && config.logLevel >= LEVEL_INFO -> Log.i(tag, m)
record.level == LEVEL_DEBUG && config.logLevel >= LEVEL_DEBUG -> Log.d(tag, m)
}
}
}
Expand All @@ -76,7 +77,34 @@ class LoggerImpl(val config: EudiWalletConfig, private val maxLogSize: Int = 100
}
return messages
}
}

@JvmSynthetic
internal fun Logger.d(tag: String, message: String) = log(
Logger.Record(
level = LEVEL_DEBUG,
sourceClassName = tag,
message = message
)
)

}
@JvmSynthetic
internal fun Logger.i(tag: String, message: String) = log(
Logger.Record(
level = LEVEL_INFO,
sourceClassName = tag,
message = message
)
)

@JvmSynthetic
internal fun Logger.e(tag: String, message: String, throwable: Throwable? = null) =
log(
Logger.Record(
level = LEVEL_ERROR,
sourceClassName = tag,
message = message,
thrown = throwable
)
)

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 European Commission
* Copyright (c) 2023-2024 European Commission
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,6 +38,8 @@ import eu.europa.ec.eudi.iso18013.transfer.response.SessionTranscriptBytes
import eu.europa.ec.eudi.openid4vp.legalName
import eu.europa.ec.eudi.wallet.internal.Openid4VpX509CertificateTrust
import eu.europa.ec.eudi.wallet.logging.Logger
import eu.europa.ec.eudi.wallet.logging.e
import eu.europa.ec.eudi.wallet.logging.i

private const val TAG = "OpenId4VpCBORResponseGe"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import eu.europa.ec.eudi.prex.PresentationSubmission
import eu.europa.ec.eudi.wallet.internal.Openid4VpUtils
import eu.europa.ec.eudi.wallet.internal.mainExecutor
import eu.europa.ec.eudi.wallet.logging.Logger
import eu.europa.ec.eudi.wallet.logging.d
import eu.europa.ec.eudi.wallet.logging.e
import eu.europa.ec.eudi.wallet.logging.i
import eu.europa.ec.eudi.wallet.util.CBOR
import eu.europa.ec.eudi.wallet.util.wrappedWithContentNegotiation
import eu.europa.ec.eudi.wallet.util.wrappedWithLogging
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package eu.europa.ec.eudi.wallet.util

import eu.europa.ec.eudi.wallet.issue.openid4vci.OpenId4VciManager.Companion.TAG
import eu.europa.ec.eudi.wallet.logging.Logger
import eu.europa.ec.eudi.wallet.logging.d
import io.ktor.client.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.plugins.logging.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package eu.europa.ec.eudi.wallet

import android.content.Context
import eu.europa.ec.eudi.wallet.logging.Logger
import eu.europa.ec.eudi.wallet.logging.LoggerImpl
import eu.europa.ec.eudi.wallet.transfer.openid4vp.ClientIdScheme
import eu.europa.ec.eudi.wallet.transfer.openid4vp.EncryptionAlgorithm
import eu.europa.ec.eudi.wallet.transfer.openid4vp.EncryptionMethod
Expand Down Expand Up @@ -124,4 +126,32 @@ class EudiWalletConfigTest {
assertNull(config.openId4VPConfig)
assertNull(config.openId4VciConfig)
}

@Test
fun testLoggerIsNullWhenLogLevelIsOff() {
val config = EudiWalletConfig(context) {
logLevel = Logger.OFF
}

assertNull(config.logger)
}

@Test
fun testLoggerIsDefaultImplementationWhenLogLevelIsNotOff() {
val config = EudiWalletConfig(context) {
logLevel = Logger.LEVEL_ERROR
}

assertTrue(config.logger is LoggerImpl)
}

@Test
fun testCustomLogger() {
val logger = Logger { record -> println(record) }
val config = EudiWalletConfig(context) {
this.logger = logger
}

assertTrue(config.logger == logger)
}
}

0 comments on commit 49e354b

Please sign in to comment.