Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom logging #79

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
}
}
Loading