mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#2293 - Metric hash back to MD5 of sql + name + loc (minus location file and line source) ~= Revert of #2288
This commit is contained in:
@@ -45,14 +45,6 @@ public interface ProfileLocation {
|
||||
*/
|
||||
String label();
|
||||
|
||||
/**
|
||||
* Return a hash of the location that intentionally excludes the line number.
|
||||
* <p>
|
||||
* The hash is expected to be stable regardless of line number in the source file
|
||||
* so that is identifies the class and method location over a long time.
|
||||
*/
|
||||
long hash();
|
||||
|
||||
/**
|
||||
* Return the full location.
|
||||
*/
|
||||
|
||||
@@ -45,15 +45,8 @@ public interface MetaQueryMetric extends MetaTimedMetric {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hash of the sql.
|
||||
* Return the hash of the plan.
|
||||
*/
|
||||
long sqlHash();
|
||||
String hash();
|
||||
|
||||
/**
|
||||
* Migrate to sqlHash().
|
||||
*/
|
||||
@Deprecated
|
||||
default long getSqlHash() {
|
||||
return sqlHash();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public interface MetaQueryPlan {
|
||||
/**
|
||||
* Return the hash of the plan.
|
||||
*/
|
||||
long sqlHash();
|
||||
String hash();
|
||||
|
||||
/**
|
||||
* Return a description of the bind values.
|
||||
|
||||
@@ -6,14 +6,6 @@ package io.ebean.meta;
|
||||
*/
|
||||
public interface MetaTimedMetric extends MetaMetric {
|
||||
|
||||
/**
|
||||
* Return the metric location hash if defined.
|
||||
* <p>
|
||||
* This hash excludes line number with the intention of being stable over time
|
||||
* as code changes move the source line (but the method is the same).
|
||||
*/
|
||||
long locationHash();
|
||||
|
||||
/**
|
||||
* Return the metric location if defined.
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,7 @@ package io.ebean.meta;
|
||||
public class MetricData {
|
||||
|
||||
private String name;
|
||||
private long sqlHash;
|
||||
private String hash;
|
||||
private String loc;
|
||||
private String sql;
|
||||
|
||||
@@ -14,7 +14,6 @@ public class MetricData {
|
||||
private Long mean;
|
||||
private Long max;
|
||||
private Long total;
|
||||
private long locHash;
|
||||
|
||||
public MetricData(String name) {
|
||||
this.name = name;
|
||||
@@ -31,20 +30,12 @@ public class MetricData {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getSqlHash() {
|
||||
return sqlHash;
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public void setSqlHash(long sqlHash) {
|
||||
this.sqlHash = sqlHash;
|
||||
}
|
||||
|
||||
public void setLocHash(long locHash) {
|
||||
this.locHash = locHash;
|
||||
}
|
||||
|
||||
public long getLocHash() {
|
||||
return locHash;
|
||||
public void setHash(String hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
public String getLoc() {
|
||||
|
||||
@@ -10,7 +10,7 @@ public class QueryPlanInit {
|
||||
|
||||
private boolean all;
|
||||
|
||||
private Set<Long> hashes = new HashSet<>();
|
||||
private Set<String> hashes = new HashSet<>();
|
||||
|
||||
private long thresholdMicros;
|
||||
|
||||
@@ -47,21 +47,21 @@ public class QueryPlanInit {
|
||||
/**
|
||||
* Return true if the query plan should be initiated based on it's hash.
|
||||
*/
|
||||
public boolean includeHash(long sqlHash) {
|
||||
return all || hashes.contains(sqlHash);
|
||||
public boolean includeHash(String hash) {
|
||||
return all || hashes.contains(hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the specific hashes that we want to collect query plans on.
|
||||
*/
|
||||
public Set<Long> sqlHashes() {
|
||||
public Set<String> hashes() {
|
||||
return hashes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the specific hashes that we want to collect query plans on.
|
||||
*/
|
||||
public void sqlHashes(Set<Long> hashes) {
|
||||
public void hashes(Set<String> hashes) {
|
||||
this.hashes = hashes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,6 @@ public interface TimedMetricStats extends MetaTimedMetric {
|
||||
*/
|
||||
void setLocation(String location);
|
||||
|
||||
/**
|
||||
* Additionally set the location hash.
|
||||
*/
|
||||
void setLocationHash(long locationHash);
|
||||
|
||||
/**
|
||||
* Override the name based on profile location.
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,7 @@ public interface SpiQueryPlan {
|
||||
/**
|
||||
* The hash of the sql.
|
||||
*/
|
||||
long getSqlHash();
|
||||
String getHash();
|
||||
|
||||
/**
|
||||
* The SQL for the query plan.
|
||||
|
||||
@@ -120,7 +120,7 @@ class DumpMetrics {
|
||||
appendQueryName(metric, sb);
|
||||
appendCounters(metric, sb);
|
||||
if (dumpHash) {
|
||||
sb.append("\n sqlHash:").append(metric.sqlHash());
|
||||
sb.append("\n hash:").append(metric.hash());
|
||||
}
|
||||
appendProfileAndSql(metric, sb);
|
||||
out(sb.toString());
|
||||
@@ -134,7 +134,6 @@ class DumpMetrics {
|
||||
String location = metric.location();
|
||||
if (dumpLoc && location != null) {
|
||||
sb.append("\n loc:").append(location);
|
||||
sb.append("\n locHash:").append(metric.locationHash());
|
||||
}
|
||||
if (dumpSql) {
|
||||
sb.append(" \n\n sql:").append(metric.sql()).append("\n\n");
|
||||
|
||||
@@ -56,7 +56,6 @@ class DumpMetricsData {
|
||||
final MetricData data = create(metric);
|
||||
appendCounters(data, metric);
|
||||
data.setLoc(metric.location());
|
||||
data.setLocHash(metric.locationHash());
|
||||
}
|
||||
|
||||
private void addCount(MetaCountMetric metric) {
|
||||
@@ -68,11 +67,10 @@ class DumpMetricsData {
|
||||
final MetricData data = create(metric);
|
||||
appendCounters(data, metric);
|
||||
appendLocationAndSql(data, metric);
|
||||
data.setSqlHash(metric.sqlHash());
|
||||
data.setHash(metric.hash());
|
||||
}
|
||||
|
||||
private void appendLocationAndSql(MetricData data, MetaQueryMetric metric) {
|
||||
data.setLocHash(metric.locationHash());
|
||||
data.setLoc(metric.location());
|
||||
data.setSql(metric.sql());
|
||||
}
|
||||
|
||||
@@ -188,8 +188,7 @@ class DumpMetricsJson implements ServerMetricsAsJson {
|
||||
metricStart(metric);
|
||||
appendTiming(metric);
|
||||
if (isIncludeDetail(metric)) {
|
||||
keyVal("locHash", metric.locationHash());
|
||||
appendExtra("loc", metric.location());
|
||||
append("loc", metric.location());
|
||||
}
|
||||
metricEnd();
|
||||
}
|
||||
@@ -198,12 +197,11 @@ class DumpMetricsJson implements ServerMetricsAsJson {
|
||||
metricStart(metric);
|
||||
appendTiming(metric);
|
||||
if (withHash) {
|
||||
keyVal("sqlHash", metric.sqlHash());
|
||||
keyVal("locHash", metric.locationHash());
|
||||
append("hash", metric.hash());
|
||||
}
|
||||
if (isIncludeDetail(metric)) {
|
||||
appendExtra("loc", metric.location());
|
||||
appendExtra("sql", metric.sql());
|
||||
append("loc", metric.location());
|
||||
append("sql", metric.sql());
|
||||
}
|
||||
metricEnd();
|
||||
}
|
||||
@@ -212,7 +210,7 @@ class DumpMetricsJson implements ServerMetricsAsJson {
|
||||
return includeExtraAttributes == 2 || includeExtraAttributes == 1 && metric.initialCollection();
|
||||
}
|
||||
|
||||
private void appendExtra(String key, String val) throws IOException {
|
||||
private void append(String key, String val) throws IOException {
|
||||
if (val != null) {
|
||||
key(key);
|
||||
val(val);
|
||||
@@ -220,13 +218,13 @@ class DumpMetricsJson implements ServerMetricsAsJson {
|
||||
}
|
||||
|
||||
private void appendTiming(MetaTimedMetric timedMetric) throws IOException {
|
||||
keyVal("count", timedMetric.count());
|
||||
keyVal("total", timedMetric.total());
|
||||
keyVal("mean", timedMetric.mean());
|
||||
keyVal("max", timedMetric.max());
|
||||
append("count", timedMetric.count());
|
||||
append("total", timedMetric.total());
|
||||
append("mean", timedMetric.mean());
|
||||
append("max", timedMetric.max());
|
||||
}
|
||||
|
||||
private void keyVal(String key, long value) throws IOException {
|
||||
private void append(String key, long value) throws IOException {
|
||||
key(key);
|
||||
val(value);
|
||||
}
|
||||
|
||||
@@ -1558,7 +1558,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
|
||||
void queryPlanInit(QueryPlanInit request, List<MetaQueryPlan> list) {
|
||||
for (CQueryPlan queryPlan : queryPlanCache.values()) {
|
||||
if (request.includeHash(queryPlan.getSqlHash())) {
|
||||
if (request.includeHash(queryPlan.getHash())) {
|
||||
queryPlan.queryPlanInit(request.thresholdMicros());
|
||||
list.add(queryPlan.createMeta(null, null));
|
||||
}
|
||||
|
||||
@@ -10,12 +10,10 @@ final class BasicProfileLocation implements ProfileLocation {
|
||||
private final String fullLocation;
|
||||
private final String location;
|
||||
private final String label;
|
||||
private final long hash;
|
||||
|
||||
BasicProfileLocation(String fullLocation) {
|
||||
this.fullLocation = fullLocation;
|
||||
this.hash = UtilLocation.hash(fullLocation);
|
||||
this.location = shortDesc(fullLocation);
|
||||
this.location = UtilLocation.loc(fullLocation);
|
||||
this.label = UtilLocation.label(location);
|
||||
}
|
||||
|
||||
@@ -44,11 +42,6 @@ final class BasicProfileLocation implements ProfileLocation {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long hash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fullLocation() {
|
||||
return fullLocation;
|
||||
@@ -64,15 +57,4 @@ final class BasicProfileLocation implements ProfileLocation {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
private String shortDesc(String location) {
|
||||
int lastPer = location.lastIndexOf('.');
|
||||
if (lastPer > -1) {
|
||||
lastPer = location.lastIndexOf('.', lastPer - 1);
|
||||
if (lastPer > -1) {
|
||||
return location.substring(lastPer + 1);
|
||||
}
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ class DProfileLocation implements ProfileLocation {
|
||||
private String fullLocation;
|
||||
private String location;
|
||||
private String label;
|
||||
private long hash;
|
||||
|
||||
private final int lineNumber;
|
||||
private int traceCount;
|
||||
@@ -46,11 +45,10 @@ class DProfileLocation implements ProfileLocation {
|
||||
return false;
|
||||
}
|
||||
final String loc = create();
|
||||
final String shortDesc = shortDesc(loc);
|
||||
label = UtilLocation.label(shortDesc);
|
||||
location = shortDesc;
|
||||
fullLocation = loc;
|
||||
hash = UtilLocation.hash(loc);
|
||||
final String location = UtilLocation.loc(loc);
|
||||
this.label = UtilLocation.label(location);
|
||||
this.location = location;
|
||||
this.fullLocation = loc;
|
||||
initWith(label);
|
||||
return true;
|
||||
}
|
||||
@@ -69,11 +67,6 @@ class DProfileLocation implements ProfileLocation {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long hash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fullLocation() {
|
||||
return fullLocation;
|
||||
@@ -116,20 +109,4 @@ class DProfileLocation implements ProfileLocation {
|
||||
return traceLine.substring(0, traceLine.length() - 1) + ":" + lineNumber + ")";
|
||||
}
|
||||
}
|
||||
|
||||
private String shortDesc(String location) {
|
||||
int pos = location.lastIndexOf('(');
|
||||
if (pos == -1) {
|
||||
pos = location.length();
|
||||
}
|
||||
|
||||
pos = location.lastIndexOf('.', pos);
|
||||
if (pos > -1) {
|
||||
pos = location.lastIndexOf('.', pos - 1);
|
||||
if (pos > -1) {
|
||||
return location.substring(pos + 1);
|
||||
}
|
||||
}
|
||||
return location;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebeaninternal.server.profile;
|
||||
|
||||
import io.ebean.ProfileLocation;
|
||||
import io.ebeaninternal.server.util.Checksum;
|
||||
import io.ebeaninternal.server.util.Md5;
|
||||
|
||||
class DQueryPlanMeta {
|
||||
|
||||
@@ -10,7 +10,7 @@ class DQueryPlanMeta {
|
||||
private final ProfileLocation profileLocation;
|
||||
private final String name;
|
||||
private final String sql;
|
||||
private final long sqlHash;
|
||||
private final String hash;
|
||||
|
||||
DQueryPlanMeta(Class<?> type, String label, ProfileLocation profileLocation, String sql) {
|
||||
this.type = type;
|
||||
@@ -22,15 +22,16 @@ class DQueryPlanMeta {
|
||||
name += "_" + label;
|
||||
}
|
||||
this.name = name;
|
||||
this.sqlHash = Checksum.checksum(sql);
|
||||
String loc = profileLocation == null ? null : profileLocation.location();
|
||||
this.hash = Md5.hash(sql, name, loc);
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public long getSqlHash() {
|
||||
return sqlHash;
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -49,10 +50,6 @@ class DQueryPlanMeta {
|
||||
return (profileLocation == null) ? null : profileLocation.location();
|
||||
}
|
||||
|
||||
public long getLocationHash() {
|
||||
return (profileLocation == null) ? 0 : profileLocation.hash();
|
||||
}
|
||||
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ class DQueryPlanMetric implements QueryPlanMetric {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sqlHash() {
|
||||
return meta.getSqlHash();
|
||||
public String hash() {
|
||||
return meta.getHash();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,11 +83,6 @@ class DQueryPlanMetric implements QueryPlanMetric {
|
||||
return meta.getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long locationHash() {
|
||||
return meta.getLocationHash();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
return stats.count();
|
||||
|
||||
@@ -14,7 +14,6 @@ class DTimeMetricStats implements TimedMetricStats {
|
||||
|
||||
private String name;
|
||||
private String location;
|
||||
private long locationHash;
|
||||
|
||||
DTimeMetricStats(String name, boolean collected, long count, long total, long max) {
|
||||
this.name = name;
|
||||
@@ -37,7 +36,6 @@ class DTimeMetricStats implements TimedMetricStats {
|
||||
.append(" max:").append(max);
|
||||
if (location != null) {
|
||||
sb.append(" loc:").append(location);
|
||||
sb.append(" locHash:").append(locationHash);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
@@ -47,11 +45,6 @@ class DTimeMetricStats implements TimedMetricStats {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocationHash(long locationHash) {
|
||||
this.locationHash = locationHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initialCollection() {
|
||||
return !collected;
|
||||
@@ -72,11 +65,6 @@ class DTimeMetricStats implements TimedMetricStats {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long locationHash() {
|
||||
return locationHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the count of values collected.
|
||||
*/
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
package io.ebeaninternal.server.profile;
|
||||
|
||||
import io.ebeaninternal.server.util.Checksum;
|
||||
|
||||
final class UtilLocation {
|
||||
|
||||
/**
|
||||
* Return a hash of the full description excluding the source line number.
|
||||
*/
|
||||
static long hash(String full) {
|
||||
static String loc(String full) {
|
||||
final int pos = full.lastIndexOf('(');
|
||||
if (pos > -1) {
|
||||
return Checksum.checksum(full.substring(0, pos));
|
||||
return full.substring(0, pos);
|
||||
} else {
|
||||
return Checksum.checksum(full);
|
||||
return full;
|
||||
}
|
||||
}
|
||||
|
||||
static String label(String shortDescription) {
|
||||
int pos = shortDescription.indexOf("(");
|
||||
if (pos == -1) {
|
||||
return shortDescription;
|
||||
} else {
|
||||
return trimInit(shortDescription.substring(0, pos));
|
||||
static String label(String location) {
|
||||
return trimInit(shortDesc(location));
|
||||
}
|
||||
|
||||
private static String shortDesc(String location) {
|
||||
int pos = location.lastIndexOf('.');
|
||||
if (pos > -1) {
|
||||
pos = location.lastIndexOf('.', pos - 1);
|
||||
if (pos > -1) {
|
||||
return location.substring(pos + 1);
|
||||
}
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,7 +13,7 @@ import io.ebeaninternal.api.SpiQueryBindCapture;
|
||||
import io.ebeaninternal.api.SpiQueryPlan;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
import io.ebeaninternal.server.core.timezone.DataTimeZone;
|
||||
import io.ebeaninternal.server.util.Checksum;
|
||||
import io.ebeaninternal.server.util.Md5;
|
||||
import io.ebeaninternal.server.util.Str;
|
||||
import io.ebeaninternal.server.query.CQueryPlanStats.Snapshot;
|
||||
import io.ebeaninternal.server.type.DataBind;
|
||||
@@ -56,13 +56,12 @@ public class CQueryPlan implements SpiQueryPlan {
|
||||
private final SpiEbeanServer server;
|
||||
private final ProfileLocation profileLocation;
|
||||
private final String location;
|
||||
private final long locationHash;
|
||||
private final String label;
|
||||
private final String name;
|
||||
private final CQueryPlanKey planKey;
|
||||
private final boolean rawSql;
|
||||
private final String sql;
|
||||
private final long sqlHash;
|
||||
private final String hash;
|
||||
private final String logWhereSql;
|
||||
private final SqlTree sqlTree;
|
||||
|
||||
@@ -93,7 +92,6 @@ public class CQueryPlan implements SpiQueryPlan {
|
||||
SpiQuery<?> query = request.getQuery();
|
||||
this.profileLocation = query.getProfileLocation();
|
||||
this.location = (profileLocation == null) ? null : profileLocation.location();
|
||||
this.locationHash = (profileLocation == null) ? 0 : profileLocation.hash();
|
||||
this.label = query.getPlanLabel();
|
||||
this.name = deriveName(label, query.getType(), request.getBeanDescriptor().getSimpleName());
|
||||
this.asOfTableCount = query.getAsOfTableCount();
|
||||
@@ -105,7 +103,7 @@ public class CQueryPlan implements SpiQueryPlan {
|
||||
this.stats = new CQueryPlanStats(this);
|
||||
this.dependentTables = sqlTree.dependentTables();
|
||||
this.bindCapture = initBindCapture(query);
|
||||
this.sqlHash = Checksum.checksum(sql);
|
||||
this.hash = Md5.hash(sql, name, location);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,7 +116,6 @@ public class CQueryPlan implements SpiQueryPlan {
|
||||
SpiQuery<?> query = request.getQuery();
|
||||
this.profileLocation = query.getProfileLocation();
|
||||
this.location = (profileLocation == null) ? null : profileLocation.location();
|
||||
this.locationHash = (profileLocation == null) ? 0 : profileLocation.hash();
|
||||
this.label = query.getPlanLabel();
|
||||
this.name = deriveName(label, query.getType(), request.getBeanDescriptor().getSimpleName());
|
||||
this.planKey = buildPlanKey(sql, logWhereSql);
|
||||
@@ -131,7 +128,7 @@ public class CQueryPlan implements SpiQueryPlan {
|
||||
this.stats = new CQueryPlanStats(this);
|
||||
this.dependentTables = sqlTree.dependentTables();
|
||||
this.bindCapture = initBindCaptureRaw(sql, query);
|
||||
this.sqlHash = Checksum.checksum(sql);
|
||||
this.hash = Md5.hash(sql, name, location);
|
||||
}
|
||||
|
||||
private String deriveName(String label, SpiQuery.Type type, String simpleName) {
|
||||
@@ -177,8 +174,8 @@ public class CQueryPlan implements SpiQueryPlan {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSqlHash() {
|
||||
return sqlHash;
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -203,10 +200,6 @@ public class CQueryPlan implements SpiQueryPlan {
|
||||
return location;
|
||||
}
|
||||
|
||||
public long getLocationHash() {
|
||||
return locationHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanInit(long thresholdMicros) {
|
||||
bindCapture.queryPlanInit(thresholdMicros);
|
||||
@@ -214,7 +207,7 @@ public class CQueryPlan implements SpiQueryPlan {
|
||||
|
||||
@Override
|
||||
public DQueryPlanOutput createMeta(String bind, String planString) {
|
||||
return new DQueryPlanOutput(getBeanType(), name, sqlHash, sql, profileLocation, bind, planString);
|
||||
return new DQueryPlanOutput(getBeanType(), name, hash, sql, profileLocation, bind, planString);
|
||||
}
|
||||
|
||||
public DataReader createDataReader(ResultSet rset) {
|
||||
@@ -261,7 +254,7 @@ public class CQueryPlan implements SpiQueryPlan {
|
||||
|
||||
private String calcAuditQueryKey() {
|
||||
// rawSql needs to include the MD5 hash of the sql
|
||||
return rawSql ? planKey.getPartialKey() + "_" + sqlHash : planKey.getPartialKey();
|
||||
return rawSql ? planKey.getPartialKey() + "_" + hash : planKey.getPartialKey();
|
||||
}
|
||||
|
||||
SqlTree getSqlTree() {
|
||||
|
||||
@@ -106,11 +106,6 @@ public final class CQueryPlanStats {
|
||||
return queryPlan.getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long locationHash() {
|
||||
return queryPlan.getLocationHash();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
return metrics.count();
|
||||
@@ -132,8 +127,8 @@ public final class CQueryPlanStats {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sqlHash() {
|
||||
return queryPlan.getSqlHash();
|
||||
public String hash() {
|
||||
return queryPlan.getHash();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,14 +16,14 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan {
|
||||
private final String sql;
|
||||
private final String bind;
|
||||
private final String plan;
|
||||
private final long sqlHash;
|
||||
private final String hash;
|
||||
private long queryTimeMicros;
|
||||
private long captureCount;
|
||||
|
||||
DQueryPlanOutput(Class<?> beanType, String label, long sqlHash, String sql, ProfileLocation profileLocation, String bind, String plan) {
|
||||
DQueryPlanOutput(Class<?> beanType, String label, String hash, String sql, ProfileLocation profileLocation, String bind, String plan) {
|
||||
this.beanType = beanType;
|
||||
this.label = label;
|
||||
this.sqlHash = sqlHash;
|
||||
this.hash = hash;
|
||||
this.sql = sql;
|
||||
this.profileLocation = profileLocation;
|
||||
this.bind = bind;
|
||||
@@ -31,8 +31,8 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sqlHash() {
|
||||
return sqlHash;
|
||||
public String hash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +99,7 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return " BeanType:" + ((beanType == null) ? "" : beanType.getSimpleName()) + " planHash:" + sqlHash + " label:" + label + " queryTimeMicros:" + queryTimeMicros + " captureCount:" + captureCount + "\n SQL:" + sql + "\nBIND:" + bind + "\nPLAN:" + plan;
|
||||
return " BeanType:" + ((beanType == null) ? "" : beanType.getSimpleName()) + " planHash:" + hash + " label:" + label + " queryTimeMicros:" + queryTimeMicros + " captureCount:" + captureCount + "\n SQL:" + sql + "\nBIND:" + bind + "\nPLAN:" + plan;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package io.ebeaninternal.server.util;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public final class Md5 {
|
||||
|
||||
/**
|
||||
* Return the MD5 hash of the underlying sql.
|
||||
*/
|
||||
public static String hash(String... values) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
for (String val : values) {
|
||||
if (val != null) {
|
||||
md.update(val.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
return digestToHex(md.digest());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("MD5 hashing failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the digest into a hex value.
|
||||
*/
|
||||
private static String digestToHex(byte[] digest) {
|
||||
StringBuilder sb = new StringBuilder(32);
|
||||
for (byte aDigest : digest) {
|
||||
sb.append(Integer.toString((aDigest & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -14,7 +14,7 @@ public class BasicProfileLocationTest {
|
||||
|
||||
assertThat(loc.obtain()).isTrue();
|
||||
assertThat(loc.fullLocation()).endsWith(":12)");
|
||||
assertThat(loc.location()).isEqualTo("NativeMethodAccessorImpl.invoke0(Native Method:12)");
|
||||
assertThat(loc.location()).isEqualTo("java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0");
|
||||
assertThat(loc.label()).isEqualTo("NativeMethodAccessorImpl.invoke0");
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class BasicProfileLocationTest {
|
||||
BasicProfileLocation loc = new BasicProfileLocation("com.foo.Bar.all");
|
||||
assertThat(loc.obtain()).isFalse();
|
||||
assertThat(loc.fullLocation()).isEqualTo("com.foo.Bar.all");
|
||||
assertThat(loc.location()).isEqualTo("Bar.all");
|
||||
assertThat(loc.location()).isEqualTo("com.foo.Bar.all");
|
||||
assertThat(loc.label()).isEqualTo("Bar.all");
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class BasicProfileLocationTest {
|
||||
BasicProfileLocation loc = new BasicProfileLocation("foo.Bar.all");
|
||||
assertThat(loc.obtain()).isFalse();
|
||||
assertThat(loc.fullLocation()).isEqualTo("foo.Bar.all");
|
||||
assertThat(loc.location()).isEqualTo("Bar.all");
|
||||
assertThat(loc.location()).isEqualTo("foo.Bar.all");
|
||||
assertThat(loc.label()).isEqualTo("Bar.all");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,12 @@ public class UtilLocationTest {
|
||||
@Test
|
||||
public void label() {
|
||||
assertThat(UtilLocation.label("foo")).isEqualTo("foo");
|
||||
assertThat(UtilLocation.label("ProfileLocationTest$Other.<init>(ProfileLocationTest.java:47)")).isEqualTo("ProfileLocationTest$Other.init");
|
||||
assertThat(UtilLocation.label("ProfileLocationTest$Other.<init>")).isEqualTo("ProfileLocationTest$Other.init");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hash() {
|
||||
assertThat(UtilLocation.hash("org.foo.MyFoo.doIt(MyFoo.java:12)")).isEqualTo(396279222L);
|
||||
assertThat(UtilLocation.hash("org.foo.MyFoo.doIt(MyFoo.java:13)")).isEqualTo(396279222L);
|
||||
assertThat(UtilLocation.hash("org.foo.MyFoo.doIt(MyFoo.java:945)")).isEqualTo(396279222L);
|
||||
public void loc() {
|
||||
assertThat(UtilLocation.loc("org.foo.MyFoo.doIt(MyFoo.java:12)")).isEqualTo("org.foo.MyFoo.doIt");
|
||||
assertThat(UtilLocation.label("org.foo.MyFoo.doIt")).isEqualTo("MyFoo.doIt");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package io.ebeaninternal.server.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
public class Md5Test {
|
||||
|
||||
@Test
|
||||
public void hash() throws Exception {
|
||||
String content = "some random content we wish to hash";
|
||||
String hash1 = Md5.hash(content);
|
||||
String hash2 = Md5.hash(content);
|
||||
assertEquals(hash1, hash2);
|
||||
assertEquals(hash1, "62c20bf679ff56cb746452ab5c88e3ed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashDifferent() throws Exception {
|
||||
String hash1 = Md5.hash("one");
|
||||
String hash2 = Md5.hash("two");
|
||||
String hash3 = Md5.hash("onetwo");
|
||||
|
||||
assertNotEquals(hash1, hash2);
|
||||
assertNotEquals(hash2, hash3);
|
||||
assertEquals(hash1, "f97c5d29941bfb1b2fdab0874906ab82");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashMulti() {
|
||||
String hash1 = Md5.hash("one", "two");
|
||||
String hash2 = Md5.hash("onetwo");
|
||||
|
||||
assertEquals(hash1, hash2);
|
||||
assertEquals(hash1, "5b9164ad6f496d9dee12ec7634ce253f");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashMulti_when_null() {
|
||||
String hash1 = Md5.hash("one", null);
|
||||
String hash2 = Md5.hash("one");
|
||||
|
||||
assertEquals(hash1, hash2);
|
||||
assertEquals(hash1, "f97c5d29941bfb1b2fdab0874906ab82");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void when_null() {
|
||||
String hash1 = Md5.hash(null, null);
|
||||
assertEquals(hash1, "d41d8cd98f00b204e9800998ecf8427e");
|
||||
}
|
||||
}
|
||||
@@ -20,15 +20,13 @@ public class ProfileLocationTest {
|
||||
public void test_obtain() {
|
||||
assertThat(doIt()).isTrue();
|
||||
assertThat(loc.fullLocation()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt(ProfileLocationTest.java:16)");
|
||||
assertThat(loc.location()).isEqualTo("ProfileLocationTest.doIt(ProfileLocationTest.java:16)");
|
||||
assertThat(loc.location()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt");
|
||||
assertThat(loc.label()).isEqualTo("ProfileLocationTest.doIt");
|
||||
assertThat(loc.hash()).isEqualTo(1867926812L);
|
||||
|
||||
// same hash even when the line number has changed
|
||||
assertThat(locB.fullLocation()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt(ProfileLocationTest.java:15)");
|
||||
assertThat(locB.location()).isEqualTo("ProfileLocationTest.doIt(ProfileLocationTest.java:15)");
|
||||
assertThat(locB.location()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt");
|
||||
assertThat(locB.label()).isEqualTo("ProfileLocationTest.doIt");
|
||||
assertThat(locB.hash()).isEqualTo(1867926812L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -43,7 +41,7 @@ public class ProfileLocationTest {
|
||||
other.hashCode();
|
||||
|
||||
assertThat(loc2.label()).isEqualTo("ProfileLocationTest$Other.init");
|
||||
assertThat(loc2.location()).isEqualTo("ProfileLocationTest$Other.<init>(ProfileLocationTest.java:52)");
|
||||
assertThat(loc2.location()).isEqualTo("org.tests.profile.ProfileLocationTest$Other.<init>");
|
||||
}
|
||||
|
||||
static class Other {
|
||||
|
||||
@@ -242,10 +242,9 @@ public class TestCustomerFinder extends BaseTestCase {
|
||||
|
||||
assertThat(metricsJson).contains("\"name\":\"txn.main\"");
|
||||
assertThat(metricsJson).contains("\"name\":\"orm.Customer.findList\"");
|
||||
assertThat(metricsJson).contains("\"locHash\":3254522637");
|
||||
assertThat(metricsJson).contains("\"loc\":\"CustomerFinder.byNameStatus(CustomerFinder.java:43)\"");
|
||||
assertThat(metricsJson).contains("\"loc\":\"org.tests.model.basic.finder.CustomerFinder.byNameStatus\"");
|
||||
if (isH2() || isPostgres()) {
|
||||
assertThat(metricsJson).contains("\"sqlHash\":3634991469");
|
||||
assertThat(metricsJson).contains("\"hash\":\"de3affa5b4bff07e19c1c012590dcde6\"");
|
||||
assertThat(metricsJson).contains("\"sql\":\"select t0.id, t0.status,");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user