diff --git a/pom.xml b/pom.xml index be8ef9bb..8dd7fba9 100644 --- a/pom.xml +++ b/pom.xml @@ -216,6 +216,11 @@ spring-boot-starter-actuator runtime + + io.micrometer + micrometer-registry-prometheus + runtime + diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisObserver.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisObserver.java new file mode 100644 index 00000000..bec01632 --- /dev/null +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisObserver.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2023, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.gridsuite.sensitivityanalysis.server.service; + +import io.micrometer.observation.Observation; +import io.micrometer.observation.ObservationRegistry; +import lombok.NonNull; +import org.springframework.stereotype.Service; + +/** + * @author Florent MILLOT + */ +@Service +public class SensitivityAnalysisObserver { + + private final ObservationRegistry observationRegistry; + + private static final String OBSERVATION_PREFIX = "app.sensitivity.analysis."; + private static final String PROVIDER_TAG_NAME = "provider"; + + public SensitivityAnalysisObserver(@NonNull ObservationRegistry observationRegistry) { + this.observationRegistry = observationRegistry; + } + + public void observe(String name, SensitivityAnalysisRunContext runContext, Observation.CheckedRunnable callable) throws E { + createSensitivityAnalysisObservation(name, runContext).observeChecked(callable); + } + + public T observe(String name, SensitivityAnalysisRunContext runContext, Observation.CheckedCallable callable) throws E { + return createSensitivityAnalysisObservation(name, runContext).observeChecked(callable); + } + + private Observation createSensitivityAnalysisObservation(String name, SensitivityAnalysisRunContext runContext) { + return Observation.createNotStarted(OBSERVATION_PREFIX + name, observationRegistry) + .lowCardinalityKeyValue(PROVIDER_TAG_NAME, runContext.getProvider()); + } +} diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisWorkerService.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisWorkerService.java index ffd9e069..4820e72b 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisWorkerService.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisWorkerService.java @@ -74,13 +74,16 @@ public class SensitivityAnalysisWorkerService { private final SensitivityAnalysisInputBuilderService sensitivityAnalysisInputBuilderService; + private final SensitivityAnalysisObserver sensitivityAnalysisObserver; + private Function sensitivityAnalysisFactorySupplier; public SensitivityAnalysisWorkerService(NetworkStoreService networkStoreService, ReportService reportService, NotificationService notificationService, SensitivityAnalysisInputBuilderService sensitivityAnalysisInputBuilderService, SensitivityAnalysisExecutionService sensitivityAnalysisExecutionService, SensitivityAnalysisResultRepository resultRepository, ObjectMapper objectMapper, - SensitivityAnalysisRunnerSupplier sensitivityAnalysisRunnerSupplier) { + SensitivityAnalysisRunnerSupplier sensitivityAnalysisRunnerSupplier, + SensitivityAnalysisObserver sensitivityAnalysisObserver) { this.networkStoreService = Objects.requireNonNull(networkStoreService); this.reportService = Objects.requireNonNull(reportService); this.notificationService = notificationService; @@ -89,6 +92,7 @@ public SensitivityAnalysisWorkerService(NetworkStoreService networkStoreService, this.resultRepository = Objects.requireNonNull(resultRepository); this.objectMapper = Objects.requireNonNull(objectMapper); sensitivityAnalysisFactorySupplier = sensitivityAnalysisRunnerSupplier::getRunner; + this.sensitivityAnalysisObserver = sensitivityAnalysisObserver; } public void setSensitivityAnalysisFactorySupplier(Function sensitivityAnalysisFactorySupplier) { @@ -119,29 +123,31 @@ public SensitivityAnalysisResult run(SensitivityAnalysisRunContext context) { } } - private SensitivityAnalysisResult run(SensitivityAnalysisRunContext context, UUID resultUuid) throws ExecutionException, InterruptedException { + private SensitivityAnalysisResult run(SensitivityAnalysisRunContext context, UUID resultUuid) throws Exception { Objects.requireNonNull(context); LOGGER.info("Run sensitivity analysis"); SensitivityAnalysis.Runner sensitivityAnalysisRunner = sensitivityAnalysisFactorySupplier.apply(context.getProvider()); - Reporter rootReporter = Reporter.NO_OP; + AtomicReference rootReporter = new AtomicReference<>(Reporter.NO_OP); Reporter reporter = Reporter.NO_OP; if (context.getReportUuid() != null) { final String reportType = context.getReportType(); String rootReporterId = context.getReporterId() == null ? reportType : context.getReporterId() + "@" + reportType; - rootReporter = new ReporterModel(rootReporterId, rootReporterId); - reporter = rootReporter.createSubReporter(reportType, reportType + " (${providerToUse})", "providerToUse", sensitivityAnalysisRunner.getName()); + rootReporter.set(new ReporterModel(rootReporterId, rootReporterId)); + reporter = rootReporter.get().createSubReporter(reportType, reportType + " (${providerToUse})", "providerToUse", sensitivityAnalysisRunner.getName()); // Delete any previous sensi computation logs - reportService.deleteReport(context.getReportUuid(), reportType); + sensitivityAnalysisObserver.observe("report.delete", context, () -> + reportService.deleteReport(context.getReportUuid(), reportType)); } CompletableFuture future = runSensitivityAnalysisAsync(context, sensitivityAnalysisRunner, reporter, resultUuid); - SensitivityAnalysisResult result = future == null ? null : future.get(); + SensitivityAnalysisResult result = future == null ? null : sensitivityAnalysisObserver.observe("run", context, () -> future.get()); if (context.getReportUuid() != null) { - reportService.sendReport(context.getReportUuid(), rootReporter); + sensitivityAnalysisObserver.observe("report.send", context, () -> + reportService.sendReport(context.getReportUuid(), rootReporter.get())); } return result; } @@ -172,7 +178,8 @@ private CompletableFuture runSensitivityAnalysisAsync return null; } SensitivityAnalysisParameters sensitivityAnalysisParameters = buildParameters(context); - Network network = getNetwork(context.getNetworkUuid(), context.getVariantId()); + Network network = sensitivityAnalysisObserver.observe("network.load", context, () -> + getNetwork(context.getNetworkUuid(), context.getVariantId())); sensitivityAnalysisInputBuilderService.build(context, network, reporter); CompletableFuture future = sensitivityAnalysisRunner.runAsync( @@ -228,7 +235,8 @@ public Consumer> consumeRun() { long nanoTime = System.nanoTime(); LOGGER.info("Just run in {}s", TimeUnit.NANOSECONDS.toSeconds(nanoTime - startTime.getAndSet(nanoTime))); - resultRepository.insert(resultContext.getResultUuid(), result, SensitivityAnalysisStatus.COMPLETED.name()); + sensitivityAnalysisObserver.observe("results.save", resultContext.getRunContext(), () -> + resultRepository.insert(resultContext.getResultUuid(), result, SensitivityAnalysisStatus.COMPLETED.name())); long finalNanoTime = System.nanoTime(); LOGGER.info("Stored in {}s", TimeUnit.NANOSECONDS.toSeconds(finalNanoTime - startTime.getAndSet(finalNanoTime))); diff --git a/src/main/resources/application-local.yaml b/src/main/resources/application-local.yaml index 0622fca9..874effde 100644 --- a/src/main/resources/application-local.yaml +++ b/src/main/resources/application-local.yaml @@ -22,4 +22,13 @@ gridsuite: base-uri: http://localhost:5027 report-server: base-uri: http://localhost:5028 - \ No newline at end of file + +management: + metrics: + distribution: + percentiles-histogram: + http.server.requests: true + endpoints: + web: + exposure: + include: prometheus, health, info \ No newline at end of file