Skip to content

Commit 6bd3222

Browse files
committed
last used before load histogram should display differently
1 parent 5bde430 commit 6bd3222

File tree

2 files changed

+119
-6
lines changed

2 files changed

+119
-6
lines changed

solr/core/src/java/org/apache/solr/core/UnloadHelper.java

Lines changed: 104 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,26 @@
22

33
import com.codahale.metrics.Histogram;
44
import com.codahale.metrics.Meter;
5+
import com.codahale.metrics.Snapshot;
56
import java.io.IOException;
67
import java.lang.invoke.MethodHandles;
78
import java.util.concurrent.ScheduledExecutorService;
89
import java.util.concurrent.TimeUnit;
910
import java.util.concurrent.atomic.AtomicBoolean;
11+
import java.util.function.BiConsumer;
1012
import java.util.function.LongSupplier;
13+
import java.util.function.Predicate;
1114
import java.util.function.Supplier;
1215
import org.apache.lucene.index.Unloader;
1316
import org.apache.lucene.util.InfoStream;
17+
import org.apache.solr.common.MapWriter;
1418
import org.apache.solr.handler.admin.MetricsHandler;
1519
import org.apache.solr.metrics.MetricSuppliers;
1620
import org.apache.solr.metrics.MetricsMap;
21+
import org.apache.solr.metrics.SolrMetricManager;
1722
import org.apache.solr.metrics.SolrMetricProducer;
1823
import org.apache.solr.metrics.SolrMetricsContext;
24+
import org.apache.solr.util.stats.MetricUtils;
1925
import org.slf4j.Logger;
2026
import org.slf4j.LoggerFactory;
2127

@@ -50,14 +56,108 @@ final class UnloadHelper<T extends Unloader.UnloadHelper>
5056
String[] metricPath = new String[] {SolrInfoBean.Category.OTHER.toString(), "unloadable"};
5157
created = solrMetricsContext.meter("created", metricPath);
5258
loaded = solrMetricsContext.meter("loaded", metricPath);
53-
loadTimeMillis = solrMetricsContext.histogram("loadTimeMillis", metricPath);
59+
loadTimeMillis =
60+
invertedHistogram(
61+
solrMetricsContext, "loadTimeMillis", metricPath, DEFAULT_WRITE_HISTOGRAM);
5462
lastAccessToReloadMillis =
55-
solrMetricsContext.histogram("lastAccessToReloadMillis", metricPath);
63+
invertedHistogram(
64+
solrMetricsContext,
65+
"lastAccessToReloadMillis",
66+
metricPath,
67+
(snapshot, filter) -> {
68+
filter.accept("min_ms", TimeUnit.NANOSECONDS.toMillis(snapshot.getMin()));
69+
filter.accept("max_ms", TimeUnit.NANOSECONDS.toMillis(snapshot.getMax()));
70+
filter.accept("mean_ms", nsToMs(snapshot.getMean()));
71+
filter.accept("median_ms", nsToMs(snapshot.getMedian()));
72+
filter.accept("stddev_ms", nsToMs(snapshot.getStdDev()));
73+
filter.accept("p25_ms", nsToMs(snapshot.getValue(0.25)));
74+
filter.accept("p05_ms", nsToMs(snapshot.getValue(0.05)));
75+
filter.accept("p01_ms", nsToMs(snapshot.getValue(0.01)));
76+
filter.accept("p001_ms", nsToMs(snapshot.getValue(0.001)));
77+
});
5678
unloaded = solrMetricsContext.meter("unloaded", metricPath);
5779
closed = solrMetricsContext.meter("closed", metricPath);
5880
}
5981
}
6082

83+
private static final long NANOS_PER_MILLI = TimeUnit.MILLISECONDS.toNanos(1);
84+
85+
private static double nsToMs(double nanos) {
86+
return nanos / NANOS_PER_MILLI;
87+
}
88+
89+
private static Histogram invertedHistogram(
90+
SolrMetricsContext ctx,
91+
String metricName,
92+
String[] metricPath,
93+
BiConsumer<Snapshot, BiConsumer<String, Object>> writeHistogram) {
94+
SolrMetricManager mgr = ctx.getMetricManager();
95+
final String name = SolrMetricManager.mkName(metricName, metricPath);
96+
ctx.registerMetricName(name);
97+
return mgr.registry(ctx.getRegistryName())
98+
.histogram(
99+
name, () -> new TimeHistogram(mgr.getHistogramSupplier().newMetric(), writeHistogram));
100+
}
101+
102+
@SuppressWarnings("UnnecessaryLambda")
103+
private static final BiConsumer<Snapshot, BiConsumer<String, Object>> DEFAULT_WRITE_HISTOGRAM =
104+
(snapshot, filter) -> {
105+
filter.accept("min_ms", TimeUnit.NANOSECONDS.toMillis(snapshot.getMin()));
106+
filter.accept("max_ms", TimeUnit.NANOSECONDS.toMillis(snapshot.getMax()));
107+
filter.accept("mean_ms", nsToMs(snapshot.getMean()));
108+
filter.accept("median_ms", nsToMs(snapshot.getMedian()));
109+
filter.accept("stddev_ms", nsToMs(snapshot.getStdDev()));
110+
filter.accept("p75_ms", nsToMs(snapshot.get75thPercentile()));
111+
filter.accept("p95_ms", nsToMs(snapshot.get95thPercentile()));
112+
filter.accept("p99_ms", nsToMs(snapshot.get99thPercentile()));
113+
filter.accept("p999_ms", nsToMs(snapshot.get999thPercentile()));
114+
};
115+
116+
private static final class TimeHistogram extends Histogram implements MetricUtils.SnapshotWriter {
117+
118+
private final Histogram delegate;
119+
private final BiConsumer<Snapshot, BiConsumer<String, Object>> writeHistogram;
120+
121+
private TimeHistogram(
122+
Histogram delegate, BiConsumer<Snapshot, BiConsumer<String, Object>> writeHistogram) {
123+
super(null);
124+
this.delegate = delegate;
125+
this.writeHistogram = writeHistogram;
126+
}
127+
128+
@Override
129+
public void addSnapshot(
130+
MapWriter.EntryWriter ew, Snapshot snapshot, Predicate<CharSequence> propertyFilter) {
131+
BiConsumer<String, Object> filter =
132+
(k, v) -> {
133+
if (propertyFilter.test(k)) {
134+
ew.putNoEx(k, v);
135+
}
136+
};
137+
writeHistogram.accept(snapshot, filter);
138+
}
139+
140+
@Override
141+
public void update(int value) {
142+
delegate.update(value);
143+
}
144+
145+
@Override
146+
public void update(long value) {
147+
delegate.update(value);
148+
}
149+
150+
@Override
151+
public long getCount() {
152+
return delegate.getCount();
153+
}
154+
155+
@Override
156+
public Snapshot getSnapshot() {
157+
return delegate.getSnapshot();
158+
}
159+
}
160+
61161
private volatile boolean closing = false;
62162

63163
private void handleRefQueues(LongSupplier indirectTrackedCount, LongSupplier refsCollected) {
@@ -106,8 +206,8 @@ public ScheduledExecutorService onCreation(Unloader<?> u) {
106206
@Override
107207
public void onLoad(long nanosSincePriorAccess, long loadTime) {
108208
loaded.mark();
109-
loadTimeMillis.update(TimeUnit.NANOSECONDS.toMillis(loadTime));
110-
lastAccessToReloadMillis.update(TimeUnit.NANOSECONDS.toMillis(nanosSincePriorAccess));
209+
loadTimeMillis.update(loadTime);
210+
lastAccessToReloadMillis.update(nanosSincePriorAccess);
111211
super.onLoad(nanosSincePriorAccess, loadTime);
112212
}
113213

solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,12 +489,21 @@ static void convertHistogram(
489489
ew.putNoEx(prop, histogram.getCount());
490490
}
491491
// non-time based values
492-
addSnapshot(ew, snapshot, propertyFilter, false);
492+
if (histogram instanceof SnapshotWriter) {
493+
((SnapshotWriter) histogram).addSnapshot(ew, snapshot, propertyFilter);
494+
} else {
495+
addSnapshot(ew, snapshot, propertyFilter, false);
496+
}
493497
};
494498
consumer.accept(name, writer);
495499
}
496500
}
497501

502+
public interface SnapshotWriter {
503+
void addSnapshot(
504+
MapWriter.EntryWriter ew, Snapshot snapshot, Predicate<CharSequence> propertyFilter);
505+
}
506+
498507
// optionally convert ns to ms
499508
static double nsToMs(boolean convert, double value) {
500509
if (convert) {
@@ -567,7 +576,11 @@ public static void convertTimer(
567576
filter.accept("15minRate", timer.getFifteenMinuteRate());
568577
if (!skipHistograms) {
569578
// time-based values in nanoseconds
570-
addSnapshot(ew, timer.getSnapshot(), propertyFilter, true);
579+
if (timer instanceof SnapshotWriter) {
580+
((SnapshotWriter) timer).addSnapshot(ew, timer.getSnapshot(), propertyFilter);
581+
} else {
582+
addSnapshot(ew, timer.getSnapshot(), propertyFilter, true);
583+
}
571584
}
572585
};
573586
if (writer._size() > 0) {

0 commit comments

Comments
 (0)