content: /*
   * 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.bookkeeper.bookie.storage.ldb;
  
  import static org.apache.bookkeeper.bookie.BookKeeperServerStats.BOOKIE_ADD_ENTRY;
  import static org.apache.bookkeeper.bookie.BookKeeperServerStats.BOOKIE_READ_ENTRY;
  import static org.apache.bookkeeper.bookie.BookKeeperServerStats.BOOKIE_SCOPE;
  import static org.apache.bookkeeper.bookie.BookKeeperServerStats.CATEGORY_SERVER;
  
  import java.util.function.Supplier;
  import lombok.Getter;
  import org.apache.bookkeeper.stats.Counter;
  import org.apache.bookkeeper.stats.Gauge;
  import org.apache.bookkeeper.stats.OpStatsLogger;
  import org.apache.bookkeeper.stats.StatsLogger;
  import org.apache.bookkeeper.stats.annotations.StatsDoc;
  
  /**
   * A umbrella class for db ledger storage stats with one instance per
   * ledger directory.
   */
  @StatsDoc(
      name = BOOKIE_SCOPE,
      category = CATEGORY_SERVER,
      help = "DbLedgerStorage related stats"
  )
  @Getter
  class DbLedgerStorageStats {
  
      private static final String ADD_ENTRY = "add-entry";
      private static final String READ_ENTRY = "read-entry";
      private static final String READ_ENTRY_LOCATIONS_INDEX_TIME = "read-locations-index-time";
      private static final String READ_ENTRYLOG_TIME = "read-entrylog-time";
      private static final String WRITE_CACHE_HITS = "write-cache-hits";
      private static final String WRITE_CACHE_MISSES = "write-cache-misses";
      private static final String READ_CACHE_HITS = "read-cache-hits";
      private static final String READ_CACHE_MISSES = "read-cache-misses";
      private static final String READAHEAD_BATCH_COUNT = "readahead-batch-count";
      private static final String READAHEAD_BATCH_SIZE = "readahead-batch-size";
      private static final String READAHEAD_TIME = "readahead-time";
      private static final String FLUSH = "flush";
      private static final String FLUSH_ENTRYLOG = "flush-entrylog";
      private static final String FLUSH_LOCATIONS_INDEX = "flush-locations-index";
      private static final String FLUSH_LEDGER_INDEX = "flush-ledger-index";
      private static final String FLUSH_SIZE = "flush-size";
  
      @Deprecated
      private static final String THROTTLED_WRITE_REQUESTS = "throttled-write-requests";
      // throttled-write-requests is deprecated, use new metric: throttled-write
      private static final String THROTTLED_WRITE = "throttled-write";
      private static final String REJECTED_WRITE_REQUESTS = "rejected-write-requests";
      private static final String WRITE_CACHE_SIZE = "write-cache-size";
      private static final String WRITE_CACHE_COUNT = "write-cache-count";
      private static final String READ_CACHE_SIZE = "read-cache-size";
      private static final String READ_CACHE_COUNT = "read-cache-count";
  
      @StatsDoc(
          name = ADD_ENTRY,
          help = "operation stats of adding entries to db ledger storage",
          parent = BOOKIE_ADD_ENTRY
      )
      private final OpStatsLogger addEntryStats;
      @StatsDoc(
          name = READ_ENTRY,
          help = "operation stats of reading entries from db ledger storage",
          parent = BOOKIE_READ_ENTRY
      )
      private final OpStatsLogger readEntryStats;
      @StatsDoc(
              name = READ_ENTRY_LOCATIONS_INDEX_TIME,
              help = "time spent reading entries from the locations index of the db ledger storage engine",
              parent = READ_ENTRY
      )
      private final Counter readFromLocationIndexTime;
      @StatsDoc(
              name = READ_ENTRYLOG_TIME,
              help = "time spent reading entries from the entry log files of the db ledger storage engine",
              parent = READ_ENTRY
      )
      private final Counter readFromEntryLogTime;
      @StatsDoc(
              name = WRITE_CACHE_HITS,
              help = "number of write cache hits (on reads)",
              parent = READ_ENTRY
      )
      private final Counter writeCacheHitCounter;
      @StatsDoc(
              name = WRITE_CACHE_MISSES,
              help = "number of write cache misses (on reads)",
              parent = READ_ENTRY
      )
      private final Counter writeCacheMissCounter;
      @StatsDoc(
          name = READ_CACHE_HITS,
          help = "number of read cache hits",
          parent = READ_ENTRY
      )
      private final Counter readCacheHitCounter;
      @StatsDoc(
          name = READ_CACHE_MISSES,
          help = "number of read cache misses",
          parent = READ_ENTRY
      )
      private final Counter readCacheMissCounter;
      @StatsDoc(
          name = READAHEAD_BATCH_COUNT,
          help = "the distribution of num of entries to read in one readahead batch"
      )
      private final OpStatsLogger readAheadBatchCountStats;
      @StatsDoc(
          name = READAHEAD_BATCH_SIZE,
          help = "the distribution of num of bytes to read in one readahead batch"
      )
      private final OpStatsLogger readAheadBatchSizeStats;
      @StatsDoc(
              name = READAHEAD_TIME,
              help = "Time spent on readahead operations"
      )
      private final Counter readAheadTime;
      @StatsDoc(
          name = FLUSH,
          help = "operation stats of flushing write cache to entry log files"
      )
      private final OpStatsLogger flushStats;
      @StatsDoc(
              name = FLUSH_ENTRYLOG,
              help = "operation stats of flushing to the current entry log file"
      )
      private final OpStatsLogger flushEntryLogStats;
      @StatsDoc(
              name = FLUSH_LOCATIONS_INDEX,
              help = "operation stats of flushing to the locations index"
      )
      private final OpStatsLogger flushLocationIndexStats;
      @StatsDoc(
              name = FLUSH_LOCATIONS_INDEX,
              help = "operation stats of flushing to the ledger index"
      )
      private final OpStatsLogger flushLedgerIndexStats;
      @StatsDoc(
          name = FLUSH_SIZE,
          help = "the distribution of number of bytes flushed from write cache to entry log files"
      )
      private final OpStatsLogger flushSizeStats;
      @StatsDoc(
          name = THROTTLED_WRITE_REQUESTS,
          help = "The number of requests throttled due to write cache is full"
      )
      private final Counter throttledWriteRequests;
      @StatsDoc(
              name = THROTTLED_WRITE,
              help = "The stats of throttled write due to write cache is full"
      )
      private final OpStatsLogger throttledWriteStats;
      @StatsDoc(
          name = REJECTED_WRITE_REQUESTS,
          help = "The number of requests rejected due to write cache is full"
      )
      private final Counter rejectedWriteRequests;
  
      @StatsDoc(
          name = WRITE_CACHE_SIZE,
          help = "Current number of bytes in write cache"
      )
      private final Gauge<Long> writeCacheSizeGauge;
      @StatsDoc(
          name = WRITE_CACHE_COUNT,
          help = "Current number of entries in write cache"
      )
      private final Gauge<Long> writeCacheCountGauge;
      @StatsDoc(
          name = READ_CACHE_SIZE,
          help = "Current number of bytes in read cache"
      )
      private final Gauge<Long> readCacheSizeGauge;
      @StatsDoc(
          name = READ_CACHE_COUNT,
          help = "Current number of entries in read cache"
      )
      private final Gauge<Long> readCacheCountGauge;
  
      DbLedgerStorageStats(StatsLogger stats,
                           Supplier<Long> writeCacheSizeSupplier,
                           Supplier<Long> writeCacheCountSupplier,
                           Supplier<Long> readCacheSizeSupplier,
                           Supplier<Long> readCacheCountSupplier) {
          addEntryStats = stats.getThreadScopedOpStatsLogger(ADD_ENTRY);
          readEntryStats = stats.getThreadScopedOpStatsLogger(READ_ENTRY);
          readFromLocationIndexTime = stats.getThreadScopedCounter(READ_ENTRY_LOCATIONS_INDEX_TIME);
          readFromEntryLogTime = stats.getThreadScopedCounter(READ_ENTRYLOG_TIME);
          readCacheHitCounter = stats.getCounter(READ_CACHE_HITS);
          readCacheMissCounter = stats.getCounter(READ_CACHE_MISSES);
          writeCacheHitCounter = stats.getCounter(WRITE_CACHE_HITS);
          writeCacheMissCounter = stats.getCounter(WRITE_CACHE_MISSES);
          readAheadBatchCountStats = stats.getOpStatsLogger(READAHEAD_BATCH_COUNT);
          readAheadBatchSizeStats = stats.getOpStatsLogger(READAHEAD_BATCH_SIZE);
          readAheadTime = stats.getThreadScopedCounter(READAHEAD_TIME);
          flushStats = stats.getOpStatsLogger(FLUSH);
          flushEntryLogStats = stats.getOpStatsLogger(FLUSH_ENTRYLOG);
          flushLocationIndexStats = stats.getOpStatsLogger(FLUSH_LOCATIONS_INDEX);
          flushLedgerIndexStats = stats.getOpStatsLogger(FLUSH_LEDGER_INDEX);
          flushSizeStats = stats.getOpStatsLogger(FLUSH_SIZE);
  
          throttledWriteRequests = stats.getThreadScopedCounter(THROTTLED_WRITE_REQUESTS);
          throttledWriteStats = stats.getOpStatsLogger(THROTTLED_WRITE);
          rejectedWriteRequests = stats.getThreadScopedCounter(REJECTED_WRITE_REQUESTS);
  
          writeCacheSizeGauge = new Gauge<Long>() {
              @Override
              public Long getDefaultValue() {
                  return 0L;
              }
  
              @Override
              public Long getSample() {
                  return writeCacheSizeSupplier.get();
              }
          };
          stats.registerGauge(WRITE_CACHE_SIZE, writeCacheSizeGauge);
          writeCacheCountGauge = new Gauge<Long>() {
              @Override
              public Long getDefaultValue() {
                  return 0L;
              }
  
              @Override
              public Long getSample() {
                  return writeCacheCountSupplier.get();
              }
          };
          stats.registerGauge(WRITE_CACHE_COUNT, writeCacheCountGauge);
          readCacheSizeGauge = new Gauge<Long>() {
              @Override
              public Long getDefaultValue() {
                  return 0L;
              }
  
              @Override
              public Long getSample() {
                  return readCacheSizeSupplier.get();
              }
          };
          stats.registerGauge(READ_CACHE_SIZE, readCacheSizeGauge);
          readCacheCountGauge = new Gauge<Long>() {
  
              @Override
              public Long getDefaultValue() {
                  return 0L;
              }
  
              @Override
              public Long getSample() {
                  return readCacheCountSupplier.get();
              }
          };
          stats.registerGauge(READ_CACHE_COUNT, readCacheCountGauge);
      }
  
  }
  