diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/MetadataEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/MetadataEndpoint.java
index 568ab8a41676440430478db18b96dea0830b6fcc..6790db5c78df4a33c8b2fdbd2d1878c407efec16 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/MetadataEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/MetadataEndpoint.java
@@ -6,6 +6,7 @@ import at.tuwien.oaipmh.OaiListIdentifiersParameters;
 import at.tuwien.oaipmh.OaiRecordParameters;
 import at.tuwien.service.MetadataService;
 import io.micrometer.core.annotation.Timed;
+import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.enums.ParameterIn;
@@ -43,7 +44,7 @@ public class MetadataEndpoint {
             @ExampleObject(value = "GetRecord"),
             @ExampleObject(value = "ListMetadataFormats"),
     })
-    @Timed(value = "repository.identify", description = "Time needed to identify the repository")
+    @Observed(name = "dbr_oai_identify")
     @Operation(summary = "Identify the repository")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
@@ -56,7 +57,7 @@ public class MetadataEndpoint {
     }
 
     @GetMapping(params = "verb=Identify", produces = "text/xml;charset=UTF-8")
-    @Timed(value = "repository.identify", description = "Time needed to identify the repository")
+    @Observed(name = "dbr_oai_identify")
     @Operation(summary = "Identify the repository")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
@@ -71,7 +72,7 @@ public class MetadataEndpoint {
     }
 
     @GetMapping(params = "verb=ListIdentifiers", produces = "text/xml;charset=UTF-8")
-    @Timed(value = "identifiers.list", description = "Time needed to list the identifiers")
+    @Observed(name = "dbr_oai_identifiers_list")
     @Operation(summary = "List the identifiers")
     public ResponseEntity<String> listIdentifiers(OaiListIdentifiersParameters parameters) {
         log.debug("endpoint list identifiers, verb=ListIdentifiers, parameters={}", parameters);
@@ -81,7 +82,7 @@ public class MetadataEndpoint {
     }
 
     @GetMapping(params = "verb=GetRecord", produces = "text/xml;charset=UTF-8")
-    @Timed(value = "record.find", description = "Time needed to find a record")
+    @Observed(name = "dbr_oai_record_get")
     @Operation(summary = "Get the record")
     public ResponseEntity<String> getRecord(OaiRecordParameters parameters) {
         log.debug("endpoint get record, verb=GetRecord, parameters={}", parameters);
@@ -116,7 +117,7 @@ public class MetadataEndpoint {
     }
 
     @GetMapping(params = "verb=ListMetadataFormats", produces = "text/xml;charset=UTF-8")
-    @Timed(value = "formats.list", description = "Time needed to list the metadata formats")
+    @Observed(name = "dbr_oai_metadataformats_list")
     @Operation(summary = "List the metadata formats")
     public ResponseEntity<String> listMetadataFormats() {
         log.debug("endpoint list metadata formats, verb=ListMetadataFormats");
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/OntologyEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/OntologyEndpoint.java
index 28f8d724da3a6938545532cdd18ea91f62fa5d90..dab0740a04654dcc86f18c5c99e8a56988e4a103 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/OntologyEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/OntologyEndpoint.java
@@ -9,6 +9,7 @@ import at.tuwien.service.EntityService;
 import at.tuwien.service.OntologyService;
 import at.tuwien.utils.PrincipalUtil;
 import io.micrometer.core.annotation.Timed;
+import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.ArraySchema;
 import io.swagger.v3.oas.annotations.media.Content;
@@ -46,7 +47,7 @@ public class OntologyEndpoint {
     }
 
     @GetMapping
-    @Timed(value = "semantics.ontology.list", description = "Time needed to list ontologies")
+    @Observed(name = "dbr_ontologies_findall")
     @Operation(summary = "List all ontologies")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
@@ -66,7 +67,7 @@ public class OntologyEndpoint {
     }
 
     @GetMapping("/{id}")
-    @Timed(value = "semantics.ontology.find", description = "Time needed to find a specific ontology")
+    @Observed(name = "dbr_ontologies_find")
     @Operation(summary = "Find one ontology")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
@@ -89,7 +90,7 @@ public class OntologyEndpoint {
 
     @PostMapping
     @PreAuthorize("hasAuthority('create-ontology')")
-    @Timed(value = "semantics.ontology.create", description = "Time needed to register a new ontology")
+    @Observed(name = "dbr_ontologies_create")
     @Operation(summary = "Register a new ontology", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "201",
@@ -115,7 +116,7 @@ public class OntologyEndpoint {
 
     @PutMapping("/{id}")
     @PreAuthorize("hasAuthority('update-ontology')")
-    @Timed(value = "semantics.ontology.update", description = "Time needed to update a new ontology")
+    @Observed(name = "dbr_ontologies_update")
     @Operation(summary = "Update an ontology", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "202",
@@ -141,7 +142,7 @@ public class OntologyEndpoint {
 
     @DeleteMapping("/{id}")
     @PreAuthorize("hasAuthority('delete-ontology')")
-    @Timed(value = "semantics.ontology.delete", description = "Time needed to delete an ontology")
+    @Observed(name = "dbr_ontologies_delete")
     @Operation(summary = "Delete an ontology", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "202",
@@ -163,7 +164,7 @@ public class OntologyEndpoint {
 
     @GetMapping("/{id}/entity")
     @PreAuthorize("hasAuthority('execute-semantic-query')")
-    @Timed(value = "semantics.find", description = "Time needed to find entities")
+    @Observed(name = "dbr_ontologies_entities_find")
     @Operation(summary = "Find entities", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java
index 3284977e77735204bd3e21546a3f608fa400f843..0cd22a58a3c9ab11881d3372adb48c57d4c87665 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java
@@ -12,6 +12,7 @@ import at.tuwien.service.AccessService;
 import at.tuwien.service.IdentifierService;
 import at.tuwien.utils.UserUtil;
 import io.micrometer.core.annotation.Timed;
+import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -56,7 +57,7 @@ public class PersistenceEndpoint {
 
     @GetMapping("/{pid}")
     @Transactional(readOnly = true)
-    @Timed(value = "pid.find", description = "Time needed to find a persisted identifier")
+    @Observed(name = "dbr_pid_find")
     @Operation(summary = "Find some identifier")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
@@ -151,7 +152,7 @@ public class PersistenceEndpoint {
 
     @PutMapping("/{id}")
     @Transactional
-    @Timed(value = "identifier.update", description = "Time needed to update an identifier")
+    @Observed(name = "dbr_pid_update")
     @PreAuthorize("hasAuthority('modify-identifier-metadata')")
     @Operation(summary = "Update some identifier", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
@@ -207,7 +208,7 @@ public class PersistenceEndpoint {
 
     @DeleteMapping("/{id}")
     @Transactional
-    @Timed(value = "identifier.delete", description = "Time needed to delete an identifier")
+    @Observed(name = "dbr_pid_delete")
     @PreAuthorize("hasAuthority('delete-identifier')")
     @Operation(summary = "Delete some identifier", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java
index e312d1110b29bb368d7bbaf5cb4027d83aee7dcd..2eceec710136d91ddb996dee7d42c17a2b94bdba 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java
@@ -15,6 +15,7 @@ import at.tuwien.utils.PrincipalUtil;
 import at.tuwien.utils.UserUtil;
 import at.tuwien.validation.EndpointValidator;
 import io.micrometer.core.annotation.Timed;
+import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.security.SecurityRequirement;
 import jakarta.validation.Valid;
@@ -51,7 +52,7 @@ public class QueryEndpoint {
 
     @PostMapping
     @Transactional(readOnly = true)
-    @Timed(value = "query.execute", description = "Time needed to execute a query")
+    @Observed(name = "dbr_query_execute")
     @PreAuthorize("hasAuthority('execute-query')")
     @Operation(summary = "Execute query", security = @SecurityRequirement(name = "bearerAuth"))
     public ResponseEntity<QueryResultDto> execute(@NotNull @PathVariable("databaseId") Long databaseId,
@@ -84,7 +85,7 @@ public class QueryEndpoint {
 
     @GetMapping("/{queryId}/data")
     @Transactional(readOnly = true)
-    @Timed(value = "query.reexecute", description = "Time needed to re-execute a query")
+    @Observed(name = "dbr_query_reexecute")
     @Operation(summary = "Re-execute some query", security = @SecurityRequirement(name = "bearerAuth"))
     public ResponseEntity<QueryResultDto> reExecute(@NotNull @PathVariable("databaseId") Long databaseId,
                                                     @NotNull @PathVariable("queryId") Long queryId,
@@ -112,7 +113,7 @@ public class QueryEndpoint {
 
     @GetMapping("/{queryId}/data/count")
     @Transactional(readOnly = true)
-    @Timed(value = "query.reexecute.count", description = "Time needed to re-execute a query")
+    @Observed(name = "dbr_query_reexecute_count")
     @Operation(summary = "Re-execute some query", security = @SecurityRequirement(name = "bearerAuth"))
     public ResponseEntity<Long> reExecuteCount(@NotNull @PathVariable("databaseId") Long databaseId,
                                                @NotNull @PathVariable("queryId") Long queryId,
@@ -132,7 +133,7 @@ public class QueryEndpoint {
 
     @GetMapping("/{queryId}/export")
     @Transactional(readOnly = true)
-    @Timed(value = "query.export", description = "Time needed to export query data")
+    @Observed(name = "dbr_query_export")
     @Operation(summary = "Exports some query", security = @SecurityRequirement(name = "bearerAuth"))
     public ResponseEntity<?> export(@NotNull @PathVariable("databaseId") Long databaseId,
                                     @NotNull @PathVariable("queryId") Long queryId,
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/SemanticsEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/SemanticsEndpoint.java
index bb2536451d7e27a237cf782876423f6671013241..f210fe1e527dd5822c0abb00a3e9f0a9d6f3307f 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/SemanticsEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/SemanticsEndpoint.java
@@ -16,6 +16,7 @@ import at.tuwien.mapper.SemanticMapper;
 import at.tuwien.service.EntityService;
 import at.tuwien.service.SemanticService;
 import io.micrometer.core.annotation.Timed;
+import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.ArraySchema;
 import io.swagger.v3.oas.annotations.media.Content;
@@ -56,7 +57,7 @@ public class SemanticsEndpoint {
 
     @GetMapping("/concept")
     @Transactional(readOnly = true)
-    @Timed(value = "semantics.concept.list", description = "Time needed to find all semantic concepts")
+    @Observed(name = "dbr_semantic_concepts_findall")
     @Operation(summary = "List semantic concepts")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
@@ -79,7 +80,7 @@ public class SemanticsEndpoint {
     @PostMapping("/concept")
     @Transactional
     @PreAuthorize("hasAuthority('create-semantic-concept')")
-    @Timed(value = "semantics.concept.save", description = "Time needed to save a semantic concept")
+    @Observed(name = "dbr_semantic_concepts_save")
     @Operation(summary = "Create or update a semantic concept", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "202",
@@ -88,7 +89,7 @@ public class SemanticsEndpoint {
                             mediaType = "application/json",
                             schema = @Schema(implementation = ConceptDto.class))}),
     })
-    public ResponseEntity<ConceptDto> saveUnit(@NotNull @Valid @RequestBody ConceptSaveDto data) {
+    public ResponseEntity<ConceptDto> saveConcept(@NotNull @Valid @RequestBody ConceptSaveDto data) {
         log.debug("endpoint save concept, data={}", data);
         final ConceptDto dto = ontologyMapper.tableColumnConceptToConceptDto(semanticService.saveConcept(data));
         log.trace("save concept resulted in dto {}", dto);
@@ -98,7 +99,7 @@ public class SemanticsEndpoint {
 
     @GetMapping("/unit")
     @Transactional(readOnly = true)
-    @Timed(value = "semantics.concept.list", description = "Time needed to find all semantic units")
+    @Observed(name = "dbr_semantic_units_findall")
     @Operation(summary = "List semantic units")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
@@ -121,7 +122,7 @@ public class SemanticsEndpoint {
     @PostMapping("/unit")
     @Transactional
     @PreAuthorize("hasAuthority('create-semantic-unit')")
-    @Timed(value = "semantics.unit.save", description = "Time needed to save a semantic unit")
+    @Observed(name = "dbr_semantic_units_save")
     @Operation(summary = "Save a semantic unit", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "202",
@@ -141,7 +142,7 @@ public class SemanticsEndpoint {
     @GetMapping("/database/{databaseId}/table/{tableId}")
     @Transactional(readOnly = true)
     @PreAuthorize("hasAuthority('table-semantic-analyse')")
-    @Timed(value = "semantics.table.analyse", description = "Time needed to analyse table semantics")
+    @Observed(name = "dbr_semantic_table_analyse")
     @Operation(summary = "Suggest table semantics", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
@@ -173,7 +174,7 @@ public class SemanticsEndpoint {
     @GetMapping("/database/{databaseId}/table/{tableId}/column/{columnId}")
     @Transactional(readOnly = true)
     @PreAuthorize("hasAuthority('table-semantic-analyse')")
-    @Timed(value = "semantics.table.columnanalyse", description = "Time needed to analyse table column semantics")
+    @Observed(name = "dbr_semantic_column_analyse")
     @Operation(summary = "Suggest table column semantics", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/StoreEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/StoreEndpoint.java
index c23a662a6e11424cf936ac3faaf641f633e23a6a..435718e4573037f041d6c98c9ca2671ccfaa1c6e 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/StoreEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/StoreEndpoint.java
@@ -19,6 +19,7 @@ import at.tuwien.utils.PrincipalUtil;
 import at.tuwien.utils.UserUtil;
 import at.tuwien.validation.EndpointValidator;
 import io.micrometer.core.annotation.Timed;
+import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.ArraySchema;
 import io.swagger.v3.oas.annotations.media.Content;
@@ -71,7 +72,7 @@ public class StoreEndpoint {
 
     @GetMapping
     @Transactional(readOnly = true)
-    @Timed(value = "store.list", description = "Time needed to list queries from the query store")
+    @Observed(name = "dbr_queries_findall")
     @Operation(summary = "Find queries", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
@@ -138,7 +139,7 @@ public class StoreEndpoint {
 
     @GetMapping("/{queryId}")
     @Transactional(readOnly = true)
-    @Timed(value = "store.find", description = "Time needed to find a query from the query store")
+    @Observed(name = "dbr_queries_find")
     @Operation(summary = "Find some query", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
@@ -196,7 +197,7 @@ public class StoreEndpoint {
     @PutMapping("/{queryId}")
     @Transactional(readOnly = true)
     @PreAuthorize("hasAuthority('persist-query')")
-    @Timed(value = "store.persist", description = "Time needed to persist a query in the query store")
+    @Observed(name = "dbr_query_persist")
     @Operation(summary = "Persist some query", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableColumnEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableColumnEndpoint.java
index e69cb22ca2bc713f36fad4b0d5e97ccd34fc52f3..ebe9b7375d672f0d57fcae8e6927f5bdb74a23da 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableColumnEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableColumnEndpoint.java
@@ -11,6 +11,7 @@ import at.tuwien.utils.PrincipalUtil;
 import at.tuwien.utils.UserUtil;
 import at.tuwien.validation.EndpointValidator;
 import io.micrometer.core.annotation.Timed;
+import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -48,7 +49,7 @@ public class TableColumnEndpoint {
     @PutMapping
     @Transactional
     @PreAuthorize("hasAuthority('modify-table-column-semantics') or hasAuthority('modify-foreign-table-column-semantics')")
-    @Timed(value = "semantics.column_update", description = "Time needed to update a table column semantic mapping")
+    @Observed(name = "dbr_semantics_column_save")
     @Operation(summary = "Update a table column semantic mapping", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "202",
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableDataEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableDataEndpoint.java
index 7a75c659ee41316537fb7bdff292c42e0bf817b8..61fbb537ddf8169a3aedac513c888313b4db2a82 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableDataEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableDataEndpoint.java
@@ -14,6 +14,7 @@ import at.tuwien.utils.PrincipalUtil;
 import at.tuwien.utils.UserUtil;
 import at.tuwien.validation.EndpointValidator;
 import io.micrometer.core.annotation.Timed;
+import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.security.SecurityRequirement;
 import jakarta.validation.Valid;
@@ -48,7 +49,7 @@ public class TableDataEndpoint {
 
     @PostMapping
     @Transactional
-    @Timed(value = "data.insert", description = "Time needed to insert data into a table")
+    @Observed(name = "dbr_table_data_insert")
     @PreAuthorize("hasAuthority('insert-table-data')")
     @Operation(summary = "Insert data", security = @SecurityRequirement(name = "bearerAuth"))
     public ResponseEntity<Void> insert(@NotNull @PathVariable("databaseId") Long databaseId,
@@ -71,7 +72,7 @@ public class TableDataEndpoint {
     @Transactional
     @Deprecated
     @PreAuthorize("hasAuthority('insert-table-data')")
-    @Timed(value = "data.update", description = "Time needed to update data in a table")
+    @Observed(name = "dbr_table_data_update")
     @Operation(summary = "Update data", security = @SecurityRequirement(name = "bearerAuth"))
     public ResponseEntity<Void> update(@NotNull @PathVariable("databaseId") Long databaseId,
                                        @NotNull @PathVariable("tableId") Long tableId,
@@ -92,7 +93,7 @@ public class TableDataEndpoint {
     @DeleteMapping
     @Transactional
     @PreAuthorize("hasAuthority('delete-table-data')")
-    @Timed(value = "data.delete", description = "Time needed to delete data into a table")
+    @Observed(name = "dbr_table_data_delete")
     @Operation(summary = "Delete data", security = @SecurityRequirement(name = "bearerAuth"))
     public ResponseEntity<Void> delete(@NotNull @PathVariable("databaseId") Long databaseId,
                                        @NotNull @PathVariable("tableId") Long tableId,
@@ -113,7 +114,7 @@ public class TableDataEndpoint {
     @PostMapping("/import")
     @Transactional
     @PreAuthorize("hasAuthority('insert-table-data')")
-    @Timed(value = "data.insertbulk", description = "Time needed to insert data from .csv into a table")
+    @Observed(name = "dbr_table_data_import")
     @Operation(summary = "Insert data from csv", security = @SecurityRequirement(name = "bearerAuth"))
     public ResponseEntity<Void> importCsv(@NotNull @PathVariable("databaseId") Long databaseId,
                                           @NotNull @PathVariable("tableId") Long tableId,
@@ -133,7 +134,7 @@ public class TableDataEndpoint {
 
     @RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD})
     @Transactional(readOnly = true)
-    @Timed(value = "data.all", description = "Time needed to find all data from a table")
+    @Observed(name = "dbr_table_data_findall")
     @Operation(summary = "Find data", security = @SecurityRequirement(name = "bearerAuth"))
     public ResponseEntity<QueryResultDto> getAll(@NotNull @PathVariable("databaseId") Long databaseId,
                                                  @NotNull @PathVariable("tableId") Long tableId,
@@ -165,7 +166,7 @@ public class TableDataEndpoint {
 
     @GetMapping("/count")
     @Transactional(readOnly = true)
-    @Timed(value = "data.all.count", description = "Time needed to get count of all data from a table")
+    @Observed(name = "dbr_table_data_countall")
     @Operation(summary = "Find data", security = @SecurityRequirement(name = "bearerAuth"))
     public ResponseEntity<Long> getCount(@NotNull @PathVariable("databaseId") Long databaseId,
                                          @NotNull @PathVariable("tableId") Long tableId,
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/SemanticsEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/SemanticsEndpointUnitTest.java
index cdee187b74e2906d0eda8f050145bfce82945f26..957825376ee00951ce0bc3eda07a89807ddbc354 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/SemanticsEndpointUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/SemanticsEndpointUnitTest.java
@@ -246,7 +246,7 @@ public class SemanticsEndpointUnitTest extends BaseUnitTest {
         }
 
         /* test */
-        final ResponseEntity<ConceptDto> response = semanticsEndpoint.saveUnit(saveDto);
+        final ResponseEntity<ConceptDto> response = semanticsEndpoint.saveConcept(saveDto);
         assertEquals(HttpStatus.ACCEPTED, response.getStatusCode());
         final ConceptDto body = response.getBody();
         assertNotNull(body);
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
index c468faabb5b1407daf481f01062442baa7f2c340..afd229f5a1206a9d54bf5ff5def0bf38cb13a348 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
@@ -5,6 +5,12 @@ import at.tuwien.annotations.MockAmqp;
 import at.tuwien.annotations.MockOpensearch;
 import at.tuwien.api.container.ContainerCreateRequestDto;
 import at.tuwien.api.database.*;
+import at.tuwien.api.database.query.ExecuteStatementDto;
+import at.tuwien.api.database.query.ImportDto;
+import at.tuwien.api.database.query.QueryPersistDto;
+import at.tuwien.api.database.table.TableCsvDeleteDto;
+import at.tuwien.api.database.table.TableCsvDto;
+import at.tuwien.api.database.table.TableCsvUpdateDto;
 import at.tuwien.config.MetricsConfig;
 import at.tuwien.endpoints.*;
 import io.micrometer.observation.tck.TestObservationRegistry;
@@ -69,6 +75,30 @@ public class PrometheusEndpointMvcTest extends BaseUnitTest {
     @Autowired
     private MaintenanceEndpoint maintenanceEndpoint;
 
+    @Autowired
+    private MetadataEndpoint metadataEndpoint;
+
+    @Autowired
+    private OntologyEndpoint ontologyEndpoint;
+
+    @Autowired
+    private PersistenceEndpoint persistenceEndpoint;
+
+    @Autowired
+    private QueryEndpoint queryEndpoint;
+
+    @Autowired
+    private SemanticsEndpoint semanticsEndpoint;
+
+    @Autowired
+    private StoreEndpoint storeEndpoint;
+
+    @Autowired
+    private TableColumnEndpoint tableColumnEndpoint;
+
+    @Autowired
+    private TableDataEndpoint tableDataEndpoint;
+
     @TestConfiguration
     static class ObservationTestConfiguration {
 
@@ -344,4 +374,271 @@ public class PrometheusEndpointMvcTest extends BaseUnitTest {
         }
     }
 
+    @Test
+    @WithMockUser(username = USER_1_USERNAME)
+    public void prometheusMetadataEndpoint_succeeds() {
+
+        /* mock */
+        try {
+            metadataEndpoint.identify();
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            metadataEndpoint.listIdentifiers(null);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            metadataEndpoint.getRecord(null);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            metadataEndpoint.listMetadataFormats();
+        } catch (Exception e) {
+            /* ignore */
+        }
+
+        /* test */
+        for (String metric : List.of("dbr_oai_identify", "dbr_oai_identifiers_list", "dbr_oai_record_get", "dbr_oai_metadataformats_list")) {
+            assertThat(registry)
+                    .hasObservationWithNameEqualTo(metric);
+        }
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"create-ontology", "update-ontology", "delete-ontology", "execute-semantic-query"})
+    public void prometheusOntologyEndpoint_succeeds() {
+
+        /* mock */
+        try {
+            ontologyEndpoint.findAll();
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            ontologyEndpoint.find(ONTOLOGY_1_ID);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            ontologyEndpoint.create(ONTOLOGY_1_CREATE_DTO, USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            ontologyEndpoint.update(ONTOLOGY_1_ID, ONTOLOGY_1_MODIFY_DTO, USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            ontologyEndpoint.delete(ONTOLOGY_1_ID);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            ontologyEndpoint.find(ONTOLOGY_1_ID, "thing", null);
+        } catch (Exception e) {
+            /* ignore */
+        }
+
+        /* test */
+        for (String metric : List.of("dbr_ontologies_findall", "dbr_ontologies_find", "dbr_ontologies_create", "dbr_ontologies_update", "dbr_ontologies_delete", "dbr_ontologies_entities_find")) {
+            assertThat(registry)
+                    .hasObservationWithNameEqualTo(metric);
+        }
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"modify-identifier-metadata", "delete-identifier"})
+    public void prometheusPersistenceEndpoint_succeeds() {
+
+        /* mock */
+        try {
+            persistenceEndpoint.find(IDENTIFIER_1_ID, null, USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            persistenceEndpoint.update(IDENTIFIER_1_ID, IDENTIFIER_1_DTO_REQUEST, USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            persistenceEndpoint.delete(IDENTIFIER_1_ID);
+        } catch (Exception e) {
+            /* ignore */
+        }
+
+        /* test */
+        for (String metric : List.of("dbr_pid_find", "dbr_pid_update", "dbr_pid_delete")) {
+            assertThat(registry)
+                    .hasObservationWithNameEqualTo(metric);
+        }
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"execute-query"})
+    public void prometheusQueryEndpoint_succeeds() {
+
+        /* mock */
+        try {
+            queryEndpoint.execute(DATABASE_1_ID, ExecuteStatementDto.builder().statement("SELECT 1").build(), null, null, USER_1_PRINCIPAL, null, null);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            queryEndpoint.reExecute(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, null, null, null, null);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            queryEndpoint.reExecuteCount(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            queryEndpoint.export(DATABASE_1_ID, QUERY_1_ID, null, USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+
+        /* test */
+        for (String metric : List.of("dbr_query_execute", "dbr_query_reexecute", "dbr_query_reexecute_count", "dbr_query_export")) {
+            assertThat(registry)
+                    .hasObservationWithNameEqualTo(metric);
+        }
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"create-semantic-concept", "create-semantic-unit", "table-semantic-analyse"})
+    public void prometheusSemanticsEndpoint_succeeds() {
+
+        /* mock */
+        try {
+            semanticsEndpoint.findAllConcepts();
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            semanticsEndpoint.saveConcept(COLUMN_CONCEPT_FAIR_DATA_SAVE_DTO);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            semanticsEndpoint.findAllUnits();
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            semanticsEndpoint.saveUnit(UNIT_1_SAVE_DTO);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            semanticsEndpoint.analyseTable(DATABASE_1_ID, TABLE_1_ID);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            semanticsEndpoint.analyseTableColumn(DATABASE_1_ID, TABLE_1_ID, COLUMN_1_1_ID);
+        } catch (Exception e) {
+            /* ignore */
+        }
+
+        /* test */
+        for (String metric : List.of("dbr_semantic_concepts_findall", "dbr_semantic_concepts_save", "dbr_semantic_units_findall", "dbr_semantic_units_save", "dbr_semantic_table_analyse", "dbr_semantic_column_analyse")) {
+            assertThat(registry)
+                    .hasObservationWithNameEqualTo(metric);
+        }
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"persist-query"})
+    public void prometheusStoreEndpoint_succeeds() {
+
+        /* mock */
+        try {
+            storeEndpoint.findAll(DATABASE_1_ID, true, USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            storeEndpoint.find(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            storeEndpoint.persist(DATABASE_1_ID, QUERY_1_ID, QueryPersistDto.builder().persist(true).build(), USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+
+        /* test */
+        for (String metric : List.of("dbr_queries_findall", "dbr_queries_find", "dbr_query_persist")) {
+            assertThat(registry)
+                    .hasObservationWithNameEqualTo(metric);
+        }
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"modify-table-column-semantics", "modify-foreign-table-column-semantics"})
+    public void prometheusTableColumnEndpoint_succeeds() {
+
+        /* mock */
+        try {
+            tableColumnEndpoint.update(DATABASE_1_ID, TABLE_1_ID, COLUMN_1_4_ID, COLUMN_1_4_SEMANTICS_UPDATE_DTO, USER_1_PRINCIPAL, "s3cr3t");
+        } catch (Exception e) {
+            /* ignore */
+        }
+
+        /* test */
+        assertThat(registry)
+                .hasObservationWithNameEqualTo("dbr_semantics_column_save");
+    }
+
+    @Test
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"insert-table-data", "delete-table-data"})
+    public void prometheusTableDataEndpoint_succeeds() {
+
+        /* mock */
+        try {
+            tableDataEndpoint.insert(DATABASE_1_ID, TABLE_1_ID, TableCsvDto.builder().build(), USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            tableDataEndpoint.update(DATABASE_1_ID, TABLE_1_ID, TableCsvUpdateDto.builder().build(), USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            tableDataEndpoint.delete(DATABASE_1_ID, TABLE_1_ID, TableCsvDeleteDto.builder().build(), USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            tableDataEndpoint.importCsv(DATABASE_1_ID, TABLE_1_ID, ImportDto.builder().build(), USER_1_PRINCIPAL);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            tableDataEndpoint.getAll(DATABASE_1_ID, TABLE_1_ID, USER_1_PRINCIPAL, null, null, null, null, null);
+        } catch (Exception e) {
+            /* ignore */
+        }
+        try {
+            tableDataEndpoint.getCount(DATABASE_1_ID, TABLE_1_ID, USER_1_PRINCIPAL, null);
+        } catch (Exception e) {
+            /* ignore */
+        }
+
+        /* test */
+        for (String metric : List.of("dbr_table_data_insert", "dbr_table_data_update", "dbr_table_data_delete", "dbr_table_data_import", "dbr_table_data_findall", "dbr_table_data_countall")) {
+            assertThat(registry)
+                    .hasObservationWithNameEqualTo(metric);
+        }
+    }
+
 }