From 10b4c377033f12fafc517673fb1ca665716d383a Mon Sep 17 00:00:00 2001 From: homedirectory Date: Mon, 9 Jun 2025 13:54:04 +0300 Subject: [PATCH 01/13] #2445 Set platform version to 2.1.0-SNAPSHOT --- platform-annotation-processors/pom.xml | 2 +- platform-annotations/pom.xml | 2 +- platform-benchmark/pom.xml | 2 +- platform-dao/pom.xml | 2 +- platform-db-evolution/pom.xml | 2 +- platform-eql-grammar/pom.xml | 2 +- platform-pojo-bl/pom.xml | 2 +- platform-web-resources/pom.xml | 2 +- platform-web-ui/pom.xml | 2 +- pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/platform-annotation-processors/pom.xml b/platform-annotation-processors/pom.xml index b0a2c291f84..c98964a2ae1 100644 --- a/platform-annotation-processors/pom.xml +++ b/platform-annotation-processors/pom.xml @@ -4,7 +4,7 @@ fielden platform-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT platform-annotation-processors diff --git a/platform-annotations/pom.xml b/platform-annotations/pom.xml index 2753d7d4c6f..16e0edd7c5f 100644 --- a/platform-annotations/pom.xml +++ b/platform-annotations/pom.xml @@ -3,7 +3,7 @@ fielden platform-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT platform-annotations diff --git a/platform-benchmark/pom.xml b/platform-benchmark/pom.xml index b438f01e0f2..8ae336e2542 100644 --- a/platform-benchmark/pom.xml +++ b/platform-benchmark/pom.xml @@ -6,7 +6,7 @@ fielden platform-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT Trident Genesis Platform Microbenckmarks diff --git a/platform-dao/pom.xml b/platform-dao/pom.xml index e6ddd055b76..c4d9c16e1c9 100644 --- a/platform-dao/pom.xml +++ b/platform-dao/pom.xml @@ -3,7 +3,7 @@ fielden platform-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT platform-dao diff --git a/platform-db-evolution/pom.xml b/platform-db-evolution/pom.xml index c1954261cf1..7bfc657548c 100644 --- a/platform-db-evolution/pom.xml +++ b/platform-db-evolution/pom.xml @@ -3,7 +3,7 @@ fielden platform-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT platform-db-evolution diff --git a/platform-eql-grammar/pom.xml b/platform-eql-grammar/pom.xml index 411b3c51b99..3feb3c135ee 100644 --- a/platform-eql-grammar/pom.xml +++ b/platform-eql-grammar/pom.xml @@ -6,7 +6,7 @@ fielden platform-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT platform-eql-grammar diff --git a/platform-pojo-bl/pom.xml b/platform-pojo-bl/pom.xml index a8d84d1fb45..728c20912be 100644 --- a/platform-pojo-bl/pom.xml +++ b/platform-pojo-bl/pom.xml @@ -3,7 +3,7 @@ fielden platform-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT platform-pojo-bl diff --git a/platform-web-resources/pom.xml b/platform-web-resources/pom.xml index d34f256a7c7..ee2a63da951 100644 --- a/platform-web-resources/pom.xml +++ b/platform-web-resources/pom.xml @@ -5,7 +5,7 @@ fielden platform-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT platform-web-resources diff --git a/platform-web-ui/pom.xml b/platform-web-ui/pom.xml index 328bfd37e51..6ba8fd9ab89 100644 --- a/platform-web-ui/pom.xml +++ b/platform-web-ui/pom.xml @@ -3,7 +3,7 @@ fielden platform-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT platform-web-ui diff --git a/pom.xml b/pom.xml index 587efbaab98..0027088f728 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ fielden platform-parent pom - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT Trident Genesis Platform Parent Trident Genesis is a software application platform designed for development of EAM/ERP type applications. From 8d18feef001e80cefd6ba7c0769c0a7e2b3a4b7e Mon Sep 17 00:00:00 2001 From: homedirectory Date: Mon, 9 Jun 2025 13:10:02 +0300 Subject: [PATCH 02/13] #2445 Introduce Maven module platform-metrics and its submodule platform-metrics-core --- .../platform-metrics-core/pom.xml | 35 ++++++++++++++++ platform-metrics/pom.xml | 42 +++++++++++++++++++ pom.xml | 1 + 3 files changed, 78 insertions(+) create mode 100644 platform-metrics/platform-metrics-core/pom.xml create mode 100644 platform-metrics/pom.xml diff --git a/platform-metrics/platform-metrics-core/pom.xml b/platform-metrics/platform-metrics-core/pom.xml new file mode 100644 index 00000000000..8d0dbe0bc70 --- /dev/null +++ b/platform-metrics/platform-metrics-core/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + + fielden + platform-metrics + 2.1.0-SNAPSHOT + + + Trident Genesis Platform Metrics Core + platform-metrics-core + jar + + The core metrics module. + + + + + + fielden + platform-pojo-bl + ${project.version} + + + + io.micrometer + micrometer-registry-prometheus + + + + + diff --git a/platform-metrics/pom.xml b/platform-metrics/pom.xml new file mode 100644 index 00000000000..b0fa64ccdc6 --- /dev/null +++ b/platform-metrics/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + + fielden + platform-parent + 2.1.0-SNAPSHOT + + + Trident Genesis Platform Metrics + platform-metrics + pom + + This module represents the metrics system. + + This module is a part of TG application observability and monitoring. + + + + platform-metrics-core + + + + 1.15.0 + + + + + + io.micrometer + micrometer-bom + ${micrometer.version} + pom + import + + + + + diff --git a/pom.xml b/pom.xml index 0027088f728..9251fb5b4e8 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,7 @@ platform-web-ui platform-benchmark platform-eql-grammar + platform-metrics From 97db2bf317fc6ff78d278499687b02b4a523b3c7 Mon Sep 17 00:00:00 2001 From: homedirectory Date: Mon, 9 Jun 2025 13:48:10 +0300 Subject: [PATCH 03/13] #2445 Basic IoC modules for the metrics system --- .../metrics/CommonMetricsIocModule.java | 34 +++++++++++++++++++ .../metrics/MetricsCoreIocModule.java | 17 ++++++++++ 2 files changed, 51 insertions(+) create mode 100644 platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/CommonMetricsIocModule.java create mode 100644 platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/CommonMetricsIocModule.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/CommonMetricsIocModule.java new file mode 100644 index 00000000000..f95c8f22843 --- /dev/null +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/CommonMetricsIocModule.java @@ -0,0 +1,34 @@ +package fielden.platform.metrics; + +import com.google.inject.Inject; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; +import io.micrometer.core.instrument.binder.system.ProcessorMetrics; +import io.micrometer.core.instrument.binder.system.UptimeMetrics; +import ua.com.fielden.platform.ioc.AbstractPlatformIocModule; + +/// This IoC module registers all built-in meters. +/// +/// [MetricsCoreIocModule] is a required dependency. +/// +public final class CommonMetricsIocModule extends AbstractPlatformIocModule { + + @Override + protected void configure() { + requestStaticInjection(CommonMetricsIocModule.class); + } + + @Inject + static void registerMetrics(final MeterRegistry meterRegistry) { + new ClassLoaderMetrics().bindTo(meterRegistry); + new JvmGcMetrics().bindTo(meterRegistry); + new JvmMemoryMetrics().bindTo(meterRegistry); + new JvmThreadMetrics().bindTo(meterRegistry); + new ProcessorMetrics().bindTo(meterRegistry); + new UptimeMetrics().bindTo(meterRegistry); + } + +} diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java new file mode 100644 index 00000000000..985737e9a9f --- /dev/null +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java @@ -0,0 +1,17 @@ +package fielden.platform.metrics; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.prometheusmetrics.PrometheusConfig; +import io.micrometer.prometheusmetrics.PrometheusMeterRegistry; +import ua.com.fielden.platform.ioc.AbstractPlatformIocModule; + +/// Core IoC module for the metrics system. +/// +public final class MetricsCoreIocModule extends AbstractPlatformIocModule { + + @Override + protected void configure() { + bind(MeterRegistry.class).toInstance(new PrometheusMeterRegistry(PrometheusConfig.DEFAULT)); + } + +} From 08e02bba83312119ead0f6cabfa2358fc113805b Mon Sep 17 00:00:00 2001 From: homedirectory Date: Mon, 9 Jun 2025 15:54:22 +0300 Subject: [PATCH 04/13] #2445 Introduce Maven module platform-metrics-web-server --- .../platform-metrics-web-server/pom.xml | 37 +++++++++++++++++++ platform-metrics/pom.xml | 1 + 2 files changed, 38 insertions(+) create mode 100644 platform-metrics/platform-metrics-web-server/pom.xml diff --git a/platform-metrics/platform-metrics-web-server/pom.xml b/platform-metrics/platform-metrics-web-server/pom.xml new file mode 100644 index 00000000000..5a4c5856aa8 --- /dev/null +++ b/platform-metrics/platform-metrics-web-server/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + + fielden + platform-metrics + 2.1.0-SNAPSHOT + + + Trident Genesis Platform Metrics (Web Server) + platform-metrics-web-server + jar + + This module provides metrics for web servers. + + + + + + fielden + platform-metrics-core + ${project.version} + + + + org.restlet + org.restlet + 2.5.1 + + + + + + diff --git a/platform-metrics/pom.xml b/platform-metrics/pom.xml index b0fa64ccdc6..81fa9dcac09 100644 --- a/platform-metrics/pom.xml +++ b/platform-metrics/pom.xml @@ -21,6 +21,7 @@ platform-metrics-core + platform-metrics-web-server From a46422d98fb110a2f0943cdd3b230a6c5695bf5f Mon Sep 17 00:00:00 2001 From: homedirectory Date: Mon, 9 Jun 2025 15:54:44 +0300 Subject: [PATCH 05/13] #2445 Extract Restlet version into a Maven property --- platform-metrics/platform-metrics-web-server/pom.xml | 2 +- platform-web-resources/pom.xml | 1 - pom.xml | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform-metrics/platform-metrics-web-server/pom.xml b/platform-metrics/platform-metrics-web-server/pom.xml index 5a4c5856aa8..a75c46b5abe 100644 --- a/platform-metrics/platform-metrics-web-server/pom.xml +++ b/platform-metrics/platform-metrics-web-server/pom.xml @@ -28,7 +28,7 @@ org.restlet org.restlet - 2.5.1 + ${restlet.version} diff --git a/platform-web-resources/pom.xml b/platform-web-resources/pom.xml index ee2a63da951..ff06c4de4fb 100644 --- a/platform-web-resources/pom.xml +++ b/platform-web-resources/pom.xml @@ -13,7 +13,6 @@ Trident Genesis Platform Web Resources - 2.5.1 9.4.57.v20241219 diff --git a/pom.xml b/pom.xml index 9251fb5b4e8..82b301cfa96 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,7 @@ 6.3.0 1.13.0 4.13.2 + 2.5.1 From 815c9b4404198a0e1152ee648719ec3aa7a05aef Mon Sep 17 00:00:00 2001 From: homedirectory Date: Mon, 9 Jun 2025 17:43:51 +0300 Subject: [PATCH 06/13] #2445 A Restlet filter to capture metrics for HTTP requests --- .../metrics/web_server/MetricsFilter.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java new file mode 100644 index 00000000000..4da3f4e273a --- /dev/null +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java @@ -0,0 +1,55 @@ +package fielden.platform.metrics.web_server; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Timer; +import jakarta.inject.Inject; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.routing.Filter; + +/// Executes around a request, capturing metrics. +/// +public class MetricsFilter extends Filter { + + private static final Logger LOGGER = LogManager.getLogger(); + private static final String WARN_ERROR_IN_METRICS = "Suppressed an error that occured in the metrics subsystem."; + + private final MeterRegistry meterRegistry; + + @Inject + private MetricsFilter(final MeterRegistry meterRegistry) { + this.meterRegistry = meterRegistry; + } + + @Override + protected int doHandle(final Request request, final Response response) { + // Do not let errors that pertain to metrics inerrupt processing of the request. + + Timer.Sample sample; + try { + sample = Timer.start(meterRegistry); + } catch (final Exception ex) { + LOGGER.warn(WARN_ERROR_IN_METRICS, ex); + sample = null; + } + + final var result = super.doHandle(request, response); + + if (sample != null) { + try { + final var timer = meterRegistry.timer("http.server.request", + "path", request.getOriginalRef().getPath(), + "method", request.getMethod().getName(), + "status", String.valueOf(response.getStatus().getCode())); + sample.stop(timer); + } catch (final Exception ex) { + LOGGER.warn(WARN_ERROR_IN_METRICS, ex); + } + } + + return result; + } + +} From 2cb35233e4e8e87cb8a697eac18fd7c595160891 Mon Sep 17 00:00:00 2001 From: homedirectory Date: Tue, 10 Jun 2025 09:51:14 +0300 Subject: [PATCH 07/13] #2445 Web resource for metrics --- .../platform-metrics-web-server/pom.xml | 6 +++ .../metrics/web_server/MetricsResource.java | 53 ++++++++++++++++++ .../web_server/MetricsResourceFactory.java | 54 +++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResource.java create mode 100644 platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResourceFactory.java diff --git a/platform-metrics/platform-metrics-web-server/pom.xml b/platform-metrics/platform-metrics-web-server/pom.xml index a75c46b5abe..b0241330aac 100644 --- a/platform-metrics/platform-metrics-web-server/pom.xml +++ b/platform-metrics/platform-metrics-web-server/pom.xml @@ -25,6 +25,12 @@ ${project.version} + + fielden + platform-web-resources + ${project.version} + + org.restlet org.restlet diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResource.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResource.java new file mode 100644 index 00000000000..2b8e1cc6572 --- /dev/null +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResource.java @@ -0,0 +1,53 @@ +package fielden.platform.metrics.web_server; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.prometheusmetrics.PrometheusMeterRegistry; +import org.restlet.Context; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.data.MediaType; +import org.restlet.representation.Representation; +import org.restlet.representation.StringRepresentation; +import org.restlet.resource.Get; +import ua.com.fielden.platform.utils.IDates; +import ua.com.fielden.platform.web.interfaces.IDeviceProvider; +import ua.com.fielden.platform.web.resources.RestServerUtil; +import ua.com.fielden.platform.web.resources.webui.AbstractWebResource; + +import static ua.com.fielden.platform.web.utils.WebUiResourceUtils.handleUndesiredExceptions; + +/// Provides metrics in the OpenMetrics format. +/// +/// Requires the [MeterRegistry] to be a [PrometheusMeterRegistry]. +/// +public class MetricsResource extends AbstractWebResource { + + private static final String CONTENT_TYPE_OPENMETRICS = "application/openmetrics-text"; + private static final MediaType MEDIA_TYPE_OPENMETRICS = MediaType.valueOf(CONTENT_TYPE_OPENMETRICS); + + private final RestServerUtil restUtil; + private final PrometheusMeterRegistry meterRegistry; + + MetricsResource( + final IDeviceProvider deviceProvider, + final IDates dates, + final Context context, + final Request request, + final Response response, + final PrometheusMeterRegistry meterRegistry, + final RestServerUtil restUtil) + { + super(context, request, response, deviceProvider, dates); + this.restUtil = restUtil; + this.meterRegistry = meterRegistry; + } + + @Get + public Representation metrics() { + return handleUndesiredExceptions(getResponse(), () -> { + final var data = meterRegistry.scrape(CONTENT_TYPE_OPENMETRICS); + return new StringRepresentation(data, MEDIA_TYPE_OPENMETRICS); + }, restUtil); + } + +} diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResourceFactory.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResourceFactory.java new file mode 100644 index 00000000000..4698e0fc17a --- /dev/null +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResourceFactory.java @@ -0,0 +1,54 @@ +package fielden.platform.metrics.web_server; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.prometheusmetrics.PrometheusMeterRegistry; +import jakarta.inject.Inject; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.Restlet; +import org.restlet.data.Method; +import ua.com.fielden.platform.entity.exceptions.InvalidArgumentException; +import ua.com.fielden.platform.utils.IDates; +import ua.com.fielden.platform.web.interfaces.IDeviceProvider; +import ua.com.fielden.platform.web.resources.RestServerUtil; + +/// Factory for [MetricsResource]. +/// +public class MetricsResourceFactory extends Restlet { + + private final RestServerUtil restUtil; + private final IDeviceProvider deviceProvider; + private final IDates dates; + private final PrometheusMeterRegistry meterRegistry; + + @Inject + private MetricsResourceFactory( + final RestServerUtil restUtil, + final IDeviceProvider deviceProvider, + final IDates dates, + final MeterRegistry meterRegistry) + { + this.restUtil = restUtil; + this.deviceProvider = deviceProvider; + this.dates = dates; + if (meterRegistry instanceof PrometheusMeterRegistry it) { + this.meterRegistry = it; + } + else { + throw new InvalidArgumentException("%s must be a %s, but was %s.".formatted( + MeterRegistry.class.getSimpleName(), PrometheusMeterRegistry.class.getSimpleName(), meterRegistry.getClass().getCanonicalName())); + } + } + + @Override + public void handle(final Request request, final Response response) { + super.handle(request, response); + + if (Method.GET.equals(request.getMethod())) { + new MetricsResource(deviceProvider, dates, getContext(), request, response, + meterRegistry, restUtil) + .handle(); + } + } + +} From 58de6d7c75f136cb164d01c6ab2467bc79d70a1b Mon Sep 17 00:00:00 2001 From: homedirectory Date: Tue, 10 Jun 2025 12:12:14 +0300 Subject: [PATCH 08/13] #2445 Authentication for the metrics resource --- .../MetricsAuthenticationIocModule.java | 32 ++++++++++++++ .../web_server/MetricsAuthenticator.java | 42 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java create mode 100644 platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticator.java diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java new file mode 100644 index 00000000000..54ec39dbfb2 --- /dev/null +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java @@ -0,0 +1,32 @@ +package fielden.platform.metrics.web_server; + +import com.google.inject.Provides; +import com.google.inject.name.Named; +import ua.com.fielden.platform.basic.config.exceptions.ApplicationConfigurationException; +import ua.com.fielden.platform.ioc.AbstractPlatformIocModule; + +/// Configures authentication for the metrics web resource. +/// +/// Applications that use [MetricsResourceFactory] must install this module. +/// +/// ### Bindings +/// +/// * [#TG_METRICS_API_KEY] -- must be specified as a System property or an environment variable. +/// +public class MetricsAuthenticationIocModule extends AbstractPlatformIocModule { + + /// Name of a binding for the API key. + /// + public static final String TG_METRICS_API_KEY = "tg.metrics.apiKey"; + + @Provides + @Named(TG_METRICS_API_KEY) + String apiKey() { + final var value = System.getProperty(TG_METRICS_API_KEY, System.getenv(TG_METRICS_API_KEY)); + if (value == null) { + throw new ApplicationConfigurationException("%s is missing.".formatted(TG_METRICS_API_KEY)); + } + return value; + } + +} diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticator.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticator.java new file mode 100644 index 00000000000..d6da5597389 --- /dev/null +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticator.java @@ -0,0 +1,42 @@ +package fielden.platform.metrics.web_server; + +import jakarta.inject.Inject; +import jakarta.inject.Named; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.data.Status; +import org.restlet.security.Authenticator; + +import javax.annotation.Nullable; + +import static fielden.platform.metrics.web_server.MetricsAuthenticationIocModule.TG_METRICS_API_KEY; + +/// Implements authentication for the metrics resource. +/// +/// For a request to be authenticated, it must contain header [#API_KEY_HEADER] that specifies a valid [API key][MetricsAuthenticationIocModule#TG_METRICS_API_KEY]. +/// +public class MetricsAuthenticator extends Authenticator { + + private static final String API_KEY_HEADER = "X-API-Key"; + + private final String apiKey; + + @Inject + private MetricsAuthenticator(final @Named(TG_METRICS_API_KEY) String apiKey) { + super(null); // Context is not used by this class + this.apiKey = apiKey; + } + + @Override + protected boolean authenticate(final Request request, final Response response) { + final @Nullable var requestApiKey = request.getHeaders().getFirstValue(API_KEY_HEADER, true); + if (!apiKey.equals(requestApiKey)) { + response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED); + return false; + } + else { + return true; + } + } + +} From 5f3699e08ed0bb8c70b8528fd2012443446881b1 Mon Sep 17 00:00:00 2001 From: homedirectory Date: Tue, 10 Jun 2025 13:02:31 +0300 Subject: [PATCH 09/13] #2445 Initial support for metrics configuration --- .../platform/metrics/MetricsConfig.java | 28 +++++++++++++++++++ .../metrics/MetricsCoreIocModule.java | 27 ++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java new file mode 100644 index 00000000000..601859e652b --- /dev/null +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java @@ -0,0 +1,28 @@ +package fielden.platform.metrics; + +import ua.com.fielden.platform.parser.IValueParser; + +import java.util.Properties; + +import static ua.com.fielden.platform.parser.IValueParser.enumIgnoreCaseParser; +import static ua.com.fielden.platform.parser.IValueParser.propertyParser; + +/// Configuration of the metrics system. +/// +/// @param mode optional (default: [Mode#DISABLED]). +/// +public record MetricsConfig (Mode mode) { + + public static final String PROPERTY_MODE = "metrics.mode"; + + public static MetricsConfig fromProperties(final Properties properties) { + final var mode = modeParser.apply(properties).getOrThrow(); + return new MetricsConfig(mode); + } + + public enum Mode { ENABLED, DISABLED } + + + private static final IValueParser modeParser = propertyParser(PROPERTY_MODE, enumIgnoreCaseParser(Mode.values()), Mode.DISABLED); + +} diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java index 985737e9a9f..17dc2096319 100644 --- a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java @@ -1,17 +1,44 @@ package fielden.platform.metrics; +import com.google.inject.Inject; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.prometheusmetrics.PrometheusConfig; import io.micrometer.prometheusmetrics.PrometheusMeterRegistry; +import org.apache.logging.log4j.Logger; import ua.com.fielden.platform.ioc.AbstractPlatformIocModule; +import java.util.Properties; + +import static org.apache.logging.log4j.LogManager.getLogger; + /// Core IoC module for the metrics system. /// +/// ### Bindings +/// +/// * [MeterRegistry]. +/// * [MetricsConfig] -- configuration is read from application properties. +/// public final class MetricsCoreIocModule extends AbstractPlatformIocModule { + private static final Logger LOGGER = getLogger(); + + private final Properties properties; + + public MetricsCoreIocModule(final Properties properties) { + this.properties = properties; + } + @Override protected void configure() { + requestStaticInjection(MetricsCoreIocModule.class); + bind(MeterRegistry.class).toInstance(new PrometheusMeterRegistry(PrometheusConfig.DEFAULT)); + bind(MetricsConfig.class).toInstance(MetricsConfig.fromProperties(properties)); + } + + @Inject + static void logMetricsConfig(final MetricsConfig metricsConfig) { + LOGGER.info("Metrics configuration: %s".formatted(metricsConfig)); } } From aeedc0790fa692096cf66700197753b8fd4cd276 Mon Sep 17 00:00:00 2001 From: homedirectory Date: Tue, 10 Jun 2025 15:33:29 +0300 Subject: [PATCH 10/13] #2445 Enhance the metrics API to handle the possibility of metrics being disabled --- .../metrics/CommonMetricsIocModule.java | 8 +++++- .../platform/metrics/MetricsConfig.java | 10 +++++++ .../metrics/MetricsCoreIocModule.java | 19 +++++++++++-- .../platform/metrics/MetricsException.java | 15 ++++++++++ .../MetricsAuthenticationIocModule.java | 25 ++++++++++++----- .../web_server/MetricsAuthenticator.java | 28 +++++++++++-------- .../metrics/web_server/MetricsFilter.java | 14 +++++++++- .../metrics/web_server/MetricsResource.java | 2 ++ .../web_server/MetricsResourceFactory.java | 9 +++++- 9 files changed, 107 insertions(+), 23 deletions(-) create mode 100644 platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsException.java diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/CommonMetricsIocModule.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/CommonMetricsIocModule.java index f95c8f22843..a8d0f80d2e1 100644 --- a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/CommonMetricsIocModule.java +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/CommonMetricsIocModule.java @@ -14,6 +14,8 @@ /// /// [MetricsCoreIocModule] is a required dependency. /// +/// If metrics are disabled, no meters will be registered. +/// public final class CommonMetricsIocModule extends AbstractPlatformIocModule { @Override @@ -22,7 +24,11 @@ protected void configure() { } @Inject - static void registerMetrics(final MeterRegistry meterRegistry) { + static void registerMetrics(final MetricsConfig config, final MeterRegistry meterRegistry) { + if (config.mode() == MetricsConfig.Mode.DISABLED) { + return; + } + new ClassLoaderMetrics().bindTo(meterRegistry); new JvmGcMetrics().bindTo(meterRegistry); new JvmMemoryMetrics().bindTo(meterRegistry); diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java index 601859e652b..552a1afe6e8 100644 --- a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java @@ -10,6 +10,7 @@ /// Configuration of the metrics system. /// /// @param mode optional (default: [Mode#DISABLED]). +/// All parts of the metrics API should document their behaviour with respect to the mode. /// public record MetricsConfig (Mode mode) { @@ -22,6 +23,15 @@ public static MetricsConfig fromProperties(final Properties properties) { public enum Mode { ENABLED, DISABLED } + public Mode assertMode(final Mode expected) { + if (!mode.equals(expected)) { + throw new MetricsException("Metrics mode must be [%s], but was [%s].".formatted(expected, mode)); + } + else { + return mode; + } + } + private static final IValueParser modeParser = propertyParser(PROPERTY_MODE, enumIgnoreCaseParser(Mode.values()), Mode.DISABLED); diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java index 17dc2096319..0aac47f3f7d 100644 --- a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java @@ -1,6 +1,7 @@ package fielden.platform.metrics; import com.google.inject.Inject; +import com.google.inject.Provides; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.prometheusmetrics.PrometheusConfig; import io.micrometer.prometheusmetrics.PrometheusMeterRegistry; @@ -15,7 +16,7 @@ /// /// ### Bindings /// -/// * [MeterRegistry]. +/// * [#meterRegistry(MetricsConfig)] /// * [MetricsConfig] -- configuration is read from application properties. /// public final class MetricsCoreIocModule extends AbstractPlatformIocModule { @@ -32,10 +33,24 @@ public MetricsCoreIocModule(final Properties properties) { protected void configure() { requestStaticInjection(MetricsCoreIocModule.class); - bind(MeterRegistry.class).toInstance(new PrometheusMeterRegistry(PrometheusConfig.DEFAULT)); bind(MetricsConfig.class).toInstance(MetricsConfig.fromProperties(properties)); } + /// If metrics are enabled, binds a [PrometheusMeterRegistry]. + /// Otherwise, binds a noop registry. + /// + @Provides + MeterRegistry meterRegistry(final MetricsConfig config) { + return switch (config.mode()) { + case ENABLED -> new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); + case DISABLED -> { + final var registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); + registry.close(); + yield registry; + } + }; + } + @Inject static void logMetricsConfig(final MetricsConfig metricsConfig) { LOGGER.info("Metrics configuration: %s".formatted(metricsConfig)); diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsException.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsException.java new file mode 100644 index 00000000000..6b5373fd8cb --- /dev/null +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsException.java @@ -0,0 +1,15 @@ +package fielden.platform.metrics; + +import ua.com.fielden.platform.exceptions.AbstractPlatformRuntimeException; + +public class MetricsException extends AbstractPlatformRuntimeException { + + public MetricsException(final String message) { + super(message); + } + + public MetricsException(final String message, final Throwable cause) { + super(message, cause); + } + +} diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java index 54ec39dbfb2..8df3dd8b6ec 100644 --- a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java @@ -2,16 +2,19 @@ import com.google.inject.Provides; import com.google.inject.name.Named; +import fielden.platform.metrics.MetricsConfig; import ua.com.fielden.platform.basic.config.exceptions.ApplicationConfigurationException; import ua.com.fielden.platform.ioc.AbstractPlatformIocModule; +import java.util.Optional; + /// Configures authentication for the metrics web resource. /// /// Applications that use [MetricsResourceFactory] must install this module. /// /// ### Bindings /// -/// * [#TG_METRICS_API_KEY] -- must be specified as a System property or an environment variable. +/// * [#apiKey(MetricsConfig)] /// public class MetricsAuthenticationIocModule extends AbstractPlatformIocModule { @@ -19,14 +22,22 @@ public class MetricsAuthenticationIocModule extends AbstractPlatformIocModule { /// public static final String TG_METRICS_API_KEY = "tg.metrics.apiKey"; + /// If metrics are enabled, an API key must be specified as a System property or an environment variable. + /// Otherwise, an empty optional will be bound. + /// @Provides @Named(TG_METRICS_API_KEY) - String apiKey() { - final var value = System.getProperty(TG_METRICS_API_KEY, System.getenv(TG_METRICS_API_KEY)); - if (value == null) { - throw new ApplicationConfigurationException("%s is missing.".formatted(TG_METRICS_API_KEY)); - } - return value; + Optional apiKey(final MetricsConfig config) { + return switch (config.mode()) { + case DISABLED -> Optional.empty(); + case ENABLED -> { + final var value = System.getProperty(TG_METRICS_API_KEY, System.getenv(TG_METRICS_API_KEY)); + if (value == null) { + throw new ApplicationConfigurationException("%s is missing.".formatted(TG_METRICS_API_KEY)); + } + yield Optional.of(value); + } + }; } } diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticator.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticator.java index d6da5597389..a3f43fd78d7 100644 --- a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticator.java +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticator.java @@ -8,6 +8,7 @@ import org.restlet.security.Authenticator; import javax.annotation.Nullable; +import java.util.Optional; import static fielden.platform.metrics.web_server.MetricsAuthenticationIocModule.TG_METRICS_API_KEY; @@ -15,28 +16,33 @@ /// /// For a request to be authenticated, it must contain header [#API_KEY_HEADER] that specifies a valid [API key][MetricsAuthenticationIocModule#TG_METRICS_API_KEY]. /// +/// If metrics are disabled, authentication will always fail. +/// public class MetricsAuthenticator extends Authenticator { private static final String API_KEY_HEADER = "X-API-Key"; - private final String apiKey; + private final Optional maybeApiKey; @Inject - private MetricsAuthenticator(final @Named(TG_METRICS_API_KEY) String apiKey) { + private MetricsAuthenticator(final @Named(TG_METRICS_API_KEY) Optional maybeApiKey) { super(null); // Context is not used by this class - this.apiKey = apiKey; + this.maybeApiKey = maybeApiKey; } @Override protected boolean authenticate(final Request request, final Response response) { - final @Nullable var requestApiKey = request.getHeaders().getFirstValue(API_KEY_HEADER, true); - if (!apiKey.equals(requestApiKey)) { - response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED); - return false; - } - else { - return true; - } + return maybeApiKey + .map(apiKey -> { + final @Nullable String requestApiKey = request.getHeaders().getFirstValue(API_KEY_HEADER, true); + return apiKey.equals(requestApiKey) || forbid(response); + }) + .orElseGet(() -> forbid(response)); + } + + private boolean forbid(final Response response) { + response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED); + return false; } } diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java index 4da3f4e273a..dfb69c68a81 100644 --- a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java @@ -1,5 +1,6 @@ package fielden.platform.metrics.web_server; +import fielden.platform.metrics.MetricsConfig; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Timer; import jakarta.inject.Inject; @@ -11,20 +12,31 @@ /// Executes around a request, capturing metrics. /// +/// If metrics are disabled, simply lets all requests through without capturing any metrics. +/// public class MetricsFilter extends Filter { private static final Logger LOGGER = LogManager.getLogger(); private static final String WARN_ERROR_IN_METRICS = "Suppressed an error that occured in the metrics subsystem."; private final MeterRegistry meterRegistry; + private final MetricsConfig metricsConfig; @Inject - private MetricsFilter(final MeterRegistry meterRegistry) { + private MetricsFilter(final MeterRegistry meterRegistry, final MetricsConfig metricsConfig) { this.meterRegistry = meterRegistry; + this.metricsConfig = metricsConfig; } @Override protected int doHandle(final Request request, final Response response) { + return switch (metricsConfig.mode()) { + case ENABLED -> doHandleWithMetrics(request, response); + case DISABLED -> super.doHandle(request, response); + }; + } + + private int doHandleWithMetrics(final Request request, final Response response) { // Do not let errors that pertain to metrics inerrupt processing of the request. Timer.Sample sample; diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResource.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResource.java index 2b8e1cc6572..1a288b78a65 100644 --- a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResource.java +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResource.java @@ -20,6 +20,8 @@ /// /// Requires the [MeterRegistry] to be a [PrometheusMeterRegistry]. /// +/// Metrics must be enabled for this class to be used. +/// public class MetricsResource extends AbstractWebResource { private static final String CONTENT_TYPE_OPENMETRICS = "application/openmetrics-text"; diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResourceFactory.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResourceFactory.java index 4698e0fc17a..5d137c73987 100644 --- a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResourceFactory.java +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsResourceFactory.java @@ -1,5 +1,6 @@ package fielden.platform.metrics.web_server; +import fielden.platform.metrics.MetricsConfig; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.prometheusmetrics.PrometheusMeterRegistry; import jakarta.inject.Inject; @@ -12,8 +13,12 @@ import ua.com.fielden.platform.web.interfaces.IDeviceProvider; import ua.com.fielden.platform.web.resources.RestServerUtil; +import static fielden.platform.metrics.MetricsConfig.Mode.ENABLED; + /// Factory for [MetricsResource]. /// +/// Metrics must be enabled for this class to be used. +/// public class MetricsResourceFactory extends Restlet { private final RestServerUtil restUtil; @@ -26,8 +31,10 @@ private MetricsResourceFactory( final RestServerUtil restUtil, final IDeviceProvider deviceProvider, final IDates dates, - final MeterRegistry meterRegistry) + final MeterRegistry meterRegistry, + final MetricsConfig metricsConfig) { + metricsConfig.assertMode(ENABLED); this.restUtil = restUtil; this.deviceProvider = deviceProvider; this.dates = dates; From 1d1f984eae2872566561dc7892484f2f148917af Mon Sep 17 00:00:00 2001 From: homedirectory Date: Tue, 10 Jun 2025 16:08:42 +0300 Subject: [PATCH 11/13] #2445 Use singleton scope for IoC bindings in metrics modules --- .../src/main/java/fielden/platform/metrics/MetricsConfig.java | 2 ++ .../java/fielden/platform/metrics/MetricsCoreIocModule.java | 2 ++ .../metrics/web_server/MetricsAuthenticationIocModule.java | 2 ++ 3 files changed, 6 insertions(+) diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java index 552a1afe6e8..6d603e8e2cd 100644 --- a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java @@ -1,5 +1,6 @@ package fielden.platform.metrics; +import jakarta.inject.Singleton; import ua.com.fielden.platform.parser.IValueParser; import java.util.Properties; @@ -12,6 +13,7 @@ /// @param mode optional (default: [Mode#DISABLED]). /// All parts of the metrics API should document their behaviour with respect to the mode. /// +@Singleton public record MetricsConfig (Mode mode) { public static final String PROPERTY_MODE = "metrics.mode"; diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java index 0aac47f3f7d..74d0c18f7c7 100644 --- a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsCoreIocModule.java @@ -5,6 +5,7 @@ import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.prometheusmetrics.PrometheusConfig; import io.micrometer.prometheusmetrics.PrometheusMeterRegistry; +import jakarta.inject.Singleton; import org.apache.logging.log4j.Logger; import ua.com.fielden.platform.ioc.AbstractPlatformIocModule; @@ -40,6 +41,7 @@ protected void configure() { /// Otherwise, binds a noop registry. /// @Provides + @Singleton MeterRegistry meterRegistry(final MetricsConfig config) { return switch (config.mode()) { case ENABLED -> new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java index 8df3dd8b6ec..277807c8dbb 100644 --- a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsAuthenticationIocModule.java @@ -3,6 +3,7 @@ import com.google.inject.Provides; import com.google.inject.name.Named; import fielden.platform.metrics.MetricsConfig; +import jakarta.inject.Singleton; import ua.com.fielden.platform.basic.config.exceptions.ApplicationConfigurationException; import ua.com.fielden.platform.ioc.AbstractPlatformIocModule; @@ -27,6 +28,7 @@ public class MetricsAuthenticationIocModule extends AbstractPlatformIocModule { /// @Provides @Named(TG_METRICS_API_KEY) + @Singleton Optional apiKey(final MetricsConfig config) { return switch (config.mode()) { case DISABLED -> Optional.empty(); From 164bd51e712d449adf7a015ba985acc1b9d9e6b2 Mon Sep 17 00:00:00 2001 From: homedirectory Date: Thu, 12 Jun 2025 18:36:14 +0300 Subject: [PATCH 12/13] #2445 Improve documentation of MetricsConfig --- .../src/main/java/fielden/platform/metrics/MetricsConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java index 6d603e8e2cd..b0c133a94f2 100644 --- a/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java +++ b/platform-metrics/platform-metrics-core/src/main/java/fielden/platform/metrics/MetricsConfig.java @@ -10,7 +10,8 @@ /// Configuration of the metrics system. /// -/// @param mode optional (default: [Mode#DISABLED]). +/// @param mode Optional (default: [Mode#DISABLED]). +/// Specified through application property [#PROPERTY_MODE], case-insensitive. /// All parts of the metrics API should document their behaviour with respect to the mode. /// @Singleton From a1cfe2619cb43523f372921fdd67d10e39032525 Mon Sep 17 00:00:00 2001 From: homedirectory Date: Thu, 12 Jun 2025 19:18:07 +0300 Subject: [PATCH 13/13] #2445 Document MetricsFilter with meter details --- .../platform/metrics/web_server/MetricsFilter.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java index dfb69c68a81..8f081186c07 100644 --- a/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java +++ b/platform-metrics/platform-metrics-web-server/src/main/java/fielden/platform/metrics/web_server/MetricsFilter.java @@ -14,6 +14,15 @@ /// /// If metrics are disabled, simply lets all requests through without capturing any metrics. /// +/// The following metrics are captured for each request: +/// +/// 1. * Name: `http.server.request` +/// * Type: [Timer] +/// * Tags: +/// * `path` -- the path component of a URI. +/// * `method` -- HTTP method name. +/// * `status` -- HTTP response status code. +/// public class MetricsFilter extends Filter { private static final Logger LOGGER = LogManager.getLogger();