Skip to content

Commit 0f731a3

Browse files
keremncjenkins
authored and
jenkins
committed
finagle-stats: convert illegal Prometheus characters to underscores
==== Problem Finagle's Prometheus exporter will happily export hyphens and forward slashes which are illegal Prometheus characters. ==== Solution Replace all illegal characters with underscores Differential Revision: https://phabricator.twitter.biz/D1218924
1 parent 52c72c4 commit 0f731a3

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ private final class PrometheusExporter(
1717
exportMetadata: Boolean,
1818
exportEmptyQuantiles: Boolean,
1919
verbosityPattern: Option[String => Boolean]) {
20+
private[this] final val NamePattern = """[^a-zA-Z0-9_]""".r
2021

2122
/**
2223
* Write the value of the metric as a `Double`.
@@ -162,7 +163,7 @@ private final class PrometheusExporter(
162163
} else {
163164
writer.append(',')
164165
}
165-
writer.append(name)
166+
writer.append(NamePattern.replaceAllIn(name, MetricBuilder.DimensionalNameScopeSeparator))
166167
writer.append('=')
167168
writer.append('"')
168169
writer.append(value)
@@ -249,7 +250,9 @@ private final class PrometheusExporter(
249250
}
250251

251252
private[this] def writeName(writer: StringBuilder, name: Seq[String]): Unit =
252-
name.addString(writer, MetricBuilder.DimensionalNameScopeSeparator)
253+
name.view
254+
.map { part => NamePattern.replaceAllIn(part, MetricBuilder.DimensionalNameScopeSeparator) }
255+
.addString(writer, MetricBuilder.DimensionalNameScopeSeparator)
253256

254257
/**
255258
* Write user-defined labels and reserved labels for Prometheus summary and histogram.

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,4 +261,24 @@ class PrometheusExporterTest extends AnyFunSuite {
261261
|foo_ping_ms_sum{biz="bar"} 6
262262
|""".stripMargin)
263263
}
264+
265+
test("translate illegal Prometheus characters to underscores") {
266+
val counter = CounterSnapshot(
267+
hierarchicalName = "metric",
268+
builder = MetricBuilder(
269+
name = Seq("invalid-metric.seconds"),
270+
metricType = CounterType,
271+
units = Seconds
272+
).withLabels(Map("invalid.label" -> "foo")).withDimensionalSupport,
273+
value = 500L
274+
)
275+
val result = writeMetrics(Seq(counter), Seq.empty, Seq.empty, exportMetadata = true)
276+
277+
assert(
278+
result ==
279+
"""# TYPE invalid_metric_seconds counter
280+
|# UNIT invalid_metric_seconds Seconds
281+
|invalid_metric_seconds{invalid_label="foo"} 500
282+
|""".stripMargin)
283+
}
264284
}

0 commit comments

Comments
 (0)