From e1e016efa260a1f45afc7a76777c7dcca6278a78 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 9 Apr 2026 11:25:11 +0000 Subject: [PATCH 1/7] Add RewardsComputationSummary Signed-off-by: Tim Emiola --- .../automation/RewardComputationTrigger.scala | 10 +++- .../scan/store/ScanAppRewardsStore.scala | 3 +- .../scan/store/db/DbScanAppRewardsStore.scala | 52 ++++++++++++++++++- .../store/DbScanAppRewardsStoreTest.scala | 48 +++++++++++++++++ 4 files changed, 109 insertions(+), 4 deletions(-) diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala index 8acdc04e63..fd2ce9b283 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala @@ -61,7 +61,15 @@ class RewardComputationTrigger( )(implicit tc: TraceContext): Future[TaskOutcome] = appRewardsStore .computeAndStoreRewards(task.roundNumber) - .map(_ => TaskSuccess(s"Computed rewards for round ${task.roundNumber}")) + .map(summary => + TaskSuccess( + s"Computed rewards for round ${task.roundNumber}: " + + s"${summary.activePartiesCount} active parties, " + + s"${summary.activityRecordsCount} activity records, " + + s"${summary.rewardedPartiesCount} rewarded parties, " + + s"${summary.batchesCreatedCount} batches" + ) + ) override protected def isStaleTask( task: RewardComputationTrigger.Task diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/ScanAppRewardsStore.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/ScanAppRewardsStore.scala index 46af735fa9..ad08436e88 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/ScanAppRewardsStore.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/ScanAppRewardsStore.scala @@ -4,6 +4,7 @@ package org.lfdecentralizedtrust.splice.scan.store import com.digitalasset.canton.tracing.TraceContext +import org.lfdecentralizedtrust.splice.scan.store.db.DbScanAppRewardsStore.RewardComputationSummary import scala.concurrent.Future @@ -28,5 +29,5 @@ trait ScanAppRewardsStore { */ def computeAndStoreRewards(roundNumber: Long)(implicit tc: TraceContext - ): Future[Unit] + ): Future[RewardComputationSummary] } diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala index 6f1bcbfd94..6308f30efa 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala @@ -79,6 +79,14 @@ object DbScanAppRewardsStore { roundNumber: Long, rootHash: ByteString, ) + + /** Summary of a single round's reward computation, for metrics reporting. */ + final case class RewardComputationSummary( + activePartiesCount: Long, + activityRecordsCount: Long, + rewardedPartiesCount: Long, + batchesCreatedCount: Long, + ) } class DbScanAppRewardsStore( @@ -177,6 +185,16 @@ class DbScanAppRewardsStore( ) } + private implicit val getResultRewardComputationSummary + : GetResult[DbScanAppRewardsStore.RewardComputationSummary] = GetResult { prs => + DbScanAppRewardsStore.RewardComputationSummary( + activePartiesCount = prs.<<[Long], + activityRecordsCount = prs.<<[Long], + rewardedPartiesCount = prs.<<[Long], + batchesCreatedCount = prs.<<[Long], + ) + } + // -- app_activity_party_totals -------------------------------------------- private def batchInsertAppActivityPartyTotals( @@ -496,8 +514,11 @@ class DbScanAppRewardsStore( */ def computeAndStoreRewards( roundNumber: Long - )(implicit tc: TraceContext): Future[Unit] = - aggregateActivityTotals(roundNumber) + )(implicit tc: TraceContext): Future[DbScanAppRewardsStore.RewardComputationSummary] = + for { + _ <- aggregateActivityTotals(roundNumber) + summary <- readComputationSummary(roundNumber) + } yield summary /** Aggregate per-party and per-round activity totals for the given round from * `app_activity_record_store`. @@ -634,6 +655,33 @@ class DbScanAppRewardsStore( ) } + // -- Computation summary ---------------------------------------------------- + + /** Read back the summary counters for a round that was just computed, + * within the same transaction. + */ + private def readComputationSummary(roundNumber: Long)(implicit + tc: TraceContext + ): Future[DbScanAppRewardsStore.RewardComputationSummary] = + runQuery( + sql"""select + (select active_app_provider_parties_count + from #${Tables.appActivityRoundTotals} + where history_id = $historyId and round_number = $roundNumber), + (select count(*) + from app_activity_record_store a + join scan_verdict_store v on a.verdict_row_id = v.row_id + where a.round_number = $roundNumber and v.history_id = $historyId), + (select coalesce(rewarded_app_provider_parties_count, 0) + from #${Tables.appRewardRoundTotals} + where history_id = $historyId and round_number = $roundNumber), + (select count(*) + from #${Tables.appRewardBatchHashes} + where history_id = $historyId and round_number = $roundNumber) + """.as[DbScanAppRewardsStore.RewardComputationSummary].head, + "appRewards.readComputationSummary", + ) + // -- Private helpers ------------------------------------------------------- private def runQuery[T]( diff --git a/apps/scan/src/test/scala/org/lfdecentralizedtrust/splice/scan/store/DbScanAppRewardsStoreTest.scala b/apps/scan/src/test/scala/org/lfdecentralizedtrust/splice/scan/store/DbScanAppRewardsStoreTest.scala index 30c8e49525..a42a443399 100644 --- a/apps/scan/src/test/scala/org/lfdecentralizedtrust/splice/scan/store/DbScanAppRewardsStoreTest.scala +++ b/apps/scan/src/test/scala/org/lfdecentralizedtrust/splice/scan/store/DbScanAppRewardsStoreTest.scala @@ -500,6 +500,54 @@ class DbScanAppRewardsStoreTest } } + // -- computeAndStoreRewards summary tests ---------------------------------- + + "computeAndStoreRewards — returns correct summary counts" in { + for { + (store, historyId) <- newStore() + _ <- insertSentinelRecords(historyId, roundNumber) + // 3 activity records, 2 parties (alice in 2 records, bob in 1) + _ <- insertActivityRecord( + historyId, + roundNumber, + Seq("alice::provider", "bob::provider"), + Seq(3000000L, 2000000L), + ) + _ <- insertActivityRecord( + historyId, + roundNumber, + Seq("alice::provider"), + Seq(1000000L), + ) + _ <- insertActivityRecord( + historyId, + roundNumber, + Seq("bob::provider"), + Seq(500000L), + ) + summary <- store.computeAndStoreRewards(roundNumber) + } yield { + summary.activePartiesCount shouldBe 2L + summary.activityRecordsCount shouldBe 3L + // No reward computation on this branch yet + summary.rewardedPartiesCount shouldBe 0L + summary.batchesCreatedCount shouldBe 0L + } + } + + "computeAndStoreRewards — empty round returns zero counts" in { + for { + (store, historyId) <- newStore() + _ <- insertSentinelRecords(historyId, roundNumber) + summary <- store.computeAndStoreRewards(roundNumber) + } yield { + summary.activePartiesCount shouldBe 0L + summary.activityRecordsCount shouldBe 0L + summary.rewardedPartiesCount shouldBe 0L + summary.batchesCreatedCount shouldBe 0L + } + } + // -- computeRewardTotals tests ------------------------------------------- val rewardTotalsTestCases = Seq( From e2968659843abd79c58a453a721ba7deda86e765 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 9 Apr 2026 11:26:00 +0000 Subject: [PATCH 2/7] Add RewardComputationMetrics Signed-off-by: Tim Emiola --- .../metrics/RewardComputationMetrics.scala | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala new file mode 100644 index 0000000000..0b62060fb6 --- /dev/null +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala @@ -0,0 +1,56 @@ +// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package org.lfdecentralizedtrust.splice.scan.metrics + +import com.daml.metrics.api.MetricHandle.{Counter, LabeledMetricsFactory} +import com.daml.metrics.api.MetricQualification.Traffic +import com.daml.metrics.api.{MetricInfo, MetricName, MetricsContext} +import org.lfdecentralizedtrust.splice.environment.SpliceMetrics +import org.lfdecentralizedtrust.splice.scan.store.db.DbScanAppRewardsStore.RewardComputationSummary + +class RewardComputationMetrics(metricsFactory: LabeledMetricsFactory)(implicit + metricsContext: MetricsContext +) { + private val prefix: MetricName = + SpliceMetrics.MetricsPrefix :+ "scan" :+ "reward_computation" + + val activePartiesCount: Counter = metricsFactory.counter( + MetricInfo( + name = prefix :+ "active-parties-count", + summary = "Cumulative number of parties with activity across computed rounds", + qualification = Traffic, + ) + )(metricsContext) + + val activityRecordsCount: Counter = metricsFactory.counter( + MetricInfo( + name = prefix :+ "activity-records-count", + summary = "Cumulative number of activity records summarized across computed rounds", + qualification = Traffic, + ) + )(metricsContext) + + val rewardedPartiesCount: Counter = metricsFactory.counter( + MetricInfo( + name = prefix :+ "rewarded-parties-count", + summary = "Cumulative number of parties with rewards across computed rounds", + qualification = Traffic, + ) + )(metricsContext) + + val batchesCreatedCount: Counter = metricsFactory.counter( + MetricInfo( + name = prefix :+ "batches-created-count", + summary = "Cumulative number of reward batches created across computed rounds", + qualification = Traffic, + ) + )(metricsContext) + + def record(summary: RewardComputationSummary): Unit = { + activePartiesCount.inc(summary.activePartiesCount)(metricsContext) + activityRecordsCount.inc(summary.activityRecordsCount)(metricsContext) + rewardedPartiesCount.inc(summary.rewardedPartiesCount)(metricsContext) + batchesCreatedCount.inc(summary.batchesCreatedCount)(metricsContext) + } +} From 3cf25a6036554bc691ac09fdb93cffa7b48d2fe6 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 9 Apr 2026 11:27:02 +0000 Subject: [PATCH 3/7] Register RewardComputationMetrics in RewardComputationTrigger Signed-off-by: Tim Emiola --- .../scan/automation/RewardComputationTrigger.scala | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala index fd2ce9b283..81db91bd68 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala @@ -4,12 +4,14 @@ package org.lfdecentralizedtrust.splice.scan.automation import org.apache.pekko.stream.Materializer +import com.daml.metrics.api.MetricsContext import org.lfdecentralizedtrust.splice.automation.{ PollingParallelTaskExecutionTrigger, TaskOutcome, TaskSuccess, TriggerContext, } +import org.lfdecentralizedtrust.splice.scan.metrics.RewardComputationMetrics import org.lfdecentralizedtrust.splice.scan.store.{AppActivityStore, ScanAppRewardsStore} import org.lfdecentralizedtrust.splice.store.UpdateHistory import com.digitalasset.canton.logging.pretty.{Pretty, PrettyPrinting} @@ -38,6 +40,12 @@ class RewardComputationTrigger( mat: Materializer, ) extends PollingParallelTaskExecutionTrigger[RewardComputationTrigger.Task] { + private val rewardMetrics = new RewardComputationMetrics(context.metricsFactory)( + MetricsContext( + "current_migration_id" -> updateHistory.domainMigrationInfo.currentMigrationId.toString + ) + ) + override def retrieveTasks()(implicit tc: TraceContext ): Future[Seq[RewardComputationTrigger.Task]] = { @@ -61,7 +69,8 @@ class RewardComputationTrigger( )(implicit tc: TraceContext): Future[TaskOutcome] = appRewardsStore .computeAndStoreRewards(task.roundNumber) - .map(summary => + .map { summary => + rewardMetrics.record(summary) TaskSuccess( s"Computed rewards for round ${task.roundNumber}: " + s"${summary.activePartiesCount} active parties, " + @@ -69,7 +78,7 @@ class RewardComputationTrigger( s"${summary.rewardedPartiesCount} rewarded parties, " + s"${summary.batchesCreatedCount} batches" ) - ) + } override protected def isStaleTask( task: RewardComputationTrigger.Task From 2a2baeecaa123625d7abbaa8cc92b2ab8c6c280c Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 9 Apr 2026 11:27:49 +0000 Subject: [PATCH 4/7] [ci] Add a TODO to obtain activity_records_count from a DB column Signed-off-by: Tim Emiola --- .../splice/scan/store/db/DbScanAppRewardsStore.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala index 6308f30efa..c1a8e722f3 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala @@ -660,6 +660,8 @@ class DbScanAppRewardsStore( /** Read back the summary counters for a round that was just computed, * within the same transaction. */ + // TODO(#4645): read activity_records_count from app_activity_round_totals + // instead of using a separate count query private def readComputationSummary(roundNumber: Long)(implicit tc: TraceContext ): Future[DbScanAppRewardsStore.RewardComputationSummary] = From 9752a385831cbd3aafad762f713515b68c67eb1e Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 9 Apr 2026 11:28:57 +0000 Subject: [PATCH 5/7] [ci] Use snake case Signed-off-by: Tim Emiola --- .../splice/scan/metrics/RewardComputationMetrics.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala index 0b62060fb6..a7c82b614f 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala @@ -17,7 +17,7 @@ class RewardComputationMetrics(metricsFactory: LabeledMetricsFactory)(implicit val activePartiesCount: Counter = metricsFactory.counter( MetricInfo( - name = prefix :+ "active-parties-count", + name = prefix :+ "active_parties_count", summary = "Cumulative number of parties with activity across computed rounds", qualification = Traffic, ) @@ -25,7 +25,7 @@ class RewardComputationMetrics(metricsFactory: LabeledMetricsFactory)(implicit val activityRecordsCount: Counter = metricsFactory.counter( MetricInfo( - name = prefix :+ "activity-records-count", + name = prefix :+ "activity_records_count", summary = "Cumulative number of activity records summarized across computed rounds", qualification = Traffic, ) @@ -33,7 +33,7 @@ class RewardComputationMetrics(metricsFactory: LabeledMetricsFactory)(implicit val rewardedPartiesCount: Counter = metricsFactory.counter( MetricInfo( - name = prefix :+ "rewarded-parties-count", + name = prefix :+ "rewarded_parties_count", summary = "Cumulative number of parties with rewards across computed rounds", qualification = Traffic, ) @@ -41,7 +41,7 @@ class RewardComputationMetrics(metricsFactory: LabeledMetricsFactory)(implicit val batchesCreatedCount: Counter = metricsFactory.counter( MetricInfo( - name = prefix :+ "batches-created-count", + name = prefix :+ "batches_created_count", summary = "Cumulative number of reward batches created across computed rounds", qualification = Traffic, ) From b14d527aca020ee4ba0e6442db7f85554541de8c Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 9 Apr 2026 20:36:18 +0900 Subject: [PATCH 6/7] Obtain activity_records_count without a JOIN Signed-off-by: Tim Emiola --- .../splice/scan/store/db/DbScanAppRewardsStore.scala | 9 +++------ .../splice/scan/store/DbScanAppRewardsStoreTest.scala | 6 +++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala index c1a8e722f3..34299f7faa 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanAppRewardsStore.scala @@ -660,8 +660,6 @@ class DbScanAppRewardsStore( /** Read back the summary counters for a round that was just computed, * within the same transaction. */ - // TODO(#4645): read activity_records_count from app_activity_round_totals - // instead of using a separate count query private def readComputationSummary(roundNumber: Long)(implicit tc: TraceContext ): Future[DbScanAppRewardsStore.RewardComputationSummary] = @@ -670,10 +668,9 @@ class DbScanAppRewardsStore( (select active_app_provider_parties_count from #${Tables.appActivityRoundTotals} where history_id = $historyId and round_number = $roundNumber), - (select count(*) - from app_activity_record_store a - join scan_verdict_store v on a.verdict_row_id = v.row_id - where a.round_number = $roundNumber and v.history_id = $historyId), + (select activity_records_count + from #${Tables.appActivityRoundTotals} + where history_id = $historyId and round_number = $roundNumber), (select coalesce(rewarded_app_provider_parties_count, 0) from #${Tables.appRewardRoundTotals} where history_id = $historyId and round_number = $roundNumber), diff --git a/apps/scan/src/test/scala/org/lfdecentralizedtrust/splice/scan/store/DbScanAppRewardsStoreTest.scala b/apps/scan/src/test/scala/org/lfdecentralizedtrust/splice/scan/store/DbScanAppRewardsStoreTest.scala index a42a443399..1aabe2db2a 100644 --- a/apps/scan/src/test/scala/org/lfdecentralizedtrust/splice/scan/store/DbScanAppRewardsStoreTest.scala +++ b/apps/scan/src/test/scala/org/lfdecentralizedtrust/splice/scan/store/DbScanAppRewardsStoreTest.scala @@ -506,7 +506,7 @@ class DbScanAppRewardsStoreTest for { (store, historyId) <- newStore() _ <- insertSentinelRecords(historyId, roundNumber) - // 3 activity records, 2 parties (alice in 2 records, bob in 1) + // 3 activity records, 2 parties (alice in 2 records, bob in 2) _ <- insertActivityRecord( historyId, roundNumber, @@ -528,8 +528,8 @@ class DbScanAppRewardsStoreTest summary <- store.computeAndStoreRewards(roundNumber) } yield { summary.activePartiesCount shouldBe 2L - summary.activityRecordsCount shouldBe 3L - // No reward computation on this branch yet + summary.activityRecordsCount shouldBe 4L // sum of per-party counts: alice=2 + bob=2 + // TODO(#4382): update when full reward pipeline is wired into computeAndStoreRewards summary.rewardedPartiesCount shouldBe 0L summary.batchesCreatedCount shouldBe 0L } From b34e7f844bf23d5bb65dd3cc5f3ec1a67989ffb3 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 9 Apr 2026 20:38:58 +0900 Subject: [PATCH 7/7] [ci] Use a Gauge instead of a Counter Signed-off-by: Tim Emiola --- .../automation/RewardComputationTrigger.scala | 5 ++ .../metrics/RewardComputationMetrics.scala | 47 ++++++++++++------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala index 81db91bd68..d0428a1905 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/automation/RewardComputationTrigger.scala @@ -14,6 +14,7 @@ import org.lfdecentralizedtrust.splice.automation.{ import org.lfdecentralizedtrust.splice.scan.metrics.RewardComputationMetrics import org.lfdecentralizedtrust.splice.scan.store.{AppActivityStore, ScanAppRewardsStore} import org.lfdecentralizedtrust.splice.store.UpdateHistory +import com.digitalasset.canton.lifecycle.{AsyncOrSyncCloseable, SyncCloseable} import com.digitalasset.canton.logging.pretty.{Pretty, PrettyPrinting} import com.digitalasset.canton.tracing.TraceContext import io.opentelemetry.api.trace.Tracer @@ -86,6 +87,10 @@ class RewardComputationTrigger( appRewardsStore .lookupLatestRoundWithRewardComputation() .map(_.exists(_ >= task.roundNumber)) + + override def closeAsync(): Seq[AsyncOrSyncCloseable] = + super.closeAsync() :+ + SyncCloseable("RewardComputationMetrics", rewardMetrics.close()) } object RewardComputationTrigger { diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala index a7c82b614f..113a3bd983 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/metrics/RewardComputationMetrics.scala @@ -3,7 +3,7 @@ package org.lfdecentralizedtrust.splice.scan.metrics -import com.daml.metrics.api.MetricHandle.{Counter, LabeledMetricsFactory} +import com.daml.metrics.api.MetricHandle.{Gauge, LabeledMetricsFactory} import com.daml.metrics.api.MetricQualification.Traffic import com.daml.metrics.api.{MetricInfo, MetricName, MetricsContext} import org.lfdecentralizedtrust.splice.environment.SpliceMetrics @@ -11,46 +11,57 @@ import org.lfdecentralizedtrust.splice.scan.store.db.DbScanAppRewardsStore.Rewar class RewardComputationMetrics(metricsFactory: LabeledMetricsFactory)(implicit metricsContext: MetricsContext -) { +) extends AutoCloseable { private val prefix: MetricName = SpliceMetrics.MetricsPrefix :+ "scan" :+ "reward_computation" - val activePartiesCount: Counter = metricsFactory.counter( + val activePartiesCount: Gauge[Long] = metricsFactory.gauge( MetricInfo( name = prefix :+ "active_parties_count", - summary = "Cumulative number of parties with activity across computed rounds", + summary = "Number of parties with activity in the latest computed round", qualification = Traffic, - ) + ), + 0L, )(metricsContext) - val activityRecordsCount: Counter = metricsFactory.counter( + val activityRecordsCount: Gauge[Long] = metricsFactory.gauge( MetricInfo( name = prefix :+ "activity_records_count", - summary = "Cumulative number of activity records summarized across computed rounds", + summary = "Number of activity records in the latest computed round", qualification = Traffic, - ) + ), + 0L, )(metricsContext) - val rewardedPartiesCount: Counter = metricsFactory.counter( + val rewardedPartiesCount: Gauge[Long] = metricsFactory.gauge( MetricInfo( name = prefix :+ "rewarded_parties_count", - summary = "Cumulative number of parties with rewards across computed rounds", + summary = "Number of parties with rewards in the latest computed round", qualification = Traffic, - ) + ), + 0L, )(metricsContext) - val batchesCreatedCount: Counter = metricsFactory.counter( + val batchesCreatedCount: Gauge[Long] = metricsFactory.gauge( MetricInfo( name = prefix :+ "batches_created_count", - summary = "Cumulative number of reward batches created across computed rounds", + summary = "Number of reward batches created in the latest computed round", qualification = Traffic, - ) + ), + 0L, )(metricsContext) def record(summary: RewardComputationSummary): Unit = { - activePartiesCount.inc(summary.activePartiesCount)(metricsContext) - activityRecordsCount.inc(summary.activityRecordsCount)(metricsContext) - rewardedPartiesCount.inc(summary.rewardedPartiesCount)(metricsContext) - batchesCreatedCount.inc(summary.batchesCreatedCount)(metricsContext) + activePartiesCount.updateValue(summary.activePartiesCount) + activityRecordsCount.updateValue(summary.activityRecordsCount) + rewardedPartiesCount.updateValue(summary.rewardedPartiesCount) + batchesCreatedCount.updateValue(summary.batchesCreatedCount) + } + + override def close(): Unit = { + activePartiesCount.close() + activityRecordsCount.close() + rewardedPartiesCount.close() + batchesCreatedCount.close() } }