From aca31dc9da3d66e13fb340c50875e24ef07e73c9 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Fri, 9 Apr 2021 19:05:04 +0300 Subject: [PATCH] Add prometheus integration (ref #294) --- dmp-backend/pom.xml | 32 +++++++ .../configurations/WebMVCConfiguration.java | 2 + .../main/java/eu/eudat/controllers/Admin.java | 6 ++ .../main/java/eu/eudat/controllers/Login.java | 4 + .../controllers/UserGuideController.java | 3 + .../managers/DataManagementPlanManager.java | 60 +++++++++++++ .../eudat/logic/managers/DatasetManager.java | 22 +++++ .../logic/managers/DatasetProfileManager.java | 26 ++++++ .../eudat/logic/managers/MetricsManager.java | 84 +++++++++++++++++++ .../config/application-devel.properties | 5 +- prometheus/config/prometheus.yml | 40 +++++++++ 11 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java create mode 100644 prometheus/config/prometheus.yml diff --git a/dmp-backend/pom.xml b/dmp-backend/pom.xml index 086bf9355..335884af1 100644 --- a/dmp-backend/pom.xml +++ b/dmp-backend/pom.xml @@ -225,6 +225,38 @@ 1.3.1 + + + io.prometheus + simpleclient + 0.10.0 + + + + io.prometheus + simpleclient_hotspot + 0.10.0 + + + + io.prometheus + simpleclient_httpserver + 0.10.0 + + + + io.prometheus + simpleclient_pushgateway + 0.10.0 + + + + + io.prometheus + simpleclient_spring_boot + 0.10.0 + + diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java index 36d9c502c..2c64aa8d1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java @@ -4,6 +4,7 @@ import eu.eudat.controllers.interceptors.RequestInterceptor; import eu.eudat.logic.handlers.PrincipalArgumentResolver; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.authentication.AuthenticationService; +import io.prometheus.client.spring.boot.EnablePrometheusEndpoint; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; @@ -17,6 +18,7 @@ import java.util.List; @EnableAsync @Configuration @EnableScheduling +@EnablePrometheusEndpoint public class WebMVCConfiguration extends WebMvcConfigurerAdapter { private ApiContext apiContext; diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java index 3894e9e3d..c607bcf3b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java @@ -7,6 +7,7 @@ import eu.eudat.exceptions.datasetprofile.DatasetProfileNewVersionException; import eu.eudat.exceptions.datasetprofile.DatasetProfileWithDatasetsExeption; import eu.eudat.logic.managers.AdminManager; import eu.eudat.logic.managers.DatasetProfileManager; +import eu.eudat.logic.managers.MetricsManager; import eu.eudat.logic.managers.UserManager; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.claims.ClaimedAuthorities; @@ -69,6 +70,7 @@ public class Admin extends BaseController { userDatasetProfile.setRole(0); getApiContext().getOperationsContext().getDatabaseRepository().getUserDatasetProfileDao().createOrUpdate(userDatasetProfile); datasetProfileManager.storeDatasetProfileUsers(datasetProfile, profile); + MetricsManager.increaseValue("totalTemplates", 1); return ResponseEntity.status(HttpStatus.OK).body(modelDefinition.getId()); } @@ -79,12 +81,16 @@ public class Admin extends BaseController { eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext()); eu.eudat.data.entities.DatasetProfile datasetprofile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); datasetprofile.setDefinition(modelDefinition.getDefinition()); + Short oldStatus = datasetprofile.getStatus(); datasetprofile.setStatus(modelDefinition.getStatus()); datasetprofile.setLabel(modelDefinition.getLabel()); datasetprofile.setDescription(modelDefinition.getDescription()); datasetprofile.setLanguage(modelDefinition.getLanguage()); eu.eudat.data.entities.DatasetProfile datasetProfile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(datasetprofile); datasetProfileManager.storeDatasetProfileUsers(datasetProfile, profile); + if (datasetProfile.getStatus() == 1 && oldStatus == 0) { + MetricsManager.increaseValue("activeTemplates", 1); + } return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java index ff6ddfe92..d9ec07835 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java @@ -4,6 +4,7 @@ package eu.eudat.controllers; import eu.eudat.exceptions.security.ExpiredTokenException; import eu.eudat.exceptions.security.NonValidTokenException; import eu.eudat.exceptions.security.NullEmailException; +import eu.eudat.logic.managers.MetricsManager; import eu.eudat.logic.managers.UserManager; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.CustomAuthenticationProvider; @@ -94,6 +95,7 @@ public class Login { public @ResponseBody ResponseEntity> externallogin(@RequestBody LoginInfo credentials) throws GeneralSecurityException, NullEmailException { logger.info("Trying To Login With " + credentials.getProvider()); + MetricsManager.increaseValue("usersLoggedIn", 1); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(customAuthenticationProvider.authenticate(credentials)).status(ApiMessageCode.SUCCESS_MESSAGE)); } @@ -102,6 +104,7 @@ public class Login { public @ResponseBody ResponseEntity> nativelogin(@RequestBody Credentials credentials) throws NullEmailException { logger.info(credentials.getUsername() + " Trying To Login"); + MetricsManager.increaseValue("usersLoggedIn", 1); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(userManager.authenticate(this.nonVerifiedUserAuthenticationService, credentials)).status(ApiMessageCode.SUCCESS_MESSAGE)); } @@ -162,6 +165,7 @@ public class Login { ResponseEntity> logout(Principal principal) { this.nonVerifiedUserAuthenticationService.Logout(principal.getToken()); logger.info(principal + " Logged Out"); + MetricsManager.decreaseValue("usersLoggedIn", 1); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java index 0d92fbdff..b65dcf671 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java @@ -1,5 +1,6 @@ package eu.eudat.controllers; +import eu.eudat.logic.managers.MetricsManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.security.Principal; @@ -37,6 +38,8 @@ public class UserGuideController { @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getUserGuide(@PathVariable(name = "lang") String lang) throws IOException { + long files = Files.list(Paths.get(this.environment.getProperty("userguide.path"))).count(); + MetricsManager.calculateValue("languages", (int) files); Stream walk = Files.walk(Paths.get(this.environment.getProperty("userguide.path"))); List result = walk.filter(Files::isRegularFile) .map(Path::toString).collect(Collectors.toList()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index d7b7a075f..75da09e2b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -375,6 +375,8 @@ public class DataManagementPlanManager { throw new Exception("DMP is finalized, therefore cannot be edited."); setNotification = true; + } else { + MetricsManager.increaseValue("draftDMPs", 1); } DMP newDmp = dataManagementPlan.toDataModel(); @@ -497,6 +499,8 @@ public class DataManagementPlanManager { } if (dataManagementPlan.getStatus() == (int) DMP.DMPStatus.FINALISED.getValue() && dmp1.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) throw new Exception("DMP is finalized, therefore cannot be edited."); + } else { + MetricsManager.increaseValue("draftDMPs", 1); } List datasets = new ArrayList<>(); DMP tempDMP = dataManagementPlan.toDataModel(); @@ -612,6 +616,7 @@ public class DataManagementPlanManager { newDmp.setDataset(new HashSet<>(databaseRepository.getDatasetDao().getWithCriteria(criteria1).toList())); this.updateIndex(newDmp); + MetricsManager.increaseValue("draftDMPs", 1); return newDmp.getId(); } @@ -623,6 +628,20 @@ public class DataManagementPlanManager { if (apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getWithCriteria(criteria).toList().size() > 0) throw new DMPWithDatasetsDeleteException("You cannot Remove Datamanagement Plan with Datasets"); DMP oldDmp = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(uuid); + switch (oldDmp.getStatus()) { + case 0: + MetricsManager.decreaseValue("draftDMPs", 1); + break; + case 1: + if (oldDmp.getDoi() != null) { + MetricsManager.decreaseValue("doiedDMPs", 1); + } + if (oldDmp.isPublic()) { + MetricsManager.decreaseValue("publishedDMPs", 1); + } + MetricsManager.decreaseValue("finalizedDMPs", 1); + break; + } oldDmp.setStatus(DMP.DMPStatus.DELETED.getValue()); apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(oldDmp); this.updateIndex(oldDmp); @@ -660,6 +679,7 @@ public class DataManagementPlanManager { else { researcher.setCreationUser(user); researcherRepository.createOrUpdate(researcher); + MetricsManager.increaseValue("researchers", 1); } } } @@ -739,12 +759,14 @@ public class DataManagementPlanManager { project.setType(Project.ProjectType.EXTERNAL.getValue()); if (project.getId() == null) project.setId(UUID.randomUUID()); projectDao.createOrUpdate(project); + MetricsManager.increaseValue("projects", 1); } } else { project.setType(Project.ProjectType.EXTERNAL.getValue()); if (project.getId() == null) project.setId(UUID.randomUUID()); projectDao.createOrUpdate(project); + MetricsManager.increaseValue("projects", 1); } } } @@ -821,6 +843,7 @@ public class DataManagementPlanManager { return newDataset; }).thenApplyAsync(item -> { futures.add(datasetDao.createOrUpdateAsync(item).whenComplete(((dataset1, throwable) -> { + MetricsManager.increaseValue("draftDatasets", 1); eu.eudat.elastic.entities.Dataset datasetElastic = new eu.eudat.elastic.entities.Dataset(); datasetElastic.setId(dataset1.getId().toString()); datasetElastic.setLabel(dataset1.getLabel()); @@ -878,6 +901,7 @@ public class DataManagementPlanManager { dmp.setPublic(true); apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); this.updateIndex(dmp); + MetricsManager.increaseValue("publishedDMPs", 1); DataManagementPlanCriteria criteria = new DataManagementPlanCriteria(); criteria.setGroupIds(Collections.singletonList(dmp.getGroupId())); criteria.setAllVersions(true); @@ -890,6 +914,7 @@ public class DataManagementPlanManager { tags = elastic.getTags(); } this.datasetManager.updateTags(dataset, tags); + MetricsManager.increaseValue("publishedDatasets", 1); } catch (Exception e) { logger.error(e.getMessage(), e); } @@ -911,6 +936,8 @@ public class DataManagementPlanManager { dmp.setStatus(DMP.DMPStatus.FINALISED.getValue()); apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); this.updateIndex(dmp); + MetricsManager.decreaseValue("draftDMPs", 1); + MetricsManager.increaseValue("finalizedDMPs", 1); List indexDatasets = new ArrayList<>(); if (datasetsToBeFinalized != null && datasetsToBeFinalized.getUuids() != null && !datasetsToBeFinalized.getUuids().isEmpty()) { apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao() @@ -960,6 +987,8 @@ public class DataManagementPlanManager { sendNotification(dmp, user, NotificationType.DMP_FINALISED); } this.updateDatasetsIndex(indexDatasets); + MetricsManager.decreaseValue("draftDatasets", indexDatasets.size()); + MetricsManager.increaseValue("finalizedDatasets", indexDatasets.size()); } public void undoFinalize(UUID id, Principal principal) throws Exception { @@ -971,6 +1000,8 @@ public class DataManagementPlanManager { dmp.setStatus(DMP.DMPStatus.ACTIVE.getValue()); apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); this.updateIndex(dmp); + MetricsManager.decreaseValue("finalizedDMPs", 1); + MetricsManager.increaseValue("draftDMPs", 1); } public void updateUsers(UUID id, List users, Principal principal) throws Exception { @@ -2028,6 +2059,35 @@ public class DataManagementPlanManager { } + public long countAllDrafts() { + DataManagementPlanCriteria criteria = new DataManagementPlanCriteria(); + criteria.setStatus(0); + return apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getWithCriteria(criteria).count(); + } + + public long countAllFinalized() { + DataManagementPlanCriteria criteria = new DataManagementPlanCriteria(); + criteria.setStatus(1); + return apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getWithCriteria(criteria).count(); + } + + public long countAllPublished() { + DataManagementPlanCriteria criteria = new DataManagementPlanCriteria(); + criteria.setIsPublic(true); + criteria.setOnlyPublic(true); + return apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getWithCriteria(criteria).count(); + } + + public long countAllResearchers() { + ResearcherCriteria criteria = new ResearcherCriteria(); + return apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao().getWithCriteria(criteria).count(); + } + + public long countAllProjects() { + ProjectCriteria criteria = new ProjectCriteria(); + return apiContext.getOperationsContext().getDatabaseRepository().getProjectDao().getWithCritetia(criteria).count(); + } + /*public DataTableData getPublicPaged(DataManagmentPlanPublicTableRequest dataManagementPlanPublicTableRequest, String fieldsGroup, Principal principal) throws Exception { dataManagementPlanPublicTableRequest.setQuery(databaseRepository.getDmpDao().asQueryable().withHint(HintedModelFactory.getHint(DataManagementPlanListingModel.class))); QueryableList items = dataManagementPlanPublicTableRequest.applyCriteria(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index ef1a0e20f..c6d10f2a9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -590,6 +590,8 @@ public class DatasetManager { } sendNotification = true; } + } else { + MetricsManager.increaseValue("draftDatasets", 1); } if (dmp.getStatus().equals(DMP.DMPStatus.FINALISED.getValue()) && datasetWizardModel.getId() != null) throw new Exception("DMP is finalized, therefore Dataset cannot be edited."); @@ -824,6 +826,7 @@ public class DatasetManager { if (dataset.getStatus() != eu.eudat.data.entities.Dataset.Status.FINALISED.getValue()) throw new Exception("You cannot make public a Dataset That Has not Been Finalised"); datasetDao.createOrUpdate(dataset); + MetricsManager.increaseValue("publishedDatasets", 1); } public ResponseEntity getDocument(String id, VisibilityRuleService visibilityRuleService, String contentType, Principal principal) throws IllegalAccessException, IOException, InstantiationException { @@ -912,6 +915,7 @@ public class DatasetManager { createServicesIfTheyDontExist(entity); createExternalDatasetsIfTheyDontExist(entity); + MetricsManager.increaseValue("draftDatasets", 1); return apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().createOrUpdate(entity); } @@ -1067,4 +1071,22 @@ public class DatasetManager { listingModel.setProfileLatestVersion(islast); return listingModel; } + + public long countAllDraft() { + eu.eudat.data.dao.criteria.DatasetCriteria criteria = new eu.eudat.data.dao.criteria.DatasetCriteria(); + criteria.setStatus(0); + return apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getWithCriteria(criteria).count(); + } + + public long countAllFinalized() { + eu.eudat.data.dao.criteria.DatasetCriteria criteria = new eu.eudat.data.dao.criteria.DatasetCriteria(); + criteria.setStatus(1); + return apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getWithCriteria(criteria).count(); + } + + public long countAllPublic() { + eu.eudat.data.dao.criteria.DatasetCriteria criteria = new eu.eudat.data.dao.criteria.DatasetCriteria(); + criteria.setIsPublic(true); + return apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getWithCriteria(criteria).count(); + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java index 56e2494d3..d7105daba 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java @@ -16,6 +16,7 @@ import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.documents.xml.datasetProfileXml.ExportXmlBuilderDatasetProfile; import eu.eudat.logic.utilities.documents.xml.datasetProfileXml.ImportXmlBuilderDatasetProfile; +import eu.eudat.logic.utilities.helpers.StreamDistinctBy; import eu.eudat.models.data.components.commons.datafield.AutoCompleteData; import eu.eudat.models.data.datasetprofile.DatasetProfileAutocompleteItem; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; @@ -42,6 +43,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.activation.MimetypesFileTypeMap; +import javax.transaction.Transactional; import javax.xml.xpath.*; import java.io.*; import java.nio.file.Files; @@ -89,6 +91,7 @@ public class DatasetProfileManager { DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); apiContext.getOperationsContext().getDatabaseRepository().detachEntity(profile); profile.setId(null); + MetricsManager.increaseValue("totalTemplates", 1); return profile; } @@ -108,6 +111,7 @@ public class DatasetProfileManager { public List getAll(DatasetProfileTableRequestItem tableRequestItem) throws IllegalAccessException, InstantiationException { QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(tableRequestItem.getCriteria()); List datasetProfiles = items.select(item -> new DatasetProfileListingModel().fromDataModel(item)); + return datasetProfiles; } @@ -227,6 +231,7 @@ public class DatasetProfileManager { File localFile = convert(multiPartFile); eu.eudat.logic.utilities.documents.xml.datasetProfileXml.datasetProfileModel.DatasetProfile profile = xmlBuilder.build(localFile); Files.deleteIfExists(localFile.toPath()); + MetricsManager.increaseValue("totalTemplates", 1); return profile; } catch (IOException e) { logger.error(e.getMessage(), e); @@ -299,4 +304,25 @@ public class DatasetProfileManager { }).collect(Collectors.toList())); } } + + public long countAlldraft() { + DatasetProfileCriteria criteria = new DatasetProfileCriteria(); + criteria.setStatus(0); + return apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).count(); + } + + public long countAllFinalized() { + DatasetProfileCriteria criteria = new DatasetProfileCriteria(); + criteria.setStatus(1); + return apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).count(); + } + + @Transactional + public long countAllUsed() { + DatasetProfileCriteria criteria = new DatasetProfileCriteria(); + criteria.setStatus(1); + criteria.setAllVersions(false); + List datasetProfiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).toList(); + return datasetProfiles.stream().filter(StreamDistinctBy.distinctByKey(DatasetProfile::getId)).filter(datasetProfile -> !datasetProfile.getDataset().isEmpty()).count(); + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java new file mode 100644 index 000000000..25e696f79 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java @@ -0,0 +1,84 @@ +package eu.eudat.logic.managers; + +import io.prometheus.client.Gauge; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.transaction.Transactional; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Component +public class MetricsManager { + private static Map gauges = Stream.of( new Object[][]{ + {"usersLoggedIn", Gauge.build("users_logged_in", "Number of current logged in users").register()}, + {"projects", Gauge.build("projects", "Number of registered Projects").register()}, + {"draftDMPs", Gauge.build("draft_dmps", "Number of draft DMPs").register()}, + {"finalizedDMPs", Gauge.build("finalized_dmps", "Number of finalized DMPs").register()}, + {"publishedDMPs", Gauge.build("published_dmps", "Number of published DMPs").register()}, + {"doiedDMPs", Gauge.build("doied_dmps", "Number of DMPs with DOI").register()}, + {"draftDatasets", Gauge.build("draft_datasets", "Number of draft Datasets").register()}, + {"finalizedDatasets", Gauge.build("finalized_datasets", "Number of finalized Datasets").register()}, + {"publishedDatasets", Gauge.build("published_datasets", "Number of published Datasets").register()}, + {"doiedDatasets", Gauge.build("doied_datasets", "Number of Datasets with DOI").register()}, + {"researchers", Gauge.build("researchers", "Number of Colaborators/Researchers").register()}, + {"totalTemplates", Gauge.build("total_templates", "Number of total Templates").register()}, + {"activeTemplates", Gauge.build("active_templates", "Number of active Templates").register()}, + {"usedTemplates", Gauge.build("used_templates", "Number of used Templates").register()}, + {"languages", Gauge.build("languages", "Number of Languages").register()} + }).collect(Collectors.toMap(data -> (String)data[0], data -> (Gauge) data[1])); + + public static void increaseValue(String name, int amount) { + gauges.get(name).inc(amount); + } + + public static void decreaseValue(String name, int amount) { + gauges.get(name).dec(amount); + } + + public static Integer getValue(String name) { + return Double.valueOf(gauges.get(name).get()).intValue(); + } + + public static void calculateValue(String name, int amount) { + Integer orig = getValue(name); + int diff = orig - amount; + if (diff != 0) { + if (diff > 0) { + decreaseValue(name, diff); + } else { + increaseValue(name, Math.abs(diff)); + } + } + } + + private final DatasetManager datasetManager; + private final DataManagementPlanManager dataManagementPlanManager; + private final DatasetProfileManager datasetProfileManager; + + @Autowired + public MetricsManager(DatasetManager datasetManager, DataManagementPlanManager dataManagementPlanManager, DatasetProfileManager datasetProfileManager) { + this.datasetManager = datasetManager; + this.dataManagementPlanManager = dataManagementPlanManager; + this.datasetProfileManager = datasetProfileManager; + } + + @PostConstruct + @Transactional + public void init() { + calculateValue("draftDMPs", (int) dataManagementPlanManager.countAllDrafts()); + calculateValue("finalizedDMPs", (int) dataManagementPlanManager.countAllFinalized()); + calculateValue("publishedDMPs", (int) dataManagementPlanManager.countAllFinalized()); + calculateValue("projects", (int) dataManagementPlanManager.countAllProjects()); + calculateValue("researchers", (int) dataManagementPlanManager.countAllResearchers()); + calculateValue("draftDatasets", (int) datasetManager.countAllDraft()); + calculateValue("finalizedDatasets", (int) datasetManager.countAllFinalized()); + calculateValue("publishedDatasets", (int) datasetManager.countAllPublic()); + calculateValue("totalTemplates", (int) datasetProfileManager.countAlldraft()); + calculateValue("activeTemplates", (int) datasetProfileManager.countAllFinalized()); + calculateValue("usedTemplates", (int) datasetProfileManager.countAllUsed()); + } + +} diff --git a/dmp-backend/web/src/main/resources/config/application-devel.properties b/dmp-backend/web/src/main/resources/config/application-devel.properties index 8f1ffc696..2f2708d6b 100644 --- a/dmp-backend/web/src/main/resources/config/application-devel.properties +++ b/dmp-backend/web/src/main/resources/config/application-devel.properties @@ -83,4 +83,7 @@ contact_email.mail= language.path=dmp-frontend/src/assets/i18n/ #############LOGGING######### -logging.config=classpath:logging/logback-${spring.profiles.active}.xml \ No newline at end of file +logging.config=classpath:logging/logback-${spring.profiles.active}.xml + +#############PROMETHEUS######### +endpoints.prometheus.sensitive: false \ No newline at end of file diff --git a/prometheus/config/prometheus.yml b/prometheus/config/prometheus.yml new file mode 100644 index 000000000..9db1229ca --- /dev/null +++ b/prometheus/config/prometheus.yml @@ -0,0 +1,40 @@ +# my global config +global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + # scrape_timeout is set to the global default (10s). + +# Alertmanager configuration +alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 + +# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. +rule_files: + # - "first_rules.yml" + # - "second_rules.yml" + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: 'prometheus' + + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + + static_configs: + - targets: ['localhost:9090'] + + - job_name: 'openDMP' + + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + + static_configs: + - targets: ['localhost:8081'] + + metrics_path: 'prometheus' +