From 3dbd5a3a742ad4d998764d39dcdaf07a4a0791cd Mon Sep 17 00:00:00 2001 From: joffrey-bion Date: Mon, 15 Feb 2021 23:40:55 +0100 Subject: Add basic metrics --- .../server/controllers/AutoGameController.kt | 26 ++++++++++++++-------- .../server/controllers/GameController.kt | 14 +++++++++--- .../server/controllers/HomeController.kt | 4 +++- .../server/controllers/LobbyController.kt | 6 +++++ .../sevenwonders/server/metrics/MetricsUtils.kt | 13 +++++++++++ .../server/repositories/LobbyRepository.kt | 8 ++++--- .../server/repositories/PlayerRepository.kt | 8 ++++--- 7 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 sw-server/src/main/kotlin/org/luxons/sevenwonders/server/metrics/MetricsUtils.kt (limited to 'sw-server/src/main/kotlin/org/luxons') diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/AutoGameController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/AutoGameController.kt index 796dc719..a4aceb96 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/AutoGameController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/AutoGameController.kt @@ -1,5 +1,6 @@ package org.luxons.sevenwonders.server.controllers +import io.micrometer.core.instrument.MeterRegistry import kotlinx.coroutines.withTimeout import org.luxons.sevenwonders.bot.connectBot import org.luxons.sevenwonders.bot.connectBots @@ -12,7 +13,9 @@ import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RestController import java.security.Principal +import kotlin.time.measureTimedValue import kotlin.time.minutes +import kotlin.time.toJavaDuration /** * Handles actions in the game's lobby. The lobby is the place where players gather before a game. @@ -20,6 +23,7 @@ import kotlin.time.minutes @RestController class AutoGameController( @Value("\${server.port}") private val serverPort: String, + private val meterRegistry: MeterRegistry, ) { @PostMapping("/autoGame") suspend fun autoGame(@RequestBody action: AutoGameAction, principal: Principal): AutoGameResult { @@ -28,16 +32,20 @@ class AutoGameController( val serverUrl = "ws://localhost:$serverPort" val lastTurn = withTimeout(5.minutes) { - val otherBotNames = List(action.nbPlayers - 1) { "JoinerBot${it + 1}" } - val owner = client.connectBot(serverUrl, "OwnerBot", action.config) - val joiners = client.connectBots(serverUrl, otherBotNames, action.config) + val (lastTurn, duration) = measureTimedValue { + val otherBotNames = List(action.nbPlayers - 1) { "JoinerBot${it + 1}" } + val owner = client.connectBot(serverUrl, "OwnerBot", action.config) + val joiners = client.connectBots(serverUrl, otherBotNames, action.config) - owner.createGameWithBotFriendsAndAutoPlay( - gameName = action.gameName, - otherBots = joiners, - customWonders = action.customWonders, - customSettings = action.customSettings, - ) + owner.createGameWithBotFriendsAndAutoPlay( + gameName = action.gameName, + otherBots = joiners, + customWonders = action.customWonders, + customSettings = action.customSettings, + ) + } + meterRegistry.timer("autogame.duration").record(duration.toJavaDuration()) + lastTurn } val scoreBoard = lastTurn.scoreBoard ?: error("Last turn info doesn't have scoreboard") diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt index 47e01876..cff3aea0 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt @@ -1,5 +1,6 @@ package org.luxons.sevenwonders.server.controllers +import io.micrometer.core.instrument.MeterRegistry import org.luxons.sevenwonders.engine.Game import org.luxons.sevenwonders.model.api.GameListEvent import org.luxons.sevenwonders.model.api.actions.PrepareMoveAction @@ -7,6 +8,7 @@ import org.luxons.sevenwonders.model.api.wrap import org.luxons.sevenwonders.model.cards.PreparedCard import org.luxons.sevenwonders.model.hideHandsAndWaitForReadiness import org.luxons.sevenwonders.server.api.toDTO +import org.luxons.sevenwonders.server.lobby.Lobby import org.luxons.sevenwonders.server.lobby.Player import org.luxons.sevenwonders.server.repositories.LobbyRepository import org.luxons.sevenwonders.server.repositories.PlayerRepository @@ -24,6 +26,7 @@ class GameController( private val template: SimpMessagingTemplate, private val playerRepository: PlayerRepository, private val lobbyRepository: LobbyRepository, + private val meterRegistry: MeterRegistry, ) { private val Principal.player get() = playerRepository.get(name) @@ -99,9 +102,7 @@ class GameController( game.playTurn() sendTurnInfo(player.lobby.getPlayers(), game, hideHands = lobby.settings.askForReadiness) if (game.endOfGameReached()) { - logger.info("Game {}: end of game, displaying score board", game.id) - player.lobby.setEndOfGame() - template.convertAndSend("/topic/games", GameListEvent.CreateOrUpdate(lobby.toDTO()).wrap()) + handleEndOfGame(game, player, lobby) } } else { template.convertAndSendToUser(player.username, "/queue/game/preparedMove", action.move) @@ -109,6 +110,13 @@ class GameController( } } + private fun handleEndOfGame(game: Game, player: Player, lobby: Lobby) { + meterRegistry.counter("games.finished").increment() + logger.info("Game {}: end of game, displaying score board", game.id) + player.lobby.setEndOfGame() + template.convertAndSend("/topic/games", GameListEvent.CreateOrUpdate(lobby.toDTO()).wrap()) + } + @MessageMapping("/game/unprepareMove") fun unprepareMove(principal: Principal) { val player = principal.player diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/HomeController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/HomeController.kt index b2fc122a..230623d8 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/HomeController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/HomeController.kt @@ -1,5 +1,6 @@ package org.luxons.sevenwonders.server.controllers +import io.micrometer.core.instrument.MeterRegistry import org.luxons.sevenwonders.model.api.ConnectedPlayer import org.luxons.sevenwonders.model.api.PlayerDTO import org.luxons.sevenwonders.model.api.actions.ChooseNameAction @@ -17,8 +18,8 @@ import java.security.Principal @Controller class HomeController( private val playerRepository: PlayerRepository, + private val meterRegistry: MeterRegistry, ) { - /** * Creates/updates the player's name (for the user's session). * @@ -33,6 +34,7 @@ class HomeController( val username = principal.name val player = playerRepository.createOrUpdate(username, action.playerName, action.isHuman, action.icon) + meterRegistry.counter("players.connections").increment() logger.info("Player '{}' chose the name '{}'", username, player.displayName) return ConnectedPlayer(username, player.displayName, player.isHuman, player.icon) } diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt index 2edf7fee..70ac50e7 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt @@ -1,5 +1,6 @@ package org.luxons.sevenwonders.server.controllers +import io.micrometer.core.instrument.MeterRegistry import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -16,6 +17,7 @@ import org.luxons.sevenwonders.model.hideHandsAndWaitForReadiness import org.luxons.sevenwonders.server.api.toDTO import org.luxons.sevenwonders.server.lobby.Lobby import org.luxons.sevenwonders.server.lobby.Player +import org.luxons.sevenwonders.server.metrics.playerCountsTags import org.luxons.sevenwonders.server.repositories.LobbyRepository import org.luxons.sevenwonders.server.repositories.PlayerRepository import org.slf4j.LoggerFactory @@ -36,6 +38,7 @@ class LobbyController( private val playerRepository: PlayerRepository, private val template: SimpMessagingTemplate, @Value("\${server.port}") private val serverPort: String, + private val meterRegistry: MeterRegistry, ) { private val Principal.player: Player get() = playerRepository.get(name) @@ -80,6 +83,7 @@ class LobbyController( } logger.info("Player {} disbanded game '{}'", player, lobby.name) deleteLobby(lobby) + meterRegistry.counter("games.disbanded", lobby.playerCountsTags()).increment() } } @@ -163,6 +167,7 @@ class LobbyController( val timeoutDuration = action.globalBotTimeoutMillis.milliseconds logger.error("Bot {} timed out after {}", action.botDisplayName, timeoutDuration) bot.disconnect() + meterRegistry.counter("bot.timeout", lobby.playerCountsTags()).increment() } } } @@ -177,6 +182,7 @@ class LobbyController( val lobby = principal.player.ownedLobby val game = lobby.startGame() + meterRegistry.counter("games.started").increment() logger.info("Game {} ('{}') successfully started", game.id, lobby.name) val currentTurnInfo = game.getCurrentTurnInfo().let { if (lobby.settings.askForReadiness) it.hideHandsAndWaitForReadiness() else it diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/metrics/MetricsUtils.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/metrics/MetricsUtils.kt new file mode 100644 index 00000000..6b91428e --- /dev/null +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/metrics/MetricsUtils.kt @@ -0,0 +1,13 @@ +package org.luxons.sevenwonders.server.metrics + +import io.micrometer.core.instrument.Tag +import org.luxons.sevenwonders.server.lobby.Lobby + +fun Lobby.playerCountsTags(): List { + val players = getPlayers() + return listOf( + Tag.of("nPlayers", players.size.toString()), + Tag.of("nHumans", players.filter { it.isHuman }.size.toString()), + Tag.of("nBots", players.filterNot { it.isHuman }.size.toString()), + ) +} diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/LobbyRepository.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/LobbyRepository.kt index e45fb5e9..5b32c514 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/LobbyRepository.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/LobbyRepository.kt @@ -1,5 +1,6 @@ package org.luxons.sevenwonders.server.repositories +import io.micrometer.core.instrument.MeterRegistry import org.luxons.sevenwonders.engine.data.GameDefinition import org.luxons.sevenwonders.server.lobby.Lobby import org.luxons.sevenwonders.server.lobby.Player @@ -8,9 +9,10 @@ import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicLong @Repository -class LobbyRepository { - - private val lobbies = ConcurrentHashMap() +class LobbyRepository( + meterRegistry: MeterRegistry, +) { + private val lobbies = meterRegistry.gaugeMapSize("games.count", emptyList(), ConcurrentHashMap())!! private var lastGameId: AtomicLong = AtomicLong(0) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/PlayerRepository.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/PlayerRepository.kt index d2d8f967..d1d5b211 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/PlayerRepository.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/PlayerRepository.kt @@ -1,5 +1,6 @@ package org.luxons.sevenwonders.server.repositories +import io.micrometer.core.instrument.MeterRegistry import org.luxons.sevenwonders.model.api.actions.Icon import org.luxons.sevenwonders.server.ApiMisuseException import org.luxons.sevenwonders.server.lobby.Player @@ -7,9 +8,10 @@ import org.springframework.stereotype.Repository import java.util.concurrent.ConcurrentHashMap @Repository -class PlayerRepository { - - private val players = ConcurrentHashMap() +class PlayerRepository( + meterRegistry: MeterRegistry, +) { + private val players = meterRegistry.gaugeMapSize("players.count", emptyList(), ConcurrentHashMap())!! operator fun contains(username: String): Boolean = players.containsKey(username) -- cgit