From a29da6d7bbfbf51827c293a9c996e207368de956 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Fri, 23 Oct 2026 15:44:35 -0700 Subject: [PATCH 1/3] Describe Specimen usage metrics --- .../org/labkey/specimen/SpecimenModule.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/specimen/src/org/labkey/specimen/SpecimenModule.java b/specimen/src/org/labkey/specimen/SpecimenModule.java index 212e54d1..02024275 100644 --- a/specimen/src/org/labkey/specimen/SpecimenModule.java +++ b/specimen/src/org/labkey/specimen/SpecimenModule.java @@ -107,13 +107,24 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; public class SpecimenModule extends SpringModule { private static final Logger LOG = LogHelper.getLogger(SpecimenModule.class, "Specimen metrics"); public static final String NAME = "Specimen"; + // Counts are reported only when non-zero + private static final Map SPECIMEN_COUNT_DESCRIPTIONS = Map.of( + "simple", "Studies using a simple specimen repository", + "simpleSpecimens", "Specimens across all simple specimen repositories", + "advanced", "Studies using an advanced specimen repository", + "events", "Specimen events across all advanced specimen repositories", + "vials", "Vials across all advanced specimen repositories", + "specimens", "Specimens (vial groupings) across all advanced specimen repositories", + "locations", "Specimen locations summed across all studies", + "locationsInUse", "Specimen locations marked in use, summed across all studies" + ); + @Override public String getName() { @@ -299,7 +310,7 @@ protected void startupAfterSpringConfig(ModuleContext moduleContext) if (null != ss) { - svc.registerUsageMetrics(NAME, () -> { + svc.registerUsageMetrics(NAME, metrics -> { // Collect and add specimen repository statistics: simple vs. advanced study count, event/vial/specimen count, count of studies with requests enabled, request count by status MultiSet specimenMultiSet = new HashMultiSet<>(); MutableInt requestsEnabled = new MutableInt(0); @@ -340,13 +351,18 @@ protected void startupAfterSpringConfig(ModuleContext moduleContext) LOG.debug(specimenMultiSet.toString()); }); - Map specimensMap = specimenMultiSet.uniqueSet().stream().collect(Collectors.toMap(s -> s, specimenMultiSet::getCount)); + SPECIMEN_COUNT_DESCRIPTIONS.forEach(metrics::describe); + specimenMultiSet.uniqueSet().forEach(s -> { + String description = SPECIMEN_COUNT_DESCRIPTIONS.get(s); + assert description != null : "No usage metric description for specimen count " + s; + metrics.put(s, specimenMultiSet.getCount(s), description); + }); Map requestsMap = new SqlSelector(SpecimenSchema.get().getSchema(), new SQLFragment("SELECT Label, COUNT(*) FROM study.SampleRequest INNER JOIN study.SampleRequestStatus srs ON StatusId = srs.RowId GROUP BY Label")).getValueMap(String.class); requestsMap.put("enabled", requestsEnabled); - specimensMap.put("requests", requestsMap); - specimensMap.put("hasLocations", hasLocations.intValue()); + metrics.put("requests", requestsMap, "Specimen requests across the server by status label, plus enabled: studies with specimen requests enabled"); + metrics.put("hasLocations", hasLocations.intValue(), "Studies with at least one specimen location"); - return specimensMap; + return metrics; }); } } From a0151f146282bfa89fa334194d600db6d653b3d8 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Fri, 23 Oct 2026 18:22:24 -0700 Subject: [PATCH 2/3] Claude review --- .../src/org/labkey/specimen/SpecimenModule.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/specimen/src/org/labkey/specimen/SpecimenModule.java b/specimen/src/org/labkey/specimen/SpecimenModule.java index 02024275..a5cd94c2 100644 --- a/specimen/src/org/labkey/specimen/SpecimenModule.java +++ b/specimen/src/org/labkey/specimen/SpecimenModule.java @@ -122,7 +122,7 @@ public class SpecimenModule extends SpringModule "vials", "Vials across all advanced specimen repositories", "specimens", "Specimens (vial groupings) across all advanced specimen repositories", "locations", "Specimen locations summed across all studies", - "locationsInUse", "Specimen locations marked in use, summed across all studies" + "locationsInUse", "Specimen locations flagged in use or referenced by specimen requests or other study data, summed across all studies" ); @Override @@ -351,15 +351,13 @@ protected void startupAfterSpringConfig(ModuleContext moduleContext) LOG.debug(specimenMultiSet.toString()); }); - SPECIMEN_COUNT_DESCRIPTIONS.forEach(metrics::describe); - specimenMultiSet.uniqueSet().forEach(s -> { - String description = SPECIMEN_COUNT_DESCRIPTIONS.get(s); - assert description != null : "No usage metric description for specimen count " + s; - metrics.put(s, specimenMultiSet.getCount(s), description); + SPECIMEN_COUNT_DESCRIPTIONS.forEach((key, description) -> { + int count = specimenMultiSet.getCount(key); + metrics.reportedIf(count > 0).put(key, count, description); }); Map requestsMap = new SqlSelector(SpecimenSchema.get().getSchema(), new SQLFragment("SELECT Label, COUNT(*) FROM study.SampleRequest INNER JOIN study.SampleRequestStatus srs ON StatusId = srs.RowId GROUP BY Label")).getValueMap(String.class); - requestsMap.put("enabled", requestsEnabled); - metrics.put("requests", requestsMap, "Specimen requests across the server by status label, plus enabled: studies with specimen requests enabled"); + metrics.group("requests", "Specimen requests across the server, by status label").putAll(requestsMap); + metrics.put("requestsEnabled", requestsEnabled.intValue(), "Studies with specimen requests enabled"); metrics.put("hasLocations", hasLocations.intValue(), "Studies with at least one specimen location"); return metrics; From a8ade52e02f83dabaa8657d54da13d1908a4f808 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Tue, 27 Oct 2026 10:58:43 -0700 Subject: [PATCH 3/3] Claude review --- specimen/src/org/labkey/specimen/SpecimenModule.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specimen/src/org/labkey/specimen/SpecimenModule.java b/specimen/src/org/labkey/specimen/SpecimenModule.java index a5cd94c2..815abd8b 100644 --- a/specimen/src/org/labkey/specimen/SpecimenModule.java +++ b/specimen/src/org/labkey/specimen/SpecimenModule.java @@ -356,8 +356,9 @@ protected void startupAfterSpringConfig(ModuleContext moduleContext) metrics.reportedIf(count > 0).put(key, count, description); }); Map requestsMap = new SqlSelector(SpecimenSchema.get().getSchema(), new SQLFragment("SELECT Label, COUNT(*) FROM study.SampleRequest INNER JOIN study.SampleRequestStatus srs ON StatusId = srs.RowId GROUP BY Label")).getValueMap(String.class); - metrics.group("requests", "Specimen requests across the server, by status label").putAll(requestsMap); - metrics.put("requestsEnabled", requestsEnabled.intValue(), "Studies with specimen requests enabled"); + metrics.group("requests", "Specimen requests across the server, by status label") + .putAll(requestsMap) + .put("enabled", requestsEnabled.intValue(), "Studies with specimen requests enabled"); metrics.put("hasLocations", hasLocations.intValue(), "Studies with at least one specimen location"); return metrics;