feat: [NETWORK] should log (#416)

Co-authored-by: Florent Champigny <florent@bere.al>
This commit is contained in:
Florent CHAMPIGNY 2025-12-01 14:26:28 +01:00 committed by GitHub
parent fb6e57edcb
commit 829e951019
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 46 additions and 9 deletions

View file

@ -3,6 +3,7 @@ package io.github.openflocon.flocon.ktor
import io.ktor.client.HttpClientConfig
import io.ktor.client.plugins.api.createClientPlugin
import io.ktor.client.request.HttpRequest
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.statement.HttpResponse
data class FloconNetworkIsImageParams(
@ -13,6 +14,7 @@ data class FloconNetworkIsImageParams(
class FloconKtorPluginConfig {
var isImage: ((param: FloconNetworkIsImageParams) -> Boolean)? = null
var shouldLog: ((request: HttpRequestBuilder) -> Boolean) = { true }
}
val FloconKtorPlugin = createClientPlugin("FloconKtorPlugin", ::FloconKtorPluginConfig) {

View file

@ -22,6 +22,7 @@ import io.ktor.utils.io.toByteArray
import io.github.openflocon.flocon.utils.currentTimeMillis
import io.github.openflocon.flocon.utils.currentTimeNanos
import io.ktor.client.call.save
import io.ktor.client.request.HttpRequestBuilder
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
@ -34,22 +35,26 @@ data class FloconNetworkIsImageParams(
class FloconKtorPluginConfig {
var isImage: ((param: FloconNetworkIsImageParams) -> Boolean)? = null
var shouldLog: ((request: HttpRequestBuilder) -> Boolean) = { true }
}
val FloconKtorPlugin = createClientPlugin("FloconKtorPlugin", ::FloconKtorPluginConfig) {
val theClient = client
val isImageCallback = pluginConfig.isImage
val shouldLogCallback = pluginConfig.shouldLog
// Intercept requests
client.sendPipeline.intercept(HttpSendPipeline.Monitoring) {
val floconNetworkPlugin = FloconApp.instance?.client?.networkPlugin
if (floconNetworkPlugin == null) {
val request: HttpRequestBuilder = context
if (floconNetworkPlugin == null || shouldLogCallback(request)) {
request.attributes.put(FLOCON_SHOULD_LOG, false)
proceed()
return@intercept
}
val request = context
val floconCallId = Uuid.random().toString()
val floconNetworkType = "http"
val requestedAt = currentTimeMillis()
@ -142,6 +147,12 @@ val FloconKtorPlugin = createClientPlugin("FloconKtorPlugin", ::FloconKtorPlugin
val call = response.call
val request: HttpRequest = call.request
val floconShouldLog = request.attributes.getOrNull(FLOCON_SHOULD_LOG) ?: true
if(!floconShouldLog) {
proceed()
return@intercept
}
val floconCallId = request.attributes.getOrNull(FLOCON_CALL_ID_KEY) ?: return@intercept
val startTime = request.attributes.getOrNull(FLOCON_START_TIME_KEY) ?: return@intercept
val isMocked = request.attributes.getOrNull(FLOCON_IS_MOCKED_KEY) ?: false
@ -199,4 +210,5 @@ fun HttpClientConfig<*>.floconInterceptor() {
private val FLOCON_CALL_ID_KEY = AttributeKey<String>("floconCallId")
private val FLOCON_START_TIME_KEY = AttributeKey<Long>("floconStartTime")
private val FLOCON_IS_MOCKED_KEY = AttributeKey<Boolean>("floconIsMocked")
private val FLOCON_IS_MOCKED_KEY = AttributeKey<Boolean>("floconIsMocked")
private val FLOCON_SHOULD_LOG = AttributeKey<Boolean>("floconShouldLog")

View file

@ -13,6 +13,7 @@ data class FloconNetworkIsImageParams(
class FloconOkhttpInterceptor(
private val isImage: ((FloconNetworkIsImageParams) -> Boolean)? = null,
private val shouldLog: (chain: Interceptor.Chain) -> Boolean = { true },
) : Interceptor {
@Throws(IOException::class)

View file

@ -23,12 +23,13 @@ data class FloconNetworkIsImageParams(
class FloconOkhttpInterceptor(
private val isImage: ((FloconNetworkIsImageParams) -> Boolean)? = null,
private val shouldLog: (chain: Interceptor.Chain) -> Boolean = { true },
) : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val floconNetworkPlugin = FloconApp.instance?.client?.networkPlugin
if (floconNetworkPlugin == null) {
if (floconNetworkPlugin == null || !shouldLog(chain)) {
// on no op, do not intercept the call, just execute it
return chain.proceed(chain.request())
}

View file

@ -61,9 +61,16 @@ class MainActivity : ComponentActivity() {
val okHttpClient = OkHttpClient()
.newBuilder()
.addInterceptor(FloconOkhttpInterceptor(isImage = {
it.request.url.toString().contains("picsum")
}))
.addInterceptor(FloconOkhttpInterceptor(
isImage = {
it.request.url.toString().contains("picsum")
},
/*shouldLog = {
val url = it.request().url.toString()
println("url: $url")
url.contains("1").not()
}*/
))
.build()
initializeSharedPreferences(applicationContext)

View file

@ -28,7 +28,15 @@ class MainActivity : ComponentActivity() {
// Initialize Ktor client with Flocon plugin
val ktorClient = HttpClient(OkHttp) {
install(FloconKtorPlugin)
install(FloconKtorPlugin) {
/*
shouldLog = {
val url = it.url.toString()
println("url: $url")
url.contains("1").not()
}
*/
}
}
// Initialize the HTTP caller

View file

@ -15,7 +15,6 @@ import io.github.openflocon.flocon.myapplication.multi.database.FoodDatabase
import io.github.openflocon.flocon.myapplication.multi.database.initializeDatabases
import io.github.openflocon.flocon.myapplication.multi.ui.App
import io.github.openflocon.flocon.plugins.database.floconRegisterDatabase
import io.github.openflocon.flocon.plugins.tables.floconTable
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import kotlinx.coroutines.Dispatchers
@ -29,6 +28,13 @@ fun main() {
isImage = {
it.request.url.toString().contains("picsum.photos")
}
/*
shouldLog = {
val url = it.url.toString()
println("url: $url")
url.contains("1").not()
}
*/
}
}