Skip to content

Instantly share code, notes, and snippets.

@timohirt
Created February 22, 2016 14:37
Show Gist options
  • Save timohirt/3836b6b875dfcf912a36 to your computer and use it in GitHub Desktop.
Save timohirt/3836b6b875dfcf912a36 to your computer and use it in GitHub Desktop.
Play! Framework Controller exposing Prometheus metrics
package controllers
import java.io.Writer
import io.prometheus.client.CollectorRegistry
import io.prometheus.client.exporter.common.TextFormat
import play.api.libs.iteratee.Concurrent
import play.api.mvc.{Action, Controller}
/*
* Don't forget to define a route to this endpoint like:
*
* /metrics controllers.PrometheusMetricsController.index
*
*/
class PrometheusMetricsController extends Controller {
def index = Action {
import play.api.libs.concurrent.Execution.Implicits._
val responseStream = Concurrent.unicast[Array[Byte]] { channel =>
val writer = new WriterAdapter(channel)
TextFormat.write004(writer, CollectorRegistry.defaultRegistry.metricFamilySamples())
writer.close()
}
Ok.stream(responseStream).withHeaders("Content-Type" -> TextFormat.CONTENT_TYPE_004)
}
}
class WriterAdapter(channel: Concurrent.Channel[Array[Byte]])
extends Writer {
override def write(charArray: Array[Char], offset: Int, length: Int): Unit = {
channel.push(new String(charArray, offset, length).getBytes("UTF-8"))
}
override def flush(): Unit = channel.end
override def close(): Unit = channel.eofAndEnd
}
@jnesbitt
Copy link

Thanks Tim. This was helpful. I'm using Play! 2.5 so I had to make a few modifications to make this work with the new Result API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment