Skip to content

Commit 11ca7e8

Browse files
keremncjenkins
authored and
jenkins
committed
finagle: more comprehensive support for dimensional metrics
==== Problem Finagle doesn't have comprehensive support for dimensional metrics === Solution 1. Promote the visibility of `hierarchicalScope`, `dimensionalScope`, and `label` in `StatsReceiver` to public. This allows consumers to define their metric schemas for dual-consumption by the flat JSON & Prometheus exporters 2. Add the flag `com.twitter.finagle.stats.fullTranslation`. This allows service owners to express that raw `.scope` calls on `StatsReceiver` instances to propagate both hierarchical & dimensional metrics 3. Add the flag `com.twitter.finagle.stats.biasToFull`. This allows service owners to express that metrics with an indeterminate identity (have not been explicitly set as dimensional) to be exported through Prometheus anyways. 4. Remove the redundant dimensional scopes set on default Finagle client/service metrics 5. Remove the redundant `app` dimensional scope set on metrics exporter through `DefaultStatsReceiver` 6. Adjust, backwards-compatibly, the JVM metrics to utilize the new APIs and export the memory manager, pool, etc as a label instead of a hierarchical scope 7. Adjust, backwards-compatibly, some other internal use-cases to use labels instead of hierarchical scope Differential Revision: https://phabricator.twitter.biz/D1218090
1 parent f00908c commit 11ca7e8

File tree

8 files changed

+34
-7
lines changed

8 files changed

+34
-7
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ Runtime Behavior Changes
2424
* finagle-core: `PipeliningClientPushSession` now collects stats `epoll_queue_delay_ns` and `message_send_latency_ns`.
2525
``PHAB_ID=D1185421``
2626
* finagle-core: Halve Netty tasks in Netty4 pipeline client. ``PHAB_ID=D1193718``
27+
* finagle-core: Dimensional client & server metrics are prefixed with just `finagle_` instead of `rpc_finagle_client`
28+
and `rpc_finagle_server`, respectively. ``PHAB_ID=D1218090``
29+
* finagle-core: Dimensional metrics from `DefaultStatsReceiver` are no longer prefixed with `app_`. ``PHAB_ID=D1218090``
2730

2831
New Features
2932
~~~~~~~~~~

finagle-core/src/main/scala/com/twitter/finagle/client/EndpointerStackClient.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,5 +178,5 @@ trait EndpointerStackClient[Req, Rep, This <: EndpointerStackClient[Req, Rep, Th
178178
}
179179

180180
private object EndpointerStackClient {
181-
private val DimensionalClientScopes: Seq[String] = Seq("rpc", "finagle", "client")
181+
private val DimensionalClientScopes: Seq[String] = Seq("finagle")
182182
}

finagle-core/src/main/scala/com/twitter/finagle/server/ListeningStackServer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,5 +217,5 @@ trait ListeningStackServer[Req, Rep, This <: ListeningStackServer[Req, Rep, This
217217
}
218218

219219
private object ListeningStackServer {
220-
private val DimensionalServerScopes: Seq[String] = Seq("rpc", "finagle", "server")
220+
private val DimensionalServerScopes: Seq[String] = Seq("finagle")
221221
}

finagle-core/src/main/scala/com/twitter/finagle/stats/FinagleStatsReceiverImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ private final class FinagleStatsReceiverImpl(underlyingStatsReceiver: StatsRecei
1919
.translateIdentity(underlyingStatsReceiver) { identity =>
2020
identity.copy(
2121
hierarchicalName = "finagle" +: identity.hierarchicalName,
22-
dimensionalName = "rpc" +: "finagle" +: identity.dimensionalName,
22+
dimensionalName = "finagle" +: identity.dimensionalName,
2323
labels = identity.labels ++ newLabels,
2424
identityType = identity.identityType.bias(IdentityType.Full)
2525
)

finagle-core/src/main/scala/com/twitter/finagle/stats/StandardStatsReceiver.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ private[finagle] class StandardStatsReceiver protected (
5656

5757
final val self: StatsReceiver =
5858
BroadcastStatsReceiver(
59-
Seq(rootStatsReceiver, rootStatsReceiver.scope(protocol).scope(serverScope)))
59+
Seq(
60+
rootStatsReceiver,
61+
rootStatsReceiver
62+
.hierarchicalScope(protocol).hierarchicalScope(serverScope)
63+
.label("protocol", protocol).label("server", serverScope)
64+
)
65+
)
6066

6167
final override def counter(metricBuilder: MetricBuilder): Counter =
6268
self.counter(withDescription(metricBuilder).withStandard.withUnlatchedCounter)

finagle-core/src/test/scala/com/twitter/finagle/stats/FinagleStatsReceiverTest.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class FinagleStatsReceiverTest extends AnyFunSuite {
1717
}
1818

1919
test("Metrics get the right dimensional scopes and labels") {
20-
assert(bizBazIdentity.dimensionalName == Seq("rpc", "finagle", "biz", "baz"))
20+
assert(bizBazIdentity.dimensionalName == Seq("finagle", "biz", "baz"))
2121
assert(bizBazIdentity.labels == Map("implementation" -> "finagle", "rpc_system" -> "finagle"))
2222
}
2323

@@ -41,7 +41,7 @@ class FinagleStatsReceiverTest extends AnyFunSuite {
4141
assert(identity.identityType == IdentityType.HierarchicalOnly)
4242

4343
assert(identity.hierarchicalName == Seq("finagle", "biz", "baz"))
44-
assert(identity.dimensionalName == Seq("rpc", "finagle", "biz", "baz"))
44+
assert(identity.dimensionalName == Seq("finagle", "biz", "baz"))
4545
assert(identity.labels == Map("implementation" -> "finagle", "rpc_system" -> "finagle"))
4646
}
4747
}

finagle-stats-core/src/main/scala/com/twitter/finagle/stats/MetricsStatsReceiver.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ object scopeSeparator
4545
"Override the scope separator."
4646
)
4747

48+
object fullTranslation
49+
extends GlobalFlag[Boolean](
50+
false,
51+
"Translate all scope() calls on StatsReceivers in both dimensional & hierarchical mode"
52+
)
53+
4854
object MetricsStatsReceiver {
4955
val defaultRegistry = new Metrics()
5056
private[stats] val defaultHostRegistry = Metrics.createDetached()
@@ -126,6 +132,12 @@ class MetricsStatsReceiver(val registry: Metrics)
126132

127133
override def toString: String = "MetricsStatsReceiver"
128134

135+
override def scopeTranslation: NameTranslatingStatsReceiver.Mode = if (fullTranslation()) {
136+
NameTranslatingStatsReceiver.FullTranslation
137+
} else {
138+
super.scopeTranslation
139+
}
140+
129141
/**
130142
* Create and register a counter inside the underlying Metrics library
131143
*/

finagle-toggle/src/main/scala/com/twitter/finagle/toggle/StandardToggleMap.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,13 @@ object StandardToggleMap {
123123
ServiceLoadedToggleMap(libraryName),
124124
libsJson
125125
)
126-
val observed = ToggleMap.observed(stacked, statsReceiver.scope("toggles", libraryName))
126+
val observed = ToggleMap.observed(
127+
stacked,
128+
statsReceiver
129+
.scope("toggles")
130+
.hierarchicalScope(libraryName)
131+
.label("library", libraryName)
132+
)
127133
val toggleMap = new ToggleMap.Mutable with ToggleMap.Proxy {
128134
def underlying: ToggleMap = observed
129135
def put(id: String, fraction: Double): Unit = mutable.put(id, fraction)

0 commit comments

Comments
 (0)