blob: 5ad34f3c5aeca2149df22fdcedc974d35e2e8bc0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.store.blockcache;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.solr.core.SolrInfoBean;
import org.apache.solr.metrics.MetricsMap;
import org.apache.solr.metrics.SolrMetricProducer;
import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.search.SolrCacheBase;
/**
* A {@link SolrInfoBean} that provides metrics on block cache operations.
*
* @lucene.experimental
*/
public class Metrics extends SolrCacheBase implements SolrInfoBean, SolrMetricProducer {
public AtomicLong blockCacheSize = new AtomicLong(0);
public AtomicLong blockCacheHit = new AtomicLong(0);
public AtomicLong blockCacheMiss = new AtomicLong(0);
public AtomicLong blockCacheEviction = new AtomicLong(0);
public AtomicLong blockCacheStoreFail = new AtomicLong(0);
// since the last call
private AtomicLong blockCacheHit_last = new AtomicLong(0);
private AtomicLong blockCacheMiss_last = new AtomicLong(0);
private AtomicLong blockCacheEviction_last = new AtomicLong(0);
public AtomicLong blockCacheStoreFail_last = new AtomicLong(0);
// These are used by the BufferStore (just a generic cache of byte[]).
// TODO: If this (the Store) is a good idea, we should make it more general and use it across more places in Solr.
public AtomicLong shardBuffercacheAllocate = new AtomicLong(0);
public AtomicLong shardBuffercacheLost = new AtomicLong(0);
private MetricsMap metricsMap;
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
private SolrMetricsContext solrMetricsContext;
private long previous = System.nanoTime();
@Override
public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
solrMetricsContext = parentContext.getChildContext(this);
metricsMap = new MetricsMap(map -> {
long now = System.nanoTime();
long delta = Math.max(now - previous, 1);
double seconds = delta / 1000000000.0;
long hits_total = blockCacheHit.get();
long hits_delta = hits_total - blockCacheHit_last.get();
blockCacheHit_last.set(hits_total);
long miss_total = blockCacheMiss.get();
long miss_delta = miss_total - blockCacheMiss_last.get();
blockCacheMiss_last.set(miss_total);
long evict_total = blockCacheEviction.get();
long evict_delta = evict_total - blockCacheEviction_last.get();
blockCacheEviction_last.set(evict_total);
long storeFail_total = blockCacheStoreFail.get();
long storeFail_delta = storeFail_total - blockCacheStoreFail_last.get();
blockCacheStoreFail_last.set(storeFail_total);
long lookups_delta = hits_delta + miss_delta;
long lookups_total = hits_total + miss_total;
map.put("size", blockCacheSize.get());
map.put("lookups", lookups_total);
map.put("hits", hits_total);
map.put("evictions", evict_total);
map.put("storeFails", storeFail_total);
map.put("hitratio_current", calcHitRatio(lookups_delta, hits_delta)); // hit ratio since the last call
map.put("lookups_persec", getPerSecond(lookups_delta, seconds)); // lookups per second since the last call
map.put("hits_persec", getPerSecond(hits_delta, seconds)); // hits per second since the last call
map.put("evictions_persec", getPerSecond(evict_delta, seconds)); // evictions per second since the last call
map.put("storeFails_persec", getPerSecond(storeFail_delta, seconds)); // evictions per second since the last call
map.put("time_delta", seconds); // seconds since last call
// TODO: these aren't really related to the BlockCache
map.put("buffercache.allocations", getPerSecond(shardBuffercacheAllocate.getAndSet(0), seconds));
map.put("buffercache.lost", getPerSecond(shardBuffercacheLost.getAndSet(0), seconds));
previous = now;
});
solrMetricsContext.gauge(this, metricsMap, true, getName(), getCategory().toString(), scope);
}
private float getPerSecond(long value, double seconds) {
return (float) (value / seconds);
}
// SolrInfoBean methods
@Override
public String getName() {
return "hdfsBlockCache";
}
@Override
public String getDescription() {
return "Provides metrics for the HdfsDirectoryFactory BlockCache.";
}
@Override
public Set<String> getMetricNames() {
return metricNames;
}
@Override
public SolrMetricsContext getSolrMetricsContext() {
return solrMetricsContext;
}
}