diff --git a/src/main/scala/Monitor.scala b/src/main/scala/Monitor.scala index 194509fa..4547ea21 100644 --- a/src/main/scala/Monitor.scala +++ b/src/main/scala/Monitor.scala @@ -136,6 +136,27 @@ object Monitor: def roundFrameLag(millis: Int) = if millis > 1 && millis < 99999 then frameLagHistogram.record(millis.toLong, TimeUnit.MILLISECONDS) + object mobile: + private val Regex = """Lichess Mobile/(\S+) \(\d*\) as:(\S+) sri:\S+ os:(Android|iOS)/(\S+).*""".r + private val counter = Kamon.counter("mobile.connect") + def connect(req: util.RequestHeader) = if req.isLichessMobile then + req.userAgent match + case Regex(version, user, osName, osVersion) => + counter + .withTags( + TagSet.from( + Map( + "version" -> version, + "osName" -> osName, + "osVersion" -> osVersion, + "auth" -> (if user == "anon" then "anon" else "auth"), + "route" -> req.path.drop(1).takeWhile('/' !=) + ) + ) + ) + .increment() + case _ => () + def time[A](metric: Monitor.type => kamon.metric.Timer)(f: => A): A = val timer = metric(Monitor).start() val res = f diff --git a/src/main/scala/netty/RequestHandler.scala b/src/main/scala/netty/RequestHandler.scala index 3ce6c63c..2b3f7882 100644 --- a/src/main/scala/netty/RequestHandler.scala +++ b/src/main/scala/netty/RequestHandler.scala @@ -18,7 +18,8 @@ final private class RequestHandler(router: Router)(using Executor) ): override def channelRead0(ctx: ChannelHandlerContext, req: FullHttpRequest): Unit = - router(util.RequestHeader(RequestUri(req.uri), req.headers)) foreach: + val request = util.RequestHeader(RequestUri(req.uri), req.headers) + router(request) foreach: case Left(status) => sendErrorResponse( ctx, @@ -35,6 +36,7 @@ final private class RequestHandler(router: Router)(using Executor) sendErrorResponse(ctx, response) req.release() case Right(endpoint) => + Monitor.mobile.connect(request) // Forward to ProtocolHandler with endpoint attribute ctx.channel.attr(ProtocolHandler.key.endpoint).set(endpoint) ctx.fireChannelRead(req)