Skip to content

Commit

Permalink
Add configurable endpoint for Prometheus scraping
Browse files Browse the repository at this point in the history
  • Loading branch information
SimunKaracic committed Feb 8, 2021
1 parent 28cdeac commit 40ec473
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ kamon.prometheus {
# Hostname and port used by the embedded web server to publish the scraping enpoint.
hostname = "0.0.0.0"
port = 9095
path = "/metrics"

# embedded server impl
# choose between
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,12 @@ class PrometheusReporter(configPath: String = DefaultConfigPath, initialConfig:
private def startEmbeddedServerIfEnabled(): Unit = {
if (_reporterSettings.startEmbeddedServer) {
val server = _reporterSettings.createEmbeddedHttpServerClass()
.getConstructor(Array[Class[_]](classOf[String], classOf[Int], classOf[ScrapeSource], classOf[Config]): _*)
.newInstance(_reporterSettings.embeddedServerHostname, _reporterSettings.embeddedServerPort:Integer, this, _config)
_logger.info(s"Started the embedded HTTP server on http://${_reporterSettings.embeddedServerHostname}:${_reporterSettings.embeddedServerPort}")
.getConstructor(Array[Class[_]](classOf[String], classOf[Int], classOf[String], classOf[ScrapeSource], classOf[Config]): _*)
.newInstance(_reporterSettings.embeddedServerHostname,
_reporterSettings.embeddedServerPort:Integer,
_reporterSettings.embeddedServerPath,
this, _config)
_logger.info(s"Started the embedded HTTP server on http://${_reporterSettings.embeddedServerHostname}:${_reporterSettings.embeddedServerPort}${_reporterSettings.embeddedServerPath}")
_embeddedHttpServer = Some(server)
}
}
Expand All @@ -101,6 +104,7 @@ object PrometheusReporter {
startEmbeddedServer: Boolean,
embeddedServerHostname: String,
embeddedServerPort: Int,
embeddedServerPath: String,
embeddedServerImpl: String,
generic: PrometheusSettings.Generic
) {
Expand All @@ -120,6 +124,7 @@ object PrometheusReporter {
startEmbeddedServer = prometheusConfig.getBoolean("start-embedded-http-server"),
embeddedServerHostname = prometheusConfig.getString("embedded-server.hostname"),
embeddedServerPort = prometheusConfig.getInt("embedded-server.port"),
embeddedServerPath = prometheusConfig.getString("embedded-server.path"),
embeddedServerImpl = prometheusConfig.getString("embedded-server.impl"),
generic = PrometheusSettings.readSettings(prometheusConfig)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ package kamon.prometheus.embeddedhttp
import com.typesafe.config.Config
import kamon.prometheus.ScrapeSource

abstract class EmbeddedHttpServer(hostname: String, port: Int, scrapeSource: ScrapeSource, config: Config) {
abstract class EmbeddedHttpServer(hostname: String, port: Int, path: String, scrapeSource: ScrapeSource, config: Config) {
def stop(): Unit
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ import java.util.zip.GZIPOutputStream
import scala.collection.JavaConverters._
import scala.collection.mutable

class SunEmbeddedHttpServer(hostname: String, port: Int, scrapeSource: ScrapeSource, config: Config) extends EmbeddedHttpServer(hostname, port, scrapeSource, config) {
class SunEmbeddedHttpServer(hostname: String, port: Int, path: String, scrapeSource: ScrapeSource, config: Config) extends EmbeddedHttpServer(hostname, port, path, scrapeSource, config) {
private val server = {
val s = HttpServer.create(new InetSocketAddress(InetAddress.getByName(hostname), port), 0)
s.setExecutor(null)
val handler = new HttpHandler {
override def handle(httpExchange: HttpExchange): Unit = {
if (httpExchange.getRequestURI.getPath == "/metrics") {
if (httpExchange.getRequestURI.getPath == path) {
val data = scrapeSource.scrapeData()
val bytes = data.getBytes(StandardCharsets.UTF_8)
var os: OutputStream = null
Expand All @@ -55,7 +55,7 @@ class SunEmbeddedHttpServer(hostname: String, port: Int, scrapeSource: ScrapeSou
}
}

s.createContext("/metrics", handler)
s.createContext(path, handler)
s.start()
s
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package kamon.prometheus
import java.io.FileNotFoundException
import java.net.URL
import com.typesafe.config.{Config, ConfigFactory}
import org.scalatest.concurrent.Eventually
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpec}

import java.util.zip.GZIPInputStream
import scala.concurrent.duration.DurationInt

class SunHttpServerSpecSuite extends EmbeddedHttpServerSpecSuite {
override def testConfig: Config = ConfigFactory.load()
Expand All @@ -22,7 +24,11 @@ class SunHttpServerSpecSuite extends EmbeddedHttpServerSpecSuite {
// override def port = 9096
//}

abstract class EmbeddedHttpServerSpecSuite extends WordSpec with Matchers with BeforeAndAfterAll with KamonTestSnapshotSupport {
abstract class EmbeddedHttpServerSpecSuite extends WordSpec
with Matchers
with BeforeAndAfterAll
with KamonTestSnapshotSupport
with Eventually {
protected def testConfig: Config

protected def port: Int = 9095
Expand Down Expand Up @@ -69,15 +75,6 @@ abstract class EmbeddedHttpServerSpecSuite extends WordSpec with Matchers with B
metrics shouldBe "# TYPE jvm_mem_total counter\njvm_mem_total 2.0\n"
}

"provide the metrics strictly on /metrics endpoint" in {
assertThrows[FileNotFoundException] {
httpGetMetrics("")
}
assertThrows[FileNotFoundException] {
httpGetMetrics("/metricsss")
}
}

"respect gzip Content-Encoding headers" in {
//arrange
testee.reportPeriodSnapshot(counter("jvm.mem"))
Expand All @@ -87,6 +84,20 @@ abstract class EmbeddedHttpServerSpecSuite extends WordSpec with Matchers with B
//assert
metrics.length should be > gzippedMetrics.length
}

"respect the path configuration" in {
httpGetMetrics("/metrics") should not be empty
assertThrows[FileNotFoundException] {
httpGetMetrics("/new-metrics")
}

testee.reconfigure(changeEndpoint("/new-metrics"))
httpGetMetrics("/new-metrics") should not be empty

assertThrows[FileNotFoundException] {
httpGetMetrics("/metrics")
}
}
}

private def httpGetMetrics(endpoint: String): String = {
Expand All @@ -106,4 +117,9 @@ abstract class EmbeddedHttpServerSpecSuite extends WordSpec with Matchers with B
try src.getLines.mkString
finally gzipStream.close()
}

private def changeEndpoint(path: String): Config = {
ConfigFactory.parseString(
s"""kamon.prometheus.embedded-server.path = ${path}""").withFallback(testConfig)
}
}

0 comments on commit 40ec473

Please sign in to comment.