private void WriteThreadProc()
{
Logger.Trace("WriteThreadProc() begin");
// Wait a few seconds to give read thread a chance to get metrics.
// Otherwise write thread is always pushing metrics _interval seconds after they were read
Thread.Sleep(15000);
while (_runWriteThread)
{
try
{
double writeStart = Util.GetNow();
int numValues = _collectedValueQueue.Count;
if (numValues > 0)
{
// Transfer current queue contents to working list
// Individual write plugins can choose how to handle the list of collectable values.
Queue<CollectableValue> collectedValues = new Queue<CollectableValue>();
lock (_queueLock)
{
while (_collectedValueQueue.Count > 0)
{
collectedValues.Enqueue(_collectedValueQueue.Dequeue());
}
}
if (collectedValues.Count > 0) {
foreach (CollectableValue collectedValue in collectedValues)
{
collectedValue.Interval = _interval;
if (collectedValue is MetricValue)
{
MetricValue metricValue = (MetricValue)collectedValue;
_aggregator.Aggregate(ref metricValue);
}
}
foreach (ICollectdPlugin plugin in _plugins)
{
var writePlugin = plugin as ICollectdWritePlugin;
if (writePlugin == null)
{
// skip if plugin is not a writeplugin
continue;
}
writePlugin.Write(collectedValues);
}
}
}
double writeEnd = Util.GetNow();
double elapsed = writeEnd - writeStart;
double revisedInterval = (_interval - elapsed) * 1000;
if (revisedInterval / _interval < 0.1)
{
Logger.Warn("Write thread took {0} seconds out of {1} second cycle", elapsed, _interval);
}
if (revisedInterval >= 0)
Thread.Sleep((int)revisedInterval);
else
{
LogEventInfo logEvent = new LogEventInfo(LogLevel.Error, Logger.Name, "Write thread exceeded cycle time");
logEvent.Properties.Add("EventID", ErrorCodes.ERROR_WRITE_EXCEEDED_CYCLE_TIME);
Logger.Log(logEvent);
}
}
catch (ThreadInterruptedException)
{
Logger.Info("Write thread interrupted");
}
catch (Exception exp)
{
LogEventInfo logEvent = new LogEventInfo(LogLevel.Error, Logger.Name, "Exception in WriteThreadProc()");
logEvent.Exception = exp;
logEvent.Properties.Add("EventID", ErrorCodes.ERROR_UNHANDLED_EXCEPTION);
Logger.Log(logEvent);
Thread.Sleep(_interval * 1000);
}
}
Logger.Trace("WriteThreadProc() return");
}