listnplay / riversong   0.4.0

MIT License GitHub

Common base for microservices

Scala versions: 2.11


Common base for microservices:

How to use


To include it in your project add "com.featurefm" %% "river-song" % "0.3.11" and "com.softwaremill.macwire" %% "macros" % "2.2.2" % "provided" Only Scala 2.11 is currently supported.


trait AllMyServices extends ServiceAssembly {
  //construct necessary objects, some of them will be implementations of BaseRouting
  //routes should built from all routes provided by instances of BaseRouting that you want to expose

  lazy val serviceA = wire[MyService]
  lazy val serviceB = wire[AnotherService]
  lazy val serviceC = wire[YetAnotherService]
  val wired: Wired = wiredInModule(assembly)
  override def services = wired.lookup(classOf[RiverSongRouting])
  wired.lookup(classOf[HealthCheck]) foreach Health().addCheck



object GeronimoService extends MainService("Geronimo") with App {
  override def assembly: ServiceAssembly = new ServiceAssembly with AllMyServices

Run GeronimoService, by default it will start HTTP server on port 8080. Services that wish to expose routes need to implement RiverSongRouting. Services that wish to expose health information should implement interface. If you want public methods automatically timed, use TimerInterceptor like this:

lazy val serviceA = time(wire[MyService])

Host and port of the server are controlled by configuration:

akka {
  http.server {
    listen_ip : ""
    listen_port: 8080

What do you get out of the box

GET / returns uptime and number of requests

GET /status returns 200 if server is up

GET /metrics?jvm={true|false}&pattern={metrics-key-regex}

GET /config and GET /config/{path}

GET /health which will become more meaningful if you register application sub-components by extending

Periodic reporters for Slf4j, StatsD, InfluxDb and DataDog.

Requests are logged (unless you turn it off in configuration). Example output:

2016-01-04T15:47:57,320 INFO  [...] ActorSystemImpl - GET /status ~> 200 OK [8ms]

Instrumented trait to help you report custom metrics (time and timeEventually for synchronous code and Futures respectively are especially useful), BaseRouting trait for metrics and routing utilities. See LifecycleRouting class for some examples.

For Actors, it is recommended to implement InstrumentedActor, it will protect you from gauge collisions when Actor is restarted and will automatically count restarts. The framework also automatically counts dead letters.




Heavily inspired by