DEV Community

Vigilmon
Vigilmon

Posted on

How to Monitor Your Scala Play Framework Application with Vigilmon

How to Monitor Your Scala Play Framework Application with Vigilmon

Play Framework is a reactive web framework for Scala (and Java) — built on Akka and used in high-traffic production systems. This guide shows how to add external uptime monitoring to any Play application with Vigilmon.

Step 1: Add a Health Endpoint to Play

Play uses a controller + route file pattern:

1. Create the health controller (app/controllers/HealthController.scala):

package controllers

import play.api.mvc._
import play.api.libs.json._
import javax.inject._
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class HealthController @Inject()(
  cc: ControllerComponents
)(implicit ec: ExecutionContext) extends AbstractController(cc) {

  def check: Action[AnyContent] = Action.async { implicit request =>
    Future.successful(
      Ok(Json.obj("status" -> "ok"))
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Add the route (conf/routes):

GET  /health  controllers.HealthController.check
Enter fullscreen mode Exit fullscreen mode

3. Test it:

curl http://localhost:9000/health
# {"status":"ok"}
Enter fullscreen mode Exit fullscreen mode

Step 2: Check Real Dependencies

For a health check that reflects actual service state:

package controllers

import play.api.mvc._
import play.api.libs.json._
import play.api.db.slick.DatabaseConfigProvider
import slick.jdbc.JdbcProfile
import javax.inject._
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Success, Failure}

@Singleton
class HealthController @Inject()(
  cc: ControllerComponents,
  dbConfigProvider: DatabaseConfigProvider
)(implicit ec: ExecutionContext) extends AbstractController(cc) {

  private val dbConfig = dbConfigProvider.get[JdbcProfile]
  import dbConfig._
  import profile.api._

  def check: Action[AnyContent] = Action.async {
    val dbCheck = db.run(sql"SELECT 1".as[Int]).transform {
      case Success(_) => Success(true)
      case Failure(_) => Success(false)
    }

    dbCheck.map { dbOk =>
      if (dbOk) {
        Ok(Json.obj("status" -> "ok", "database" -> "ok"))
      } else {
        ServiceUnavailable(Json.obj("status" -> "error", "database" -> "unreachable"))
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Exclude Health from Authentication Filters

Play uses filters that apply to all routes. If you have an auth filter, exclude the health route:

// app/filters/AuthFilter.scala
class AuthFilter @Inject()(implicit val mat: Materializer, ec: ExecutionContext) extends Filter {

  def apply(nextFilter: RequestHeader => Future[Result])
            (requestHeader: RequestHeader): Future[Result] = {
    // Skip auth for health endpoint
    if (requestHeader.path.startsWith("/health")) {
      nextFilter(requestHeader)
    } else {
      // Apply auth logic
      validateToken(requestHeader).flatMap {
        case true => nextFilter(requestHeader)
        case false => Future.successful(Unauthorized("Not authorized"))
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Play Configuration

Make sure your Play app binds to the right port in production:

# conf/application.conf
play.http.port=9000
play.server.http.port=9000

# Allow health endpoint without CSRF
play.filters.disabled += play.filters.csrf.CSRFFilter
# Or configure CSRF to exclude health
Enter fullscreen mode Exit fullscreen mode

Step 5: Connect to Vigilmon

  1. Sign up at vigilmon.online
  2. Add Monitor → HTTP Monitor
  3. URL: https://your-play-app.com/health
  4. Expected status: 200
  5. Optional content check: "status":"ok"
  6. Check interval: 60 seconds
  7. Alert channels: email or Slack

Play Framework with Docker

FROM eclipse-temurin:21-jdk AS builder
WORKDIR /app
COPY . .
RUN sbt dist
RUN unzip target/universal/*.zip -d target/universal/dist

FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=builder /app/target/universal/dist .

HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \n  CMD curl -f http://localhost:9000/health || exit 1

CMD ["./bin/your-app", "-Dplay.http.secret.key=${APP_SECRET}"]
Enter fullscreen mode Exit fullscreen mode

Summary

  1. Create a HealthController with a check action that returns Ok (200)
  2. Add GET /health controllers.HealthController.check to your routes
  3. Optionally check database/dependencies and return ServiceUnavailable (503) when unhealthy
  4. Exclude the health route from auth filters
  5. Connect to Vigilmon for external, multi-region monitoring

Play's reactive architecture handles high concurrency. Make sure you know the moment it stops handling requests.

Top comments (0)