sbt Example: Akka

Here are instructions for how to take a sample application and add telemetry to it for sbt. In this example you will add Cinnamon and a Coda Hale Console reporter will be used to print telemetry output to the terminal window.

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.

Sample application

We are going to use a Hello World example that illustrates Lightbend Telemetry basics. Within 30 minutes, you should be able to download and run the example and use this guide to understand how the example is constructed. This will get your feet wet, and hopefully inspire you to dive deeper into Lightbend Telemetry!

The example for Scala includes a distribution of sbt (build tool). You can run it on Linux, MacOS, or Windows.

  1. Download the zip file from Lightbend Tech Hub by clicking CREATE A PROJECT FOR ME.
  2. Extract the zip file to a convenient location:
    • On Linux and OSX systems, open a terminal and use the command unzip akka-quickstart-scala.zip. Note: On OSX, if you unzip using Archiver, you also have to make the sbt files executable:

    chmod u+x ./sbt
    chmod u+x ./sbt-dist/bin/sbt
    
    • On Windows, use a tool such as File Explorer to extract the project.

Running the example

To run Hello World:

  1. In a console, change directories to the top level of the unzipped project.

    For example, if you used the default project name, akka-quickstart-scala, and extracted the project to your root directory, from the root directory, enter: cd akka-quickstart-scala

  2. Enter ./sbt on OSX/Linux or sbt.bat on Windows to start sbt.

    sbt downloads project dependencies. The > prompt indicates sbt has started in interactive mode.

  3. At the sbt prompt, enter reStart.

    sbt builds the project and runs Hello World

The output should look something like this (scroll all the way to the right to see the Actor output):

...

[info] Starting application akka-quickstart-scala in the background ...
akka-quickstart-scala Starting com.example.AkkaQuickstart.main()
[success] Total time: 3 s, completed Feb. 18, 2020, 5:39:54 p.m.

...

akka-quickstart-scala [2020-02-18 17:39:54,977] [INFO] [com.example.Greeter$] [AkkaQuickStart-akka.actor.default-dispatcher-5] [akka://AkkaQuickStart/user/greeter] - Hello Charles!
akka-quickstart-scala [2020-02-18 17:39:54,978] [INFO] [com.example.GreeterBot$] [AkkaQuickStart-akka.actor.default-dispatcher-5] [akka://AkkaQuickStart/user/Charles] - Greeting 1 for Charles
akka-quickstart-scala [2020-02-18 17:39:54,978] [INFO] [com.example.Greeter$] [AkkaQuickStart-akka.actor.default-dispatcher-3] [akka://AkkaQuickStart/user/greeter] - Hello Charles!
akka-quickstart-scala [2020-02-18 17:39:54,979] [INFO] [com.example.GreeterBot$] [AkkaQuickStart-akka.actor.default-dispatcher-5] [akka://AkkaQuickStart/user/Charles] - Greeting 2 for Charles
akka-quickstart-scala [2020-02-18 17:39:54,979] [INFO] [com.example.Greeter$] [AkkaQuickStart-akka.actor.default-dispatcher-3] [akka://AkkaQuickStart/user/greeter] - Hello Charles!
akka-quickstart-scala [2020-02-18 17:39:54,979] [INFO] [com.example.GreeterBot$] [AkkaQuickStart-akka.actor.default-dispatcher-5] [akka://AkkaQuickStart/user/Charles] - Greeting 3 for Charles

Congratulations, you just ran your first Akka app. Now lets make some changes to add Lightbend Telemetry to our project.

Modifications

The modifications below are required to enable Lightbend Telemetry.

project/plugins.sbt

Lightbend Telemetry has a convenient sbt plugin that makes it easy to add the Cinnamon Java Agent to your build. Add the following plugin to your project/plugins.sbt file:

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

build.sbt

Open the file build.sbt and make it look this way:

// Enable the Lightbend Telemetry (Cinnamon) sbt plugin
lazy val helloAkka = project in file(".") enablePlugins(Cinnamon)

// Add the Cinnamon Agent for run and test
cinnamon in run := true
cinnamon in test := true

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

name := "akka-quickstart-scala"

version := "1.0"

scalaVersion := "2.12.11"

mainClass := Some("com.example.AkkaQuickstart")

lazy val akkaVersion = "2.6.4"

libraryDependencies ++= Seq(
  // Use Coda Hale Metrics and Akka instrumentation
  Cinnamon.library.cinnamonCHMetrics,
  Cinnamon.library.cinnamonAkkaTyped,
  "com.typesafe.akka" %% "akka-actor-typed" % akkaVersion,
  "ch.qos.logback" % "logback-classic" % "1.2.3",
  "com.typesafe.akka" %% "akka-actor-testkit-typed" % akkaVersion % Test,
  "org.scalatest" %% "scalatest" % "3.1.0" % Test
)

Note: Please note that the Scala and Akka versions may vary. Lightbend Telemetry currently supports Akka versions 2.5.x and 2.6.x.

application.conf

Add a application.conf file to the folder src/main/resources with the following content:

cinnamon.application = "hello-akka"

cinnamon.akka {
  actors {
    "/user/*" {
      # DISCLAIMER: In a real application, it will be better to tag the actors
      # so that will be easier to make sense of the metrics. But since this is
      # just a sample, we are using `instance` to keep it simple.
      # See the following page for more information:
      report-by = instance
    }
  }
}

cinnamon.chmetrics {
  reporters += "console-reporter"
}

Running

When you have modified the files above you simply use sbt to run the application:

./sbt run

The output should look something like this:

...
[info] [2020-02-18 17:49:40,568] [INFO] [com.example.Greeter$] [AkkaQuickStart-akka.actor.default-dispatcher-5] [akka://AkkaQuickStart/user/greeter] - Hello Charles!
[info] [2020-02-18 17:49:40,569] [INFO] [com.example.GreeterBot$] [AkkaQuickStart-akka.actor.default-dispatcher-3] [akka://AkkaQuickStart/user/Charles] - Greeting 1 for Charles
[info] [2020-02-18 17:49:40,569] [INFO] [com.example.Greeter$] [AkkaQuickStart-akka.actor.default-dispatcher-5] [akka://AkkaQuickStart/user/greeter] - Hello Charles!
[info] [2020-02-18 17:49:40,569] [INFO] [com.example.GreeterBot$] [AkkaQuickStart-akka.actor.default-dispatcher-3] [akka://AkkaQuickStart/user/Charles] - Greeting 2 for Charles
[info] [2020-02-18 17:49:40,570] [INFO] [com.example.Greeter$] [AkkaQuickStart-akka.actor.default-dispatcher-5] [akka://AkkaQuickStart/user/greeter] - Hello Charles!
[info] [2020-02-18 17:49:40,570] [INFO] [com.example.GreeterBot$] [AkkaQuickStart-akka.actor.default-dispatcher-3] [akka://AkkaQuickStart/user/Charles] - Greeting 3 for Charles
[info] 2/18/20 5:49:45 PM =============================================================
[info] -- Gauges ----------------------------------------------------------------------
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_default-dispatcher.active-threads
[info]              value = 0
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_default-dispatcher.parallelism
[info]              value = 12
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_default-dispatcher.pool-size
[info]              value = 2
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_default-dispatcher.queued-tasks
[info]              value = 0
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_default-dispatcher.running-threads
[info]              value = 0
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_internal-dispatcher.active-threads
[info]              value = 0
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_internal-dispatcher.parallelism
[info]              value = 12
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_internal-dispatcher.pool-size
[info]              value = 2
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_internal-dispatcher.queued-tasks
[info]              value = 0
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_internal-dispatcher.running-threads
[info]              value = 0
[info] metrics.cinnamon.agent.2_13_2.java.1_8_0_242.scala.2_13_1.akka.2_6_3.versions
[info]              value = 1
[info] -- Counters --------------------------------------------------------------------
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_default-dispatcher.actors.akka_actor_typed_internal_adapter_ActorAdapter.running-actors
[info]              count = 1
[info] -- Histograms ------------------------------------------------------------------
[info] metrics.akka.systems.AkkaQuickStart.dispatchers.akka_actor_default-dispatcher.actors.akka_actor_typed_internal_adapter_ActorAdapter.mailbox-size
[info]              count = 2
[info]                min = 1
[info]                max = 1
...

That is how easy it is to get started! You can find more information about configuration, plugins, etc. in the rest of this documentation.