diff --git a/build.sbt b/build.sbt index 82c859d..359d63a 100644 --- a/build.sbt +++ b/build.sbt @@ -328,6 +328,8 @@ lazy val server = (project in file("server")) ) ++ javacRelease17, libraryDependencies ++= Seq( "com.linecorp.armeria" % "armeria" % "1.28.4", + // Prometheus registry for armeria's MetricCollectingService + /metrics exposition. + "io.micrometer" % "micrometer-registry-prometheus" % "1.12.4", "org.apache.commons" % "commons-lang3" % "3.19.0", // Netty dependencies diff --git a/server/src/main/java/io/unitycatalog/server/UnityCatalogServer.java b/server/src/main/java/io/unitycatalog/server/UnityCatalogServer.java index 923c3f9..cd7b697 100644 --- a/server/src/main/java/io/unitycatalog/server/UnityCatalogServer.java +++ b/server/src/main/java/io/unitycatalog/server/UnityCatalogServer.java @@ -8,11 +8,16 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.json.JsonMapper; import com.linecorp.armeria.common.HttpResponse; +import com.linecorp.armeria.common.metric.MeterIdPrefixFunction; +import com.linecorp.armeria.common.metric.PrometheusMeterRegistries; import com.linecorp.armeria.server.Server; import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.annotation.JacksonRequestConverterFunction; import com.linecorp.armeria.server.annotation.JacksonResponseConverterFunction; import com.linecorp.armeria.server.docs.DocService; +import com.linecorp.armeria.server.metric.MetricCollectingService; +import com.linecorp.armeria.server.metric.PrometheusExpositionService; +import io.micrometer.prometheus.PrometheusMeterRegistry; import io.unitycatalog.server.auth.AllowingAuthorizer; import io.unitycatalog.server.auth.JCasbinAuthorizer; import io.unitycatalog.server.auth.UnityCatalogAuthorizer; @@ -99,9 +104,19 @@ private void setDefaults(UnityCatalogServer.Builder unityCatalogServerBuilder) { } private Server initializeServer(UnityCatalogServer.Builder unityCatalogServerBuilder) { + // Expose Prometheus metrics at /metrics so per-route request counts (e.g. + // credential vending) are scrapeable. MetricCollectingService records every + // route; PrometheusExpositionService serves the registry. + PrometheusMeterRegistry meterRegistry = PrometheusMeterRegistries.newRegistry(); ServerBuilder armeriaServerBuilder = Server.builder() .http(unityCatalogServerBuilder.port) + .meterRegistry(meterRegistry) + .decorator( + MetricCollectingService.newDecorator( + MeterIdPrefixFunction.ofDefault("armeria.server"))) + .service( + "/metrics", PrometheusExpositionService.of(meterRegistry.getPrometheusRegistry())) .serviceUnder("/docs", new DocService()); // Init hibernate