From c7bd6c8bde8362a8651830257b80afdcbb7b65eb Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 8 Aug 2022 21:34:00 +1200 Subject: [PATCH] Support a naming convention function that can be applied to metrics names for reporting For example, can apply a lower case underscore naming convention to the metrics names. This can be done such that it doesn't have to be applied every time the metrics are collected and reported. --- .../java/io/ebean/config/DatabaseConfig.java | 18 +++++++ .../io/ebean/meta/BasicMetricVisitor.java | 16 +++++-- .../java/io/ebean/meta/MetricNamingMatch.java | 16 +++++++ .../java/io/ebean/meta/MetricVisitor.java | 7 +++ .../server/core/DefaultMetaInfoManager.java | 26 +++++----- .../server/core/DefaultServer.java | 2 +- .../server/deploy/BeanDescriptor.java | 2 +- .../server/profile/DCountMetric.java | 8 ++++ .../server/profile/DQueryPlanMetric.java | 16 +++++-- .../server/profile/DTimedMetric.java | 33 ++++++++----- .../server/profile/DTimedProfileLocation.java | 13 +++-- .../server/query/CQueryPlan.java | 5 +- .../server/query/CQueryPlanStats.java | 21 +++++++-- .../profile/BasicProfileLocationTest.java | 43 +++++++++++++++++ .../server/profile/DCountMetricTest.java | 43 +++++++++++++++++ .../server/profile/DQueryPlanMetricTest.java | 47 +++++++++++++++++++ .../server/profile/DTimedMetricTest.java | 38 +++++++++++++++ .../io/ebean/xtest/base/DtoQuery2Test.java | 7 ++- .../io/ebean/xtest/base/DtoQueryTest.java | 3 +- 19 files changed, 314 insertions(+), 50 deletions(-) create mode 100644 ebean-api/src/main/java/io/ebean/meta/MetricNamingMatch.java create mode 100644 ebean-core/src/test/java/io/ebeaninternal/server/profile/DCountMetricTest.java create mode 100644 ebean-core/src/test/java/io/ebeaninternal/server/profile/DQueryPlanMetricTest.java diff --git a/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java b/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java index 8dc39b17f..0ed96efda 100644 --- a/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java +++ b/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java @@ -16,6 +16,7 @@ import io.ebean.event.changelog.ChangeLogPrepare; import io.ebean.event.changelog.ChangeLogRegister; import io.ebean.event.readaudit.ReadAuditLogger; import io.ebean.event.readaudit.ReadAuditPrepare; +import io.ebean.meta.MetricNamingMatch; import io.ebean.util.StringHelper; import javax.persistence.EnumType; @@ -24,6 +25,7 @@ import java.time.Clock; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.*; +import java.util.function.Function; /** * The configuration used for creating a Database. @@ -546,6 +548,8 @@ public class DatabaseConfig { private String dumpMetricsOptions; + private Function metricNaming = MetricNamingMatch.INSTANCE; + /** * Construct a Database Configuration for programmatically creating an Database. */ @@ -3396,6 +3400,20 @@ public class DatabaseConfig { this.loadModuleInfo = loadModuleInfo; } + /** + * Return the naming convention to apply to metrics names. + */ + public Function getMetricNaming() { + return metricNaming; + } + + /** + * Set the naming convention to apply to metrics names. + */ + public void setMetricNaming(Function metricNaming) { + this.metricNaming = metricNaming; + } + public enum UuidVersion { VERSION4, VERSION1, diff --git a/ebean-api/src/main/java/io/ebean/meta/BasicMetricVisitor.java b/ebean-api/src/main/java/io/ebean/meta/BasicMetricVisitor.java index a95ca0b5a..653068a98 100644 --- a/ebean-api/src/main/java/io/ebean/meta/BasicMetricVisitor.java +++ b/ebean-api/src/main/java/io/ebean/meta/BasicMetricVisitor.java @@ -2,6 +2,7 @@ package io.ebean.meta; import java.util.ArrayList; import java.util.List; +import java.util.function.Function; /** * A simple MetricVisitor that can collect the desired metrics into lists. @@ -9,27 +10,29 @@ import java.util.List; public class BasicMetricVisitor extends AbstractMetricVisitor implements ServerMetrics { private final String name; + private final Function naming; private final List timed = new ArrayList<>(); private final List query = new ArrayList<>(); private final List count = new ArrayList<>(); public BasicMetricVisitor() { - this("db"); + this("db", MetricNamingMatch.INSTANCE); } /** * Construct to reset and collect everything. */ - public BasicMetricVisitor(String name) { - this(name, true, true, true, true); + public BasicMetricVisitor(String name, Function naming) { + this(name, naming, true, true, true, true); } /** * Construct specifying reset and what to collect. */ - public BasicMetricVisitor(String name, boolean reset, boolean collectTransactionMetrics, boolean collectQueryMetrics, boolean collectL2Metrics) { + public BasicMetricVisitor(String name, Function naming, boolean reset, boolean collectTransactionMetrics, boolean collectQueryMetrics, boolean collectL2Metrics) { super(reset, collectTransactionMetrics, collectQueryMetrics, collectL2Metrics); this.name = name; + this.naming = naming; } @Override @@ -37,6 +40,11 @@ public class BasicMetricVisitor extends AbstractMetricVisitor implements ServerM return name; } + @Override + public Function namingConvention() { + return naming; + } + @Override public ServerMetricsAsJson asJson() { return new MetricsAsJson(this); diff --git a/ebean-api/src/main/java/io/ebean/meta/MetricNamingMatch.java b/ebean-api/src/main/java/io/ebean/meta/MetricNamingMatch.java new file mode 100644 index 000000000..a67469611 --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/meta/MetricNamingMatch.java @@ -0,0 +1,16 @@ +package io.ebean.meta; + +import java.util.function.Function; + +/** + * Metric naming convention that is exact match. + */ +public final class MetricNamingMatch implements Function { + + public static final Function INSTANCE = new MetricNamingMatch(); + + @Override + public String apply(String name) { + return name; + } +} diff --git a/ebean-api/src/main/java/io/ebean/meta/MetricVisitor.java b/ebean-api/src/main/java/io/ebean/meta/MetricVisitor.java index fac9f050e..519c13d8f 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetricVisitor.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetricVisitor.java @@ -1,10 +1,17 @@ package io.ebean.meta; +import java.util.function.Function; + /** * Defines visitor to read and report the transaction and query metrics. */ public interface MetricVisitor { + /** + * Return the naming convention that should be applied to the reported metric names. + */ + Function namingConvention(); + /** * Return true if the metrics should be reset. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultMetaInfoManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultMetaInfoManager.java index 4ce02d910..b4a29697c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultMetaInfoManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultMetaInfoManager.java @@ -1,20 +1,9 @@ package io.ebeaninternal.server.core; -import io.ebean.meta.AbstractMetricVisitor; -import io.ebean.meta.BasicMetricVisitor; -import io.ebean.meta.MetaCountMetric; -import io.ebean.meta.MetaInfoManager; -import io.ebean.meta.MetaQueryMetric; -import io.ebean.meta.MetaQueryPlan; -import io.ebean.meta.MetaTimedMetric; -import io.ebean.meta.MetricData; -import io.ebean.meta.MetricVisitor; -import io.ebean.meta.QueryPlanInit; -import io.ebean.meta.QueryPlanRequest; -import io.ebean.meta.ServerMetrics; -import io.ebean.meta.ServerMetricsAsJson; +import io.ebean.meta.*; import java.util.List; +import java.util.function.Function; /** * DefaultServer based implementation of MetaInfoManager. @@ -22,9 +11,11 @@ import java.util.List; final class DefaultMetaInfoManager implements MetaInfoManager { private final DefaultServer server; + private final Function naming; - DefaultMetaInfoManager(DefaultServer server) { + DefaultMetaInfoManager(DefaultServer server, Function naming) { this.server = server; + this.naming = naming; } @Override @@ -49,7 +40,7 @@ final class DefaultMetaInfoManager implements MetaInfoManager { @Override public BasicMetricVisitor visitBasic() { - BasicMetricVisitor basic = new BasicMetricVisitor(server.name()); + BasicMetricVisitor basic = new BasicMetricVisitor(server.name(), naming); visitMetrics(basic); return basic; } @@ -68,6 +59,11 @@ final class DefaultMetaInfoManager implements MetaInfoManager { super(true, true, true, true); } + @Override + public Function namingConvention() { + return MetricNamingMatch.INSTANCE; + } + @Override public void visitTimed(MetaTimedMetric metric) { // ignore diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index f8d7ff419..222a7af1f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -213,7 +213,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { this.transactionManager = config.createTransactionManager(this, docStoreComponents.updateProcessor()); this.documentStore = docStoreComponents.documentStore(); this.queryPlanManager = config.initQueryPlanManager(transactionManager); - this.metaInfoManager = new DefaultMetaInfoManager(this); + this.metaInfoManager = new DefaultMetaInfoManager(this, this.config.getMetricNaming()); this.serverPlugins = config.getPlugins(); this.ddlGenerator = config.initDdlGenerator(this); this.scriptRunner = new DScriptRunner(this); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index e8d8f2d04..08804a53d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -1482,7 +1482,7 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { iudMetrics.visit(visitor); for (CQueryPlan queryPlan : queryPlanCache.values()) { if (!queryPlan.isEmptyStats()) { - visitor.visitQuery(queryPlan.getSnapshot(visitor.reset())); + visitor.visitQuery(queryPlan.visit(visitor)); } } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java index 962c6ce22..34c47cfc6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java @@ -13,6 +13,7 @@ final class DCountMetric implements CountMetric { private final String name; private final LongAdder count = new LongAdder(); + private String reportName; DCountMetric(String name) { this.name = name; @@ -50,10 +51,17 @@ final class DCountMetric implements CountMetric { public void visit(MetricVisitor visitor) { long val = visitor.reset() ? count.sumThenReset() : count.sum(); if (val > 0) { + final String name = reportName != null ? reportName : reportName(visitor); visitor.visitCount(new DCountMetricStats(name, val)); } } + String reportName(MetricVisitor visitor) { + final String tmp = visitor.namingConvention().apply(name); + this.reportName = tmp; + return tmp; + } + private static class DCountMetricStats implements CountMetricStats { private final String name; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java index 2490db52d..183a5d457 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java @@ -11,6 +11,7 @@ final class DQueryPlanMetric implements QueryPlanMetric { private final DQueryPlanMeta meta; private final DTimedMetric metric; private boolean collected; + private String reportName; DQueryPlanMetric(DQueryPlanMeta meta, DTimedMetric metric) { this.meta = meta; @@ -21,11 +22,18 @@ final class DQueryPlanMetric implements QueryPlanMetric { public void visit(MetricVisitor visitor) { TimedMetricStats stats = metric.collect(visitor.reset()); if (stats != null) { - visitor.visitQuery(new Stats(meta, stats, collected)); + String name = reportName != null ? reportName : reportName(visitor); + visitor.visitQuery(new Stats(name, meta, stats, collected)); collected = true; } } + String reportName(MetricVisitor visitor) { + final String tmp = visitor.namingConvention().apply(meta.getName()); + this.reportName = tmp; + return tmp; + } + @Override public TimedMetric metric() { return metric; @@ -33,11 +41,13 @@ final class DQueryPlanMetric implements QueryPlanMetric { private static class Stats implements MetaQueryMetric { + private final String name; private final DQueryPlanMeta meta; private final TimedMetricStats stats; private final boolean collected; - private Stats(DQueryPlanMeta meta, TimedMetricStats stats, boolean collected) { + private Stats(String name, DQueryPlanMeta meta, TimedMetricStats stats, boolean collected) { + this.name = name; this.meta = meta; this.stats = stats; this.collected = collected; @@ -75,7 +85,7 @@ final class DQueryPlanMetric implements QueryPlanMetric { @Override public String name() { - return meta.getName(); + return name; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java index a62fef911..f79d129ae 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java @@ -19,6 +19,7 @@ final class DTimedMetric implements TimedMetric { private final LongAdder total = new LongAdder(); private final LongAccumulator max = new LongAccumulator(Math::max, Long.MIN_VALUE); private boolean collected; + private String reportName; DTimedMetric(String name) { this.name = name; @@ -40,9 +41,6 @@ final class DTimedMetric implements TimedMetric { add((System.nanoTime() - startNanos) / 1000L); } - /** - * Add a value. Usually the value is Time or Bytes etc. - */ @Override public void add(long value) { count.increment(); @@ -55,9 +53,6 @@ final class DTimedMetric implements TimedMetric { return count.sum() == 0; } - /** - * Reset all the internal counters and start time. - */ @Override public void reset() { max.reset(); @@ -67,30 +62,42 @@ final class DTimedMetric implements TimedMetric { @Override public void visit(MetricVisitor visitor) { - DTimeMetricStats metric = collect(visitor.reset()); - if (metric != null) { - visitor.visitTimed(metric); + final long countSum = visitor.reset() ? count.sumThenReset() : count.sum(); + if (countSum > 0) { + final String name = reportName != null ? reportName : reportName(visitor); + visitor.visitTimed(stats(visitor.reset(), name, countSum)); } } @Override public DTimeMetricStats collect(boolean reset) { - return (count.sum() == 0) ? null : getStatistics(reset); + final long countSum = reset ? count.sumThenReset() : count.sum(); + if (countSum == 0) { + return null; + } else { + return stats(reset, name, countSum); + } } /** * Return the current statistics resetting the internal values if reset is true. */ - private DTimeMetricStats getStatistics(boolean reset) { + private DTimeMetricStats stats(boolean reset, String name, long countSum) { try { if (reset) { - return new DTimeMetricStats(name, collected, count.sumThenReset(), total.sumThenReset(), max.getThenReset()); + return new DTimeMetricStats(name, collected, countSum, total.sumThenReset(), max.getThenReset()); } else { - return new DTimeMetricStats(name, collected, count.sum(), total.sum(), max.get()); + return new DTimeMetricStats(name, collected, countSum, total.sum(), max.get()); } } finally { collected = true; } } + String reportName(MetricVisitor visitor) { + final String tmp = visitor.namingConvention().apply(name); + this.reportName = tmp; + return tmp; + } + } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java index 2164f86c7..9039a6751 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java @@ -13,6 +13,7 @@ final class DTimedProfileLocation extends DProfileLocation implements TimedProfi private final TimedMetric timedMetric; private final boolean overrideMetricName; private String fullName; + private String reportName; DTimedProfileLocation(int lineNumber, String label, TimedMetric timedMetric) { super(lineNumber); @@ -47,11 +48,17 @@ final class DTimedProfileLocation extends DProfileLocation implements TimedProfi public void visit(MetricVisitor visitor) { TimedMetricStats collect = timedMetric.collect(visitor.reset()); if (collect != null) { - if (overrideMetricName) { - collect.setName(fullName); - } + final String name = reportName != null ? reportName : reportName(visitor, collect.name()); + collect.setName(name); collect.setLocation(location()); visitor.visitTimed(collect); } } + + private String reportName(MetricVisitor visitor, String name) { + final String defaultName = overrideMetricName ? fullName : name; + final String tmp = visitor.namingConvention().apply(defaultName); + this.reportName = tmp; + return tmp; + } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java index d07276920..5ce73fc62 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java @@ -4,6 +4,7 @@ import io.ebean.ProfileLocation; import io.ebean.config.dbplatform.SqlLimitResponse; import io.ebean.core.type.DataReader; import io.ebean.core.type.ScalarDataReader; +import io.ebean.meta.MetricVisitor; import io.ebean.metric.MetricFactory; import io.ebean.metric.TimedMetric; import io.ebeaninternal.api.*; @@ -279,8 +280,8 @@ public class CQueryPlan implements SpiQueryPlan { /** * Return a copy of the current query statistics. */ - public final Snapshot getSnapshot(boolean reset) { - return stats.getSnapshot(reset); + public final Snapshot visit(MetricVisitor visitor) { + return stats.visit(visitor); } /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java index 6733cfb6f..6b6c3d66e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.query; import io.ebean.meta.MetaQueryMetric; +import io.ebean.meta.MetricVisitor; import io.ebean.metric.TimedMetric; import io.ebean.metric.TimedMetricStats; @@ -13,6 +14,7 @@ public final class CQueryPlanStats { private final TimedMetric timedMetric; private boolean collected; private long lastQueryTime; + private String reportName; /** * Construct for a given query plan. @@ -55,23 +57,32 @@ public final class CQueryPlanStats { /** * Return a Snapshot of the query execution statistics potentially resetting the internal counters. */ - Snapshot getSnapshot(boolean reset) { - TimedMetricStats collect = timedMetric.collect(reset); - Snapshot snapshot = new Snapshot(collected, queryPlan, collect); + Snapshot visit(MetricVisitor visitor) { + TimedMetricStats collect = timedMetric.collect(visitor.reset()); + String name = reportName != null ? reportName : reportName(visitor); + Snapshot snapshot = new Snapshot(name, collected, queryPlan, collect); collected = true; return snapshot; } + String reportName(MetricVisitor visitor) { + final String tmp = visitor.namingConvention().apply(queryPlan.getName()); + this.reportName = tmp; + return tmp; + } + /** * A snapshot of the current statistics for a query plan. */ static class Snapshot implements MetaQueryMetric { + private final String name; private final boolean collected; private final CQueryPlan queryPlan; private final TimedMetricStats metrics; - Snapshot(boolean collected, CQueryPlan queryPlan, TimedMetricStats metrics) { + Snapshot(String name, boolean collected, CQueryPlan queryPlan, TimedMetricStats metrics) { + this.name = name; this.collected = collected; this.queryPlan = queryPlan; this.metrics = metrics; @@ -94,7 +105,7 @@ public final class CQueryPlanStats { @Override public String name() { - return queryPlan.getName(); + return name; } @Override diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java index ea33744b8..f93e12979 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java @@ -1,12 +1,55 @@ package io.ebeaninternal.server.profile; +import io.ebean.meta.BasicMetricVisitor; +import io.ebean.meta.MetaTimedMetric; import io.ebean.metric.MetricFactory; import org.junit.jupiter.api.Test; +import java.util.List; +import java.util.function.Function; + import static org.assertj.core.api.Assertions.assertThat; class BasicProfileLocationTest { + Function naming = (String name) -> "prefix[" + name.replace('.', '-') + "]"; + + @Test + void metricNameFromOverride() { + DTimedProfileLocation loc = new DTimedProfileLocation(12, "", MetricFactory.get().createTimedMetric("a.b.c")); + loc.initWith("foo.label"); + loc.add(42); + + BasicMetricVisitor visitor = new BasicMetricVisitor("v", naming); + loc.visit(visitor); + + List result = visitor.timedMetrics(); + assertThat(result).hasSize(1); + assertThat(result.get(0).name()).isEqualTo("prefix[txn-named-foo-label]"); + assertThat(result.get(0).total()).isEqualTo(42); + + loc.add(21); + BasicMetricVisitor visitor2 = new BasicMetricVisitor("v", naming); + loc.visit(visitor2); + List result2 = visitor2.timedMetrics(); + assertThat(result2).hasSize(1); + assertThat(result2.get(0).name()).isEqualTo("prefix[txn-named-foo-label]"); + assertThat(result2.get(0).total()).isEqualTo(21); + } + + @Test + void metricNameFromTimed() { + DTimedProfileLocation loc = new DTimedProfileLocation(12, "foo", MetricFactory.get().createTimedMetric("a.b.c")); + loc.add(42); + + BasicMetricVisitor visitor = new BasicMetricVisitor("v", naming); + loc.visit(visitor); + + List result = visitor.timedMetrics(); + assertThat(result).hasSize(1); + assertThat(result.get(0).name()).isEqualTo("prefix[a-b-c]"); + } + @Test void obtain() { DProfileLocation loc = new DTimedProfileLocation(12, "foo", MetricFactory.get().createTimedMetric("junk")); diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/DCountMetricTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/DCountMetricTest.java new file mode 100644 index 000000000..0abf64666 --- /dev/null +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/DCountMetricTest.java @@ -0,0 +1,43 @@ +package io.ebeaninternal.server.profile; + +import io.ebean.meta.BasicMetricVisitor; +import io.ebean.meta.MetaCountMetric; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.function.Function; + +import static org.assertj.core.api.Assertions.assertThat; + +class DCountMetricTest { + + Function naming = (String name) -> "prefix[" + name.replace('.', '-') + "]"; + + @Test + void visit() { + + DCountMetric counter = new DCountMetric("org.hello"); + counter.add(7); + { + BasicMetricVisitor visitor = new BasicMetricVisitor("v", naming); + counter.visit(visitor); + List result = visitor.countMetrics(); + + assertThat(result).hasSize(1); + assertThat(result.get(0).name()).isEqualTo("prefix[org-hello]"); + assertThat(result.get(0).count()).isEqualTo(7); + } + { + // second collection + counter.add(4); + counter.add(8); + BasicMetricVisitor visitor2 = new BasicMetricVisitor("v", naming); + counter.visit(visitor2); + + List result2 = visitor2.countMetrics(); + assertThat(result2).hasSize(1); + assertThat(result2.get(0).name()).isEqualTo("prefix[org-hello]"); + assertThat(result2.get(0).count()).isEqualTo(12); + } + } +} diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/DQueryPlanMetricTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/DQueryPlanMetricTest.java new file mode 100644 index 000000000..9d4c85f41 --- /dev/null +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/DQueryPlanMetricTest.java @@ -0,0 +1,47 @@ +package io.ebeaninternal.server.profile; + +import io.ebean.meta.BasicMetricVisitor; +import io.ebean.meta.MetaQueryMetric; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.function.Function; + +import static org.assertj.core.api.Assertions.assertThat; + +class DQueryPlanMetricTest { + + Function naming = (String name) -> "prefix[" + name.replace('.', '-') + "]"; + + @Test + void visit() { + + DQueryPlanMeta meta = new DQueryPlanMeta(Object.class, "lab", null, "sql"); + DTimedMetric metric = new DTimedMetric("org.timed.plan"); + DQueryPlanMetric planMetric = new DQueryPlanMetric(meta, metric); + + metric.add(560); + metric.add(260); + { + BasicMetricVisitor visitor = new BasicMetricVisitor("v", naming); + planMetric.visit(visitor); + List result = visitor.queryMetrics(); + + assertThat(result).hasSize(1); + assertThat(result.get(0).name()).isEqualTo("prefix[dto-Object_lab]"); + assertThat(result.get(0).count()).isEqualTo(2); + assertThat(result.get(0).total()).isEqualTo(820); + } + metric.add(410); + { + BasicMetricVisitor visitor = new BasicMetricVisitor("v", naming); + planMetric.visit(visitor); + List result = visitor.queryMetrics(); + + assertThat(result).hasSize(1); + assertThat(result.get(0).name()).isEqualTo("prefix[dto-Object_lab]"); + assertThat(result.get(0).count()).isEqualTo(1); + assertThat(result.get(0).total()).isEqualTo(410); + } + } +} diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricTest.java index 782289661..f3b6fc5fd 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricTest.java @@ -1,7 +1,12 @@ package io.ebeaninternal.server.profile; +import io.ebean.meta.BasicMetricVisitor; +import io.ebean.meta.MetaTimedMetric; import org.junit.jupiter.api.Test; +import java.util.List; +import java.util.function.Function; + import static org.assertj.core.api.Assertions.assertThat; public class DTimedMetricTest { @@ -52,4 +57,37 @@ public class DTimedMetricTest { assertThat(stats.total()).isGreaterThan(10000); assertThat(stats.max()).isEqualTo(stats.total() / 2); } + + Function naming = (String name) -> "prefix[" + name.replace('.', '-') + "]"; + + @Test + void visit() { + DTimedMetric metric = new DTimedMetric("org.timed"); + metric.add(560); + metric.add(500); + { + BasicMetricVisitor visitor = new BasicMetricVisitor("v", naming); + metric.visit(visitor); + List result = visitor.timedMetrics(); + + assertThat(result).hasSize(1); + assertThat(result.get(0).name()).isEqualTo("prefix[org-timed]"); + assertThat(result.get(0).count()).isEqualTo(2); + assertThat(result.get(0).total()).isEqualTo(1060); + } + + metric.add(160); + metric.add(100); + metric.add(150); + { + BasicMetricVisitor visitor = new BasicMetricVisitor("v", naming); + metric.visit(visitor); + List result = visitor.timedMetrics(); + + assertThat(result).hasSize(1); + assertThat(result.get(0).name()).isEqualTo("prefix[org-timed]"); + assertThat(result.get(0).count()).isEqualTo(3); + assertThat(result.get(0).total()).isEqualTo(410); + } + } } diff --git a/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java b/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java index 5c62ac653..2cfd8ec41 100644 --- a/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java +++ b/ebean-test/src/test/java/io/ebean/xtest/base/DtoQuery2Test.java @@ -14,6 +14,7 @@ import org.tests.model.basic.ResetBasicData; import java.util.List; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -209,8 +210,10 @@ public class DtoQuery2Test extends BaseTestCase { log.info("Found " + custs); } + Function lowerUnderscore = (String key) -> "prefix:" + key.replace('.','_').toLowerCase(); + // collect without reset - BasicMetricVisitor basic = new BasicMetricVisitor("db", false, true, true, true); + BasicMetricVisitor basic = new BasicMetricVisitor("db", lowerUnderscore, false, true, true, true); server().metaInfo().visitMetrics(basic); List stats = basic.queryMetrics(); @@ -219,7 +222,7 @@ public class DtoQuery2Test extends BaseTestCase { MetaQueryMetric queryMetric = stats.get(0); assertThat(queryMetric.label()).isEqualTo("basic"); assertThat(queryMetric.count()).isEqualTo(3); - assertThat(queryMetric.name()).isEqualTo("dto.DCust_basic"); + assertThat(queryMetric.name()).isEqualTo("prefix:dto_dcust_basic"); server().findDto(DCust.class, "select c4.id, c4.name from o_customer c4 where lower(c4.name) = :name") diff --git a/ebean-test/src/test/java/io/ebean/xtest/base/DtoQueryTest.java b/ebean-test/src/test/java/io/ebean/xtest/base/DtoQueryTest.java index c1576f135..fc4c3615e 100644 --- a/ebean-test/src/test/java/io/ebean/xtest/base/DtoQueryTest.java +++ b/ebean-test/src/test/java/io/ebean/xtest/base/DtoQueryTest.java @@ -1,5 +1,6 @@ package io.ebean.xtest.base; +import io.ebean.meta.MetricNamingMatch; import io.ebean.xtest.BaseTestCase; import io.ebean.DB; import io.ebean.DtoQuery; @@ -286,7 +287,7 @@ class DtoQueryTest extends BaseTestCase { } // collect without reset - BasicMetricVisitor basic = new BasicMetricVisitor("db", false, true, true, true); + BasicMetricVisitor basic = new BasicMetricVisitor("db", MetricNamingMatch.INSTANCE, false, true, true, true); server().metaInfo().visitMetrics(basic); List stats = basic.queryMetrics();