In this lesson, you will learn how to build lightweight, real-time telemetry pipelines that expose your application’s managed memory behavior to external monitoring tools using EventCounters.
The Power of Lightweight Telemetry
While heavy profiling tools are excellent for local debugging, they often impose too much overhead for production environments. EventCounters provide a low-overhead, pull-based mechanism to stream live metrics—such as GC Heap Size or Gen 0/1/2 collection counts—to external monitoring systems like Prometheus, Azure Monitor, or even simple console listeners.
Unlike complex diagnostic traces, an EventCounter is a simple numerical gauge that updates periodically. The .NET runtime already exposes these memory statistics via the System.Runtime event source, but you can create your own custom counters to track specific domain-relevant memory growth.
Implementing a Memory Watcher
To expose memory metrics, you attach an EventListener that listens to the System.Runtime source. Below is a simplified snippet of how you might hook into these counters:
public class MemoryEventListener : EventListener
{
protected override void OnEventSourceCreated(EventSource eventSource)
{
if (eventSource.Name == "System.Runtime")
{
// Enable the source and request memory statistics
EnableEvents(eventSource, EventLevel.Informational, EventKeywords.None,
new Dictionary<string, string?> { { "EventCounterIntervalSec", "1" } });
}
}
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
if (eventData.Payload?.FirstOrDefault() is IDictionary<string, object> counterPayload)
{
// Extract the 'Mean' value from the 'GC Heap Size' counter
if (counterPayload["Name"].ToString() == "gc-heap-size")
{
Console.WriteLine($"Current Heap Size: {counterPayload["Mean"]} MB");
}
}
}
}
By setting the EventCounterIntervalSec, you control the sampling frequency, allowing you to observe memory pressure without significant impact on your application's throughput. This approach is vital for detecting memory leaks in long-running services where you need to correlate heap growth with specific request patterns or background tasks.
Key Takeaway: EventCounters provide a low-overhead, production-ready pipeline for surfacing internal managed memory metrics to your observability stack, enabling proactive detection of heap-related performance regressions.