Im using messageInspectors in my WCF service to measure elapsed time on each service method like this :
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
{
if (_activated)
{
_startTime.Stop();
PerformanceCounterHandler.Instance.SetAveragePerformanceCounter(operationName, _startTime.ElapsedTicks);
}
}
public object BeforeCall(string operationName, object[] inputs)
{
Guid correlationState;
if (_activated)
{
correlationState = Guid.NewGuid();
_startTime = new Stopwatch();
_startTime.Start();
return correlationState;
}
return null;
}
This is how the counters is registred
foreach (string methodName in ServiceMethodNames)
{
counter = new CounterCreationData(methodName, methodName + " > Genomsnittlig tid(ms)", PerformanceCounterType.AverageTimer32);
col.Add(counter);
counter = new CounterCreationData(methodName + "_base", methodName + " > Genomsnittlig tid(ms)", PerformanceCounterType.AverageBase);
col.Add(counter);
}
The method for setting the performance counter looks like this :
public Boolean SetAveragePerformanceCounter(string performanceCounterName, long value)
{
PerformanceCounter performCounter;
if (_useOrbitPerformanceCounters && (performCounter = _performanceCounters.Values.Where(c=> c.CounterName == performanceCounterName).FirstOrDefault()) != null)
{
performCounter.IncrementBy(value);
performanceCounterName = performanceCounterName + "_base";
performCounter = _performanceCounters[performanceCounterName];
performCounter.Increment();
return true;
}
return false;
}
The performance counter does however show spikes instead of average? If I change the view to report everything is 0 as long as I do nothing? I need to be able to see how the calltime average looks like right now even if there is no calls for the moment. What am I doing wrong?
The problem is, that the
AverageTimer32
doesn't show some alltime average value. From the documentation:The interesting part is the formula. The performance counter just shows the average between two performance counter readings. So if no requests where made, the resulting value is 0 because the numerator is 0.
Maybe it's somehow possible to calculate the value on your own and expose it through some other type of performance counter.
EDIT: I wrote a demo application to demonstrate a workaround, but it feels quite messy. I created an
NumberOfItems32
performance counter.And set the value like so:
The disadvantage of this solution is obvious. Since the performance counter can only store
long
you lose the decimal places of your average value. Another workaround for this problem would be to scale your values, for example multiplying them with 10 and then choose an lower scaling in performance monitor.