All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.solr.store.blockcache.Metrics Maven / Gradle / Ivy

There is a newer version: 9.6.1
Show newest version
/*
 * 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 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((detailed, 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 getMetricNames() {
    return metricNames;
  }

  @Override
  public SolrMetricsContext getSolrMetricsContext() {
    return solrMetricsContext;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy