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.

Official sample

See a comprehensive sample application using Akka, sbt, and Akka Insights here: https://github.com/lightbend/telemetry-samples/tree/master/akka/shopping-cart-scala.

Prerequisites

The following must be installed for these instructions to work:

Commercial credentials

To gain access to Akka Insights 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 commercial 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 Akka Insights 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 Akka Insights!

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 Akka Insights to our project.

Modifications

The modifications below are required to enable Akka Insights.

project/plugins.sbt

Akka Insights 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.20.3")

build.sbt

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

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

// Add the Cinnamon Agent for run and test
run / cinnamon := true
test / cinnamon := 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.13.13"

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

resolvers += "Akka library repository".at("https://repo.akka.io/maven")

lazy val akkaVersion = "2.9.5"

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
)

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/*" {
      # WARNING: 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:
      # https://developer.lightbend.com/docs/telemetry/current/instrumentations/akka/actors-typed.html
      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.