KEMBAR78
Allow developers to use built-in meters for tracking stats on caches · Issue #67770 · dotnet/runtime · GitHub
Skip to content

Allow developers to use built-in meters for tracking stats on caches #67770

@maryamariyan

Description

@maryamariyan

Summary

Today, the user has to write their own metrics retrieval system. By adding built-in metrics, the library could hook into existing list of caches, and publish all stats so it could handle all that user would do otherwise in their code to support multiple caches. To help identify caches, MemoryCache would need a Name property to help support the meter scenario.

With the built-in metrics the name is shown per memory cache, and the onus is on user to provide a unique name otherwise the library could add a warning and either pick one or update the duplicated name with a warning.

To learn more check out this gist.

Goal

This issue helps focus on a good user experience for developers who wish to track statistics for multiple memory caches by having built-in meters added to the library. Today getting statistics for multiple caches is possible but requires developer to write their own meter.

Our focus here is to add support for cache names, a built-in Meter, and a default naming convention for the cache created by AddMemoryCache() in M.E.C (tracked in #67769).

NOTE:

This issue needs to also address #67769
For more information refer to #66479 (comment).

What is already available in Preview 4:

GetCurrentStatistics() API (based on #50406) allows app developers to use either event counters or metrics APIs to track statistics for one or more memory caches with code snippets.

With IMemoryCache.GetCurrentStatistics(), the user now has support for the following use cases:

  • One cache with either event counters or metrics APIs
  • Multiple caches with metrics API

Using IMemoryCache.GetCurrentStatistics() for one memory cache

Use AddMemoryCache API to instantiate a single memory cache and via DI get it injected to enable them calling GetCurrentStatistics.

Sample usage/screenshot for event counter:

// when using `services.AddMemoryCache(options => options.TrackStatistics = true);` to instantiate

    [EventSource(Name = "Microsoft-Extensions-Caching-Memory")]
    internal sealed class CachingEventSource : EventSource
    {
        public CachingEventSource(IMemoryCache memoryCache) { _memoryCache = memoryCache; }
        protected override void OnEventCommand(EventCommandEventArgs command)
        {
            if (command.Command == EventCommand.Enable)
            {
                if (_cacheHitsCounter == null)
                {
                    _cacheHitsCounter = new PollingCounter("cache-hits", this, () =>
                        _memoryCache.GetCurrentStatistics().CacheHits)
                    {
                        DisplayName = "Cache hits",
                    };
                }
            }
        }
    }

Helps them view stats below with dotnet-counters tool:

image

Using IMemoryCache.GetCurrentStatistics() for multiple memory caches

In order to get stats for more than one memory cache in the app, the user may use metrics APIs in their own code, so long as they have a way of distinguishing their caches by name or ID:

sample usage/screenshot for multiple caches using metrics APIs

 Meter s_meter = new Meter("Microsoft.Extensions.Caching.Memory.MemoryCache", "1.0.0");
 var cacheHitsMetrics = s_meter.CreateObservableGauge<int>("cache-hits", GetCacheHits);

// metrics callback for cache hits
static IEnumerable<Measurement<int>> GetCacheHits()
{
    return new Measurement<int>[]
    {
            // or measurements could be looped or read from a real queue somewhere:
            new Measurement<int>(mc1.GetCurrentStatistics().CacheHits, new KeyValuePair<string,object>("CacheName", "mc1")),
            new Measurement<int>(mc2.GetCurrentStatistics().CacheHits, new KeyValuePair<string,object>("CacheName", "mc2")),
            new Measurement<int>(mc3.GetCurrentStatistics().CacheHits, new KeyValuePair<string,object>("CacheName", "mc3")),
    };
}

Sample stats with dotnet-counters tool:

image

Each metrics would need to create its own observable gauge (one for hits, then misses, etc.) and each callback function for the gauge iterates through list of caches creating measurements.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions