@Override
    public CacheInfo getCacheInfo() {
        final PropertyPath basePropertyPath = getBasePropertyPath();

        final Map<String, String> map = new HashMap<>();
        // Local copy in case rebuild is called
        final CacheHolder<K, V> localCacheHolder = this.cacheHolder;
        final Cache<K, V> cache = localCacheHolder.getCache();
        map.put("Entries", String.valueOf(cache.estimatedSize()));
        // The lock covers cacheBuilder too
        addEntries(map, getCacheBuilder().toString());
        addEntries(map, cache.stats().toString());

        map.forEach((k, v) -> {
            if (k.startsWith("Expire") ||
                k.equals("TotalLoadTime") ||
                k.equals("RefreshAfterWrite")) {
                convertNanosToDuration(map, k, v);
            }
        });

        // We don't make use of Weighers in the cache so the weight stats are meaningless
        map.remove("EvictionWeight");

        // Let users know how many times we have evicted items for hitting the size limit.
        map.put("Reached Size Limit Count", Integer.toString(reachedSizeLimitCount.get()));

        return new CacheInfo(name, basePropertyPath, map);
    }
Subclasses should implement this method to add to the cacheBuilder as required
and return a cache built from cacheBuilder. The builder already has a
removalNotificationConsumer if applicable and recordStats has been set.
stroom-cache/stroom-cache-impl/src/main/java/stroom/cache/impl/AbstractStroomCache.java