-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
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:
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:
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.

