Closed
Description
Background and Motivation
In Bing, we want to track performance of dynamically loaded plugin code very closely so that we can figure out whether the code is staying within the bounds of good performance and behavior. A plugin that gets too far out of bounds can be disabled or run at a lower priority, for example.
Currently, we can track the following in real-time:
- Wall-time (
Stopwatch
) - CPU-time (Win32 API GetThreadTimes)
- Unhandled exceptions
In addition, we can track the following with ETW events, but only after the fact, or in limited-time profiles.
- Memory allocation (especially LOH allocations)
- First-chance exceptions
- JITted methods
We'd like to be able to get these stats via API, in order of importance:
- GC - Bytes Allocated (
GC.GetAllocatedBytesForCurrentThread
appears to satisfy this) - JIT stats - % time (CPU time? wall time?)
a. Jitted bytes would be nice to have here, but time is more important. - Locks taken, # of times thread was blocked
- Exceptions thrown - aware that we can listen to FirstChanceException handler, but this process-global, as far as I know, so messier to deal with.
Proposed API and Example
We could wrap the stats in a Stopwatch like class that gets a lot more than time:
var mon = new ThreadStatsMonitor();
mon.Start()
thirdPartyCode.Execute();
mon.Stop();
Logger.Log(
mon.BytesAllocated, // I'm aware of GC.GetAllocatedBytesForCurrentThread
mon.JITCPUTime,
mon.MethodsJitted,
mon.ILBytesJited,
mon.nativeBytesGenerated,
mon.ExceptionsThrown, //i.e., first-chance exceptions
mon.LockSynchronizations,
mon.CPUTime,
mon.WallTime,
);
// This is simplistic logic, but conveys the point
if (mon.BytesAllocated > MaxBytesPerPlugin)
{
thirdPartyCode.Disable();
}
Risks
Pay-for-play. Not everybody wants all the stats. Some of the stats could be expensive to generate.