sbt Example: Play

Below is an example for how to configure Cinnamon for Play metrics with sbt.

Note: Cinnamon supports Play 2.6 and greater.

Background

When developing Play applications it is very convenient to use Play’s development run command. However, because of the way the run command is implemented it is not possible to use Lightbend Telemetry in combination with this command. Instead, you have to build the Play application as a distribution and run that - more information about this here below.

Prerequisites

The following must be installed for these instructions to work:

Bintray credentials

To gain access to Lightbend Telemetry you must have a Lightbend subscription and Lightbend account.

Once you have logged in, the Lightbend platform credentials guide contains instructions for configuring your sbt, maven or gradle project to access Lightbend’s commercial dependencies, including Telemetry. If you have previously used a username and password to configure your Bintray credentials, the guide will instruct you how to update to using the new scheme.

Note: The URLs generated as part of your Lightbend platform credentials should not be committed to public source control repositories.

If you do not have a Lightbend subscription, please contact us to request an evaluation.

Configuration

Start off by adding the Cinnamon sbt plugin to the project/plugins.sbt file:

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.5")

addSbtPlugin("com.lightbend.cinnamon" % "sbt-cinnamon" % "2.14.2")

The next step is to amend the build.sbt to contain Cinnamon:

lazy val root = (project in file(".")).enablePlugins(PlayScala, Cinnamon)

// Generate your Lightbend commercial sbt resolvers at:
//   https://www.lightbend.com/account/lightbend-platform/credentials

libraryDependencies ++= Seq(
  Cinnamon.library.cinnamonCHMetrics, // only needed to use the Console reporter
  Cinnamon.library.cinnamonPlay
)

Finally, you should ensure that you have a configuration file (conf/application.conf) that instructs Cinnamon on how to instrument Play. The example below enables all available Play metrics and logs output using the Console reporter:

cinnamon.application = "hello-play-telemetry"

cinnamon.play.http {

  // Create server metrics for all servers and all paths
  servers {
    "*:*" {
      paths {
        "*" {
          metrics = on
        }
      }
    }
  }

  // Create client metrics for all servers and all paths
  clients {
    "*:*" {
      paths {
        "*" {
          metrics = on
        }
      }
    }
  }
}

cinnamon.chmetrics {
  reporters += console-reporter
}

Running

When you have configured your Play application in accordance with the instructions here above you can run it, but as previously explained you cannot use sbt run with the Cinnamon Agent. We still urge you to use the run command during development of the Play application. This is one of the things that make Play a true development friendly environment. When you want to test your application with telemetry you can do so with this command:

sbt runProd

Note: The command above fails if configuration for play.http.secret.key is missing. See more details in Play documentation.

The output should look something like this:

[info] Loading settings for project global-plugins from sbt-updates.sbt,plugins.sbt,sbt-eclipse.sbt ...

...

(Starting server. Type Ctrl+D to exit logs, the server will remain in background)

[INFO] [02/24/2020 12:25:53.915] [Cinnamon] Agent version 2.13.2

...

2020-02-24 12:25:56 INFO  play.api.Play  Application started (Prod) (no global state)
[INFO] [02/24/2020 12:25:56.466] [Cinnamon] Agent found Akka HTTP version: 10.1.11
2020-02-24 12:25:57 INFO  play.core.server.AkkaHttpServer  Listening for HTTP on /0:0:0:0:0:0:0:0:9000
2/24/20, 12:26:00 PM ===========================================================

-- Gauges ----------------------------------------------------------------------
metrics.akka.systems.application.dispatchers.akka_actor_default-dispatcher.active-threads
             value = 10
metrics.akka.systems.application.dispatchers.akka_actor_default-dispatcher.parallelism
             value = 12
metrics.akka.systems.application.dispatchers.akka_actor_default-dispatcher.pool-size
             value = 12
metrics.akka.systems.application.dispatchers.akka_actor_default-dispatcher.queued-tasks
             value = 0
metrics.akka.systems.application.dispatchers.akka_actor_default-dispatcher.running-threads
             value = 9
metrics.akka.systems.application.dispatchers.akka_actor_internal-dispatcher.active-threads
             value = 0
metrics.akka.systems.application.dispatchers.akka_actor_internal-dispatcher.parallelism
             value = 12
metrics.akka.systems.application.dispatchers.akka_actor_internal-dispatcher.pool-size
             value = 12
metrics.akka.systems.application.dispatchers.akka_actor_internal-dispatcher.queued-tasks
             value = 0
metrics.akka.systems.application.dispatchers.akka_actor_internal-dispatcher.running-threads
             value = 0
metrics.akka.systems.application.dispatchers.akka_io_pinned-dispatcher.active-threads
             value = 1
metrics.akka.systems.application.dispatchers.akka_io_pinned-dispatcher.pool-size
             value = 1
metrics.akka.systems.application.dispatchers.akka_io_pinned-dispatcher.running-threads
             value = 0
metrics.cinnamon.play.2_8_0.agent.2_13_2.java.11_0_6.scala.2_13_1.akka.2_6_1.versions
             value = 1

-- Histograms ------------------------------------------------------------------
metrics.akka-http.systems.application.http-servers.127_0_0_1_9000.request-methods.GET.request-paths._.endpoint-response-time
             count = 18420
               min = 215399
               max = 121857543
...

Play configuration

The Play metrics can be configured to a detailed level. See the Play metrics configuration for more details.