Il y a 9 ans -
Temps de lecture 2 minutes
Monitorer ses requêtes Spray
Dans le cadre de l’un de nos développements, nous avons mis en place une application basée sur Scala, Akka et Spray afin de communiquer avec une autre application.
Nous avons rapidement eu le besoin de monitorer les requêtes échangées entre ces deux applications. Pour cela Spray fournit un module de statistique. Dans cet article, nous allons voir sa mise en place.
1. Configuration
Voici les dépendances à importer avec SBT :
"io.spray" % "spray-can" % "1.3.1", "io.spray" % "spray-http" % "1.3.1", "io.spray" % "spray-httpx" % "1.3.1", "io.spray" % "spray-routing" % "1.3.1"
Précision, nous utilisons Scala 2.10.
Pourquoi quatre dépendances me direz vous ? Tout simplement parce que Spray est découpé assez finement :
- Les objets concernant les statistiques sont présents dans spray-can
- Les "path" se retrouvent dans spray-routing
- Le support du Json avec Spray est dans spray-httpx
- Les media types sont dans spray-http
Nous devons activer les statistiques de Spray dans notre fichier application.conf :
spray.can { server { stats-support = on } }
2. Utilisation
Nous allons créer un acteur qui va se charger d’afficher les statistiques :
class RestServiceActor extends RestService { implicit def actorRefFactory = ActorSystem("myApp") override def receiveActor = runRoute(rest) }
trait RestService extends HttpService with spray.httpx.SprayJsonSupport { val actorListener: ActorSelection = actorRefFactory.actorSelection("/user/IO-HTTP/listener-0") val rest = respondWithMediaType(MediaTypes.`application/json`) { path("stats") { import JsonStats._ get { complete { actorListener.ask(Http.GetStats)(1.second).mapTo[Stats] } } } } }
Quelques explications :
- Nous utilisons la fonction runRoute de Spray qui exécute le endpoint passé en paramètre. La fonction rest fait référence à celle définie dans le trait RestService.
- Nous voulons retourner le résultat sous le format JSON
- Nous retrouvons l’acteur HTTP listener sur lequel nous allons récupérer les statistiques (actorRefFactory.actorSelection("/user/IO-HTTP/listener-0"))
- Nous demandons à cet acteur les statistiques ask(Http.GetStats) et effectuons un mapping sur l’objet Stats
Afin d’effectuer le mapping au format JSON, nous devons définir et importer l’objet JsonStats. Il définit des implicits permettant d’effectuer cette transformation.
object JsonStats extends Json4sSupport { implicit def json4sFormats: Formats = DefaultFormats implicit val statsMarshaller = json4sMarshaller[Stats] }
Nous avons choisi d’utiliser la librairie json4s suivante :
"org.json4s" %% "json4s-native" % "3.2.9"
Cette dernière nous permet notamment d’utiliser la classe DefaultFormats afin de sérialiser et déserialiser nos objets.
Il ne reste plus qu’à lancer l’application et saisir l’url suivante : http://localhost:8080/stats
Nous avons alors accès aux statistiques suivantes :
{ "uptime": { "length": 12556219319, "unit": {} }, "totalRequests": 2, "openRequests": 1, "maxOpenRequests": 1, "totalConnections": 2, "openConnections": 2, "maxOpenConnections": 2, "requestTimeouts": 0 }
Il devient alors simple d’effectuer du monitoring et du tunning sur nos requêtes.
Commentaire