From df2f0feef806c6e9b0f4c3715fd3368a32a19d24 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 14 May 2025 20:32:33 -0400 Subject: [PATCH] Improvement to the logs of RelaySpeedLogger --- .../service/relayClient/RelaySpeedLogger.kt | 68 +++++++++++++++---- .../vitorpamplona/quartz/utils/LargeCache.kt | 35 ++++++++++ 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/RelaySpeedLogger.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/RelaySpeedLogger.kt index 2286eaca1..711765964 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/RelaySpeedLogger.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/RelaySpeedLogger.kt @@ -30,21 +30,67 @@ import java.util.concurrent.atomic.AtomicInteger import kotlin.collections.forEach import kotlin.collections.get import kotlin.concurrent.timer +import kotlin.jvm.java import kotlin.text.get import kotlin.text.set +class KindGroup( + var count: AtomicInteger = AtomicInteger(0), + val subs: LargeCache = LargeCache(), + val relays: LargeCache = LargeCache(), +) { + fun increment( + subId: String, + relayUrl: String, + ) { + count.incrementAndGet() + + val subStats = subs.get(subId) + if (subStats != null) { + subStats.incrementAndGet() + } else { + subs.put(subId, AtomicInteger(1)) + } + + val relayStats = relays.get(relayUrl) + if (relayStats != null) { + relayStats.incrementAndGet() + } else { + relays.put(relayUrl, AtomicInteger(1)) + } + } + + fun reset() { + count.set(0) + subs.forEach { key, value -> value.set(0) } + relays.forEach { key, value -> value.set(0) } + } + + fun printSubs() = subs.joinToString(", ") { key, value -> if (value.get() > 0) "$key ($value)" else "" } + + fun printRelays() = relays.joinToString(", ") { key, value -> if (value.get() > 0) "${key.removePrefix("wss://").removeSuffix("/")} ($value)" else "" } + + override fun toString() = "(${count.get()}); ${printSubs()}; ${printRelays()}" +} + class FrameStat { var eventCount = AtomicInteger(0) - var kinds = LargeCache() + var kinds = LargeCache() - fun increment(kind: Int) { + fun increment( + kind: Int, + subId: String, + relayUrl: String, + ) { eventCount.incrementAndGet() - val kindCount = kinds.get(kind) - if (kindCount != null) { - kindCount.incrementAndGet() + val kindGroup = kinds.get(kind) + if (kindGroup != null) { + kindGroup.increment(subId, relayUrl) } else { - kinds.put(kind, AtomicInteger(1)) + val group = KindGroup(AtomicInteger(0)) + group.increment(subId, relayUrl) + kinds.put(kind, group) } } @@ -52,16 +98,14 @@ class FrameStat { fun reset() { eventCount.set(0) - kinds.forEach { key, value -> - value.set(0) - } + kinds.forEach { key, value -> value.reset() } } fun log() { Log.d(TAG, "Events Per Second: ${eventCount.get()}") kinds.forEach { key, value -> - if (value.get() > 0) { - Log.d(TAG, "-- Events Per Second Debug: $key $value") + if (value.count.get() > 0) { + Log.d(TAG, "-- Kind $key $value") } } } @@ -101,7 +145,7 @@ class RelaySpeedLogger( arrivalTime: Long, afterEOSE: Boolean, ) { - current.increment(event.kind) + current.increment(event.kind, subscriptionId, relay.url) } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/utils/LargeCache.kt b/quartz/src/main/java/com/vitorpamplona/quartz/utils/LargeCache.kt index 5626fa1c2..860a6ae4f 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/utils/LargeCache.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/utils/LargeCache.kt @@ -20,8 +20,11 @@ */ package com.vitorpamplona.quartz.utils +import org.apache.commons.lang3.text.FormattableUtils.append +import java.io.File.separator import java.util.concurrent.ConcurrentSkipListMap import java.util.function.BiConsumer +import kotlin.text.StringBuilder class LargeCache { private val cache = ConcurrentSkipListMap() @@ -159,6 +162,38 @@ class LargeCache { cache.forEach(runner) // } // println("LargeCache full loop $elapsed \t for $runner") + + listOf(1, 2, 3).joinToString() + } + + fun joinToString( + separator: CharSequence = ", ", + prefix: CharSequence = "", + postfix: CharSequence = "", + limit: Int = -1, + truncated: CharSequence = "...", + transform: ((K, V) -> CharSequence)? = null, + ): String { + val buffer = StringBuilder() + buffer.append(prefix) + var count = 0 + forEach { key, value -> + val str = if (transform != null) transform(key, value) else "" + if (str.isNotEmpty()) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + when { + transform != null -> buffer.append(str) + else -> buffer.append("$key $value") + } + } else { + return@forEach + } + } + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer.toString() } }