Send Finagle stats to Codahale Metrics

Last year I needed to send lots of metrics from some java applications to Graphite, and I did it easily using a library called Metrics.

Recently I had to send some stats from a Finagle based application (Finagle collect and expose some metrics automatically) to the same Graphite server, so I had tried the same approach using the Metrics library, and as a result, I ended up doing a finagle module called finagle-metrics.

So let’s see how to use it! :)

First things first. So, let’s install the finagle-metrics locally. To do that, just run:

git clone https://github.com/rlazoti/finagle-metrics.git
cd finagle-metrics
git checkout tags/version-0.0.1 -b version-0.0.1
sbt publish-local

After that you should see something like this output:

[info]  published finagle-metrics_2.11 to /Users/rodrigolazoti/.ivy2/local/com.github.rlazoti/finagle-metrics_2.11/0.0.1/poms/finagle-metrics_2.11.pom
[info]  published finagle-metrics_2.11 to /Users/rodrigolazoti/.ivy2/local/com.github.rlazoti/finagle-metrics_2.11/0.0.1/jars/finagle-metrics_2.11.jar
[info]  published finagle-metrics_2.11 to /Users/rodrigolazoti/.ivy2/local/com.github.rlazoti/finagle-metrics_2.11/0.0.1/srcs/finagle-metrics_2.11-sources.jar
[info]  published finagle-metrics_2.11 to /Users/rodrigolazoti/.ivy2/local/com.github.rlazoti/finagle-metrics_2.11/0.0.1/docs/finagle-metrics_2.11-javadoc.jar
[info]  published ivy to /Users/rodrigolazoti/.ivy2/local/com.github.rlazoti/finagle-metrics_2.11/0.0.1/ivys/ivy.xml
[success] Total time: 16 s, completed Jan 7, 2015 10:15:30 PM

Okay, the finagle-metris is now installed locally, so from now on we can add it as a dependency to our finagle application. We need to create some folders and files, so let’s do that:

mkdir -p finagle-example/src/main/scala/
cd finagle-example
touch build.sbt
touch src/main/scala/App.scala

Then I’m going to add the following content to build.sbt:

name := "finagle-example"

version := "0.0.1-SNAPSHOT"

scalaVersion := "2.11.4"

libraryDependencies ++= Seq(
  "com.twitter"        %% "twitter-server"  % "1.9.0",
  "com.github.rlazoti" %% "finagle-metrics" % "0.0.1"
)

And finally, let’s create our finagle application. I’m gonna add the following content to /src/main/scala/App.scala:

import com.codahale.metrics.ConsoleReporter
import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.metrics.MetricsStatsReceiver
import com.twitter.io.Charsets
import com.twitter.server.TwitterServer
import com.twitter.util.{Await, Future}
import org.jboss.netty.buffer.ChannelBuffers.copiedBuffer
import org.jboss.netty.handler.codec.http._
import java.util.concurrent.TimeUnit

object App extends TwitterServer {

  val service = new Service[HttpRequest, HttpResponse] {
    def apply(request: HttpRequest) = {
      val response = new DefaultHttpResponse(request.getProtocolVersion, HttpResponseStatus.OK)
      response.setContent(copiedBuffer("hello", Charsets.Utf8))
      Future.value(response)
    }
  }

  val reporter = ConsoleReporter
    .forRegistry(MetricsStatsReceiver.metrics)
    .convertRatesTo(TimeUnit.SECONDS)
    .convertDurationsTo(TimeUnit.MILLISECONDS)
    .build

  def main() {
    val server = Http.serve(":8080", service)
    reporter.start(5, TimeUnit.SECONDS)

    onExit {
      server.close()
    }

    Await.ready(server)
  }

}

Note that I used the ConsoleReporter to report the Codahale’s metrics to the console every five seconds.

Also, note that I didn’t need to do anything related to the finagle-metrics, I just needed to define a location (Reporter) to where the Codahale metrics will be sent, but the metrics themselves were sent automatically (Thanks Finagle for that). :)

To run our example, just execute the following command and wait a few seconds to see the metrics being displayed on the console:

sbt 'run-main App'

Click here to see more about the finagle-metrics library.


comments powered by Disqus