Skip to content

Commit cc7a988

Browse files
authored
Merge pull request #65 from TimWSpence/non-safepointing-text-render
Non safepointing text render
2 parents e8e98a0 + 3fa71be commit cc7a988

3 files changed

Lines changed: 118 additions & 3 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2018 http4s.org
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.http4s.metrics.prometheus
18+
19+
import java.io.Writer
20+
21+
/** This should be equivalent to [[java.io.StringWriter]] but uses
22+
* a [[java.lang.StringBuilder]] rather than a [[java.lang.StringBuffer]]
23+
* and consequently is not synchronized
24+
*/
25+
private[prometheus] class NonSafepointingStringWriter extends Writer {
26+
27+
private[this] val buf: StringBuilder = new StringBuilder()
28+
29+
override def write(str: String): Unit = {
30+
buf.append(str)
31+
()
32+
}
33+
34+
override def write(buff: Array[Char]): Unit = {
35+
buf.append(buff)
36+
()
37+
}
38+
39+
override def write(i: Int): Unit = {
40+
buf.append(i.toChar)
41+
()
42+
}
43+
44+
override def write(str: String, start: Int, limit: Int): Unit = write(str.slice(start, limit))
45+
46+
override def write(buff: Array[Char], start: Int, limit: Int): Unit = write(
47+
buff.slice(start, limit)
48+
)
49+
50+
override def append(c: Char): Writer = {
51+
buf.append(c)
52+
this
53+
}
54+
55+
override def append(cs: CharSequence): Writer = {
56+
buf.append(cs)
57+
this
58+
}
59+
60+
override def append(cs: CharSequence, start: Int, limit: Int): Writer =
61+
// Replicating behaviour of StringWriter ¯\_(ツ)_/¯
62+
if (cs == null) append("null")
63+
else
64+
append(cs.subSequence(start, limit))
65+
66+
override def flush(): Unit = ()
67+
68+
override def close(): Unit = ()
69+
70+
override def toString(): String = buf.toString()
71+
72+
}

prometheus-metrics/src/main/scala/org/http4s/metrics/prometheus/PrometheusExportService.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ import org.http4s.Uri.Path
2525
import org.http4s._
2626
import org.http4s.syntax.all._
2727

28-
import java.io.StringWriter
29-
3028
/*
3129
* PrometheusExportService Contains an HttpService
3230
* ready to be scraped by Prometheus, paired
@@ -54,7 +52,7 @@ object PrometheusExportService {
5452
def generateResponse[F[_]: Sync](collectorRegistry: CollectorRegistry): F[Response[F]] =
5553
Sync[F]
5654
.delay {
57-
val writer = new StringWriter
55+
val writer = new NonSafepointingStringWriter()
5856
TextFormat.write004(writer, collectorRegistry.metricFamilySamples)
5957
writer.toString
6058
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2018 http4s.org
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.http4s.metrics.prometheus
18+
19+
import cats.effect._
20+
import munit.CatsEffectSuite
21+
import org.http4s.client.dsl.io._
22+
import org.http4s.dsl.io._
23+
import org.http4s.implicits._
24+
25+
class PrometheusExportServiceSuite extends CatsEffectSuite {
26+
27+
test("Returns Prometheus-format") {
28+
PrometheusExportService.build[IO].use { svc =>
29+
svc.routes.orNotFound
30+
.run(GET(uri"/metrics"))
31+
.flatMap(resp => resp.as[String])
32+
.flatMap { resp =>
33+
IO {
34+
val lines = resp.linesIterator.toList
35+
// Assortment of lines that should appear in the output as a sanity check
36+
assert(clue(lines).contains("# TYPE jvm_memory_pool_allocated_bytes_total counter"))
37+
assert(clue(lines).contains("# HELP jvm_threads_daemon Daemon thread count of a JVM"))
38+
assert(clue(lines).contains("# HELP process_open_fds Number of open file descriptors."))
39+
assert(clue(lines).contains("# TYPE process_open_fds gauge"))
40+
}
41+
}
42+
}
43+
}
44+
45+
}

0 commit comments

Comments
 (0)