Example #1
0
 public void Write(MetricValue metric)
 {
     if (metric == null)
     {
         Logger.Debug("write() - Invalid null metric");
         return;
     }
     if (!_connected)
         StartConnection();
     if (_connected && _channel != null)
     {
         string routingKey = GetAmqpRoutingKey(metric);
         string message = metric.GetMetricJsonStr();
         try
         {
             _channel.BasicPublish(_exchange, routingKey, null, Encoding.UTF8.GetBytes(message));
         }
         catch
         {
             CloseConnection();
         }
     }
 }
        public IList<MetricValue> Read()
        {
            if (DateTime.Now > _configurationReloadTime.AddSeconds(_reloadConfigurationInterval))
            {
                Logger.Info("WindowsPerformanceCounter reloading configuration");
                Configure();
            }
            var metricValueList = new List<MetricValue>();
            foreach (Metric metric in _metrics)
            {
                var vals = new List<double>();
                var missingInstances = new List<PerformanceCounter>();
                foreach (PerformanceCounter ctr in metric.Counters)
                {
                    double val;
                    try
                    {
                         val = ctr.NextValue();
                    }
                    catch (InvalidOperationException)
                    {
                        // The instance is gone
                        missingInstances.Add(ctr);
                        continue;
                    }
                    if (metric.ScaleUpFactor > 0)
                    {
                        val = val*metric.ScaleUpFactor;
                    }
                    else
                    {
                        if (metric.ScaleDownFactor > 0)
                        {
                            val = val/metric.ScaleDownFactor;
                        }
                    }
                    vals.Add(val);
                }

                foreach (PerformanceCounter missingInstance in missingInstances)
                {
                    string logstr =
                        string.Format(
                            "Category:{0} - Instance:{1} - counter:{2} - ScaleUpFactor:{3} - ScaleDownFactor:{4} -  CollectdPlugin:{5} - CollectdPluginInstance:{6} - CollectdType:{7} - CollectdTypeInstance:{8}",
                            metric.Category, metric.Instance, metric.CounterName, metric.ScaleUpFactor, metric.ScaleDownFactor, metric.CollectdPlugin, metric.CollectdPluginInstance,
                            metric.CollectdType, metric.CollectdTypeInstance);
                    Logger.Info("Removed Performance COUNTER : {0}", logstr);
                    metric.Counters.Remove(missingInstance);
                }

                var metricValue = new MetricValue
                {
                    HostName = _hostName,
                    PluginName = metric.CollectdPlugin,
                    PluginInstanceName = metric.CollectdPluginInstance,
                    TypeName = metric.CollectdType,
                    TypeInstanceName = metric.CollectdTypeInstance,
                    Values = vals.ToArray()
                };

                TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
                double epoch = t.TotalMilliseconds/1000;
                metricValue.Epoch = Math.Round(epoch, 3);

                metricValueList.Add(metricValue);
            }
            return (metricValueList);
        }
Example #3
0
        public void Write(MetricValue metric)
        {
            // Optoinal Regex replace of unsafe chars
            if (SafeCharsRegex != null)
            {
                metric.PluginInstanceName = SafeCharsRegex.Replace(metric.PluginInstanceName, ReplaceWith);
            }

            string message = metric.GetMetricJsonStr();

            if (_batchedMetricStr == null)
            {
                _batchedMetricStr = new StringBuilder("[").Append(message);
            }
            else
            {
                _batchedMetricStr.Append(",").Append(message);
            }
            _numMetrics++;

            if (_numMetrics < BatchSize) return;

            publish();
        }
Example #4
0
 public void Write(MetricValue metric)
 {
     if (metric == null)
     {
         Logger.Debug("write() - Invalid null metric");
         return;
     }
     foreach (HttpWriter writer in _httpWriters)
     {
         writer.Write(metric);
     }
 }
Example #5
0
        public void Aggregate(ref MetricValue metricValue)
        {
            // If rates are not stored then there is nothing to aggregate
            if (!_storeRates)
            {
                return;
            }
            IList<DataSource> dsl = DataSetCollection.Instance.GetDataSource(metricValue.TypeName);
            if (dsl == null || metricValue.Values.Length != dsl.Count)
            {
                return;
            }

            double now = Util.GetNow();

            lock (_cacheLock)
            {
                CacheEntry cEntry;
                string key = metricValue.Key();

                if (!(_cache.TryGetValue(key, out cEntry)))
                {
                    cEntry = new CacheEntry(metricValue.DeepCopy());
                    for (int i = 0; i < metricValue.Values.Length; i++)
                    {
                        if (dsl[i].Type == DsType.Derive ||
                            dsl[i].Type == DsType.Absolute ||
                            dsl[i].Type == DsType.Counter)
                        {
                            metricValue.Values[i] = double.NaN;
                            cEntry.MetricRate.Values[i] = double.NaN;
                        }
                    }
                    cEntry.MetricRate.Epoch = now;
                    _cache[key] = cEntry;
                    return;
                }
                for (int i = 0; i < metricValue.Values.Length; i++)
                {
                    double rawValNew = metricValue.Values[i];
                    double rawValOld = cEntry.RawValues[i];
                    double rawValDiff = rawValNew - rawValOld;
                    double timeDiff = cEntry.MetricRate.Epoch - now;

                    double rateNew = rawValDiff/timeDiff;

                    switch (dsl[i].Type)
                    {
                        case DsType.Gauge:
                            // no rates calculations are done, values are stored as-is for gauge
                            cEntry.RawValues[i] = rawValNew;
                            cEntry.MetricRate.Values[i] = rawValNew;
                            break;

                        case DsType.Absolute:
                            // similar to gauge, except value will be divided by time diff
                            cEntry.MetricRate.Values[i] = metricValue.Values[i]/timeDiff;
                            cEntry.RawValues[i] = rawValNew;
                            metricValue.Values[i] = cEntry.MetricRate.Values[i];
                            break;

                        case DsType.Derive:
                            cEntry.RawValues[i] = rawValNew;
                            cEntry.MetricRate.Values[i] = rateNew;
                            metricValue.Values[i] = rateNew;

                            break;

                        case DsType.Counter:
                            // Counters are very simlar to derive except when counter wraps around                                
                            if (rawValNew < rawValOld)
                            {
                                // counter has wrapped around
                                cEntry.MetricRate.Values[i] = metricValue.Values[i]/timeDiff;
                                cEntry.RawValues[i] = rawValNew;
                                metricValue.Values[i] = cEntry.MetricRate.Values[i];
                            }
                            else
                            {
                                cEntry.MetricRate.Values[i] = rateNew;
                                cEntry.RawValues[i] = rawValNew;
                                metricValue.Values[i] = rateNew;
                            }
                            break;
                    }

                    // range checks
                    if (metricValue.Values[i] < dsl[i].Min)
                    {
                        metricValue.Values[i] = dsl[i].Min;
                        cEntry.RawValues[i] = metricValue.Values[i];
                    }
                    if (metricValue.Values[i] > dsl[i].Max)
                    {
                        metricValue.Values[i] = dsl[i].Max;
                        cEntry.RawValues[i] = metricValue.Values[i];
                    }

                    cEntry.MetricRate.Epoch = now;
                    _cache[key] = cEntry;
                }
            }
        }
        public void Write(MetricValue metric)
        {
            string message = metric.GetMetricJsonStr();
            if (_batchedMetricStr == null)
            {
                _batchedMetricStr = new StringBuilder("[").Append(message);
            }
            else
            {
                _batchedMetricStr.Append(",").Append(message);
            }
            _numMetrics++;

            if (_numMetrics < BatchSize) return;

            _batchedMetricStr.Append("]");
            HttpPost(_batchedMetricStr.ToString());
            _batchedMetricStr = null;
            _numMetrics = 0;
        }
        public IList<CollectableValue> Read()
        {
            // Only collect events and event metric every nth interval
            if (_intervalCounter++ % _intervalMultiplier != 0)
                return new List<CollectableValue>();

            IList<CollectableValue> collectableValues = new List<CollectableValue>();
            long totalEvents = 0;
            long collectionTime = (long)(Util.toEpoch(DateTime.UtcNow));

            List<long> recordIds = new List<long>();
            foreach (EventQuery eventQuery in _events)
            {
                List<EventRecord> records = GetEventRecords(eventQuery.minLevel, eventQuery.maxLevel, eventQuery.log, eventQuery.source);

                // Filter the events - event ID must be in target range, description must match regex and we mustn't have already read this event record ID in another query
                Regex filterExp = new Regex(eventQuery.filterExp, RegexOptions.None);
                List<EventRecord> filteredRecords = records.FindAll(delegate(EventRecord record)
                {
                    return !recordIds.Contains((long)record.RecordId) && record.Id >= eventQuery.minEventId && record.Id <= eventQuery.maxEventId && filterExp.IsMatch(record.FormatDescription());
                });

                // Add these record IDs to dedupe list so we don't capture them again in a later query
                filteredRecords.ForEach(delegate(EventRecord record) { recordIds.Add((long)record.RecordId); });

                if (filteredRecords.Count <= eventQuery.maxPerCycle)
                {
                    foreach (EventRecord record in filteredRecords)
                    {
                        // Timestamp from record is machine time, not GMT
                        long timestamp = (long)(Util.toEpoch(record.TimeCreated.Value.ToUniversalTime()));
                        long id = (long)record.RecordId;
                        string message = record.FormatDescription();
                        EventValue newevent = new EventValue(_hostName, timestamp, record.Level.Value, eventQuery.title, message, id);
                        collectableValues.Add(newevent);
                        totalEvents++;
                    }
                }
                else
                {
                    // Too many events - summarise by counting events by application,level and code
                    Dictionary<string, int> detailMap = new Dictionary<string, int>();
                    int minLevel = 999; // used to get the most severe event in the period for the summary level
                    filteredRecords.ForEach(delegate(EventRecord record)
                    {
                        string key = string.Format("{0} in {1} ({2})", record.LevelDisplayName, record.ProviderName, record.Id);

                        if (record.Level.Value < minLevel)
                            minLevel = record.Level.Value;

                        if (detailMap.ContainsKey(key))
                        {
                            detailMap[key] = detailMap[key] + 1;
                        }
                        else
                        {
                            detailMap.Add(key, 1);
                        }
                    });

                    List<KeyValuePair<string, int>> detailList = new List<KeyValuePair<string, int>>();
                    foreach (string key in detailMap.Keys)
                    {
                        detailList.Add(new KeyValuePair<string, int>(key, detailMap[key]));
                    }
                    detailList.Sort(delegate(KeyValuePair<string, int> pair1, KeyValuePair<string, int> pair2) { return -pair1.Value.CompareTo(pair2.Value); });

                    string[] messageLines = new string[detailList.Count];

                    int ix = 0;
                    foreach (KeyValuePair<string, int> pair in detailList)
                    {
                        messageLines[ix++] = pair.Value + " x " + pair.Key;
                    }
                    string title = string.Format("{0} ({1} events)", eventQuery.title, filteredRecords.Count);
                    EventValue newevent = new EventValue(_hostName, collectionTime, minLevel, title, String.Join(", ", messageLines), 0);
                    collectableValues.Add(newevent);
                    totalEvents += filteredRecords.Count;
                }
            }

            // Add event count metric
            MetricValue eventCountMetric = new MetricValue
            {
                HostName = _hostName,
                PluginName = "windows_events",
                PluginInstanceName = "",
                TypeName = "count",
                TypeInstanceName = "event_count",
                Values = new double[] { totalEvents },
                FriendlyNames = new string[] { "Windows Event Count" },
                Epoch = collectionTime
            };
            collectableValues.Add(eventCountMetric);

            return collectableValues;
        }
Example #8
0
        public IList<MetricValue> Read()
        {
            lock (_lock)
            {
                var res = new List<MetricValue>();
                var removeList = new List<string>();
                foreach (var pair in _metrics)
                {
                    StatsdMetric metric = pair.Value;
                    if (metric.NumUpdates <= 0 &&
                        ((_delCounter && metric.Type == StatsdMetric.StatsdType.StatsdCounter) ||
                         (_delTimer && metric.Type == StatsdMetric.StatsdType.StatsdTimer) ||
                         (_delGauge && metric.Type == StatsdMetric.StatsdType.StatsdGauge) ||
                         (_delSet && metric.Type == StatsdMetric.StatsdType.StatsdSet)))
                    {
                        removeList.Add(pair.Key);
                        continue;
                    }
                    var metricVal = new MetricValue
                    {
                        HostName = _hostName,
                        PluginName = "statsd",
                        PluginInstanceName = "",
                        TypeInstanceName = metric.Name,
                        Values = new[] {metric.GetMetric()}
                    };
                    switch (metric.Type)
                    {
                        case StatsdMetric.StatsdType.StatsdGauge:
                            metricVal.TypeName = "gauge";
                            break;
                        case StatsdMetric.StatsdType.StatsdTimer:
                            metricVal.TypeName = "latency";
                            metricVal.TypeInstanceName += "-average";
                            break;
                        case StatsdMetric.StatsdType.StatsdSet:
                            metricVal.TypeName = "objects";
                            break;
                        default:
                            metricVal.TypeName = "derive";
                            break;
                    }
                    TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
                    double epoch = t.TotalMilliseconds/1000;
                    metricVal.Epoch = Math.Round(epoch, 3);

                    res.Add(metricVal);

                    if (metric.Type == StatsdMetric.StatsdType.StatsdTimer)
                    {
                        if (_timerLower)
                        {
                            MetricValue lowerValue = metricVal.DeepCopy();
                            lowerValue.TypeInstanceName = metric.Name + "-lower";
                            lowerValue.Values[0] = metric.Lat.Min;
                            res.Add(lowerValue);
                        }
                        if (_timerUpper)
                        {
                            MetricValue upperValue = metricVal.DeepCopy();
                            upperValue.TypeInstanceName = metric.Name + "-upper";
                            upperValue.Values[0] = metric.Lat.Max;
                            res.Add(upperValue);
                        }

                        if (_timerSum)
                        {
                            MetricValue upperSum = metricVal.DeepCopy();
                            upperSum.TypeInstanceName = metric.Name + "-Sum";
                            upperSum.Values[0] = metric.Lat.Sum;
                            res.Add(upperSum);
                        }
                        if (_timerCount)
                        {
                            MetricValue upperCount = metricVal.DeepCopy();
                            upperCount.TypeInstanceName = metric.Name + "-count";
                            upperCount.Values[0] = metric.Lat.Num;
                            res.Add(upperCount);
                        }
                        Histogram histogram = metric.Lat.Histogram;
                        if (_percentiles != null && _percentiles.Length > 0 && histogram != null)
                        {
                            foreach (float percentile in _percentiles)
                            {
                                double val = histogram.GetPercentile(percentile);

                                MetricValue mv = metricVal.DeepCopy();
                                mv.TypeInstanceName = metric.Name + "-percentile-" + percentile;
                                mv.Values[0] = val;
                                res.Add(mv);
                            }
                        }
                    }
                    metric.Reset();
                }
                Logger.Debug("Removing entries that were not updated:{0}", removeList.Count);
                foreach (string key in removeList)
                {
                    _metrics.Remove(key);
                }
                return (res);
            }
        }
        public IList<CollectableValue> Read()
        {
            // Check if it is time to reload the metric config
            // We need to periodially reload the config in case new instances or new categories are available (e.g. due to cluster move)
            if (Util.GetNow() - _lastUpdated >= _reloadInterval)
            {
                Configure();
            }

            var metricValueList = new List<CollectableValue>();
            foreach (Metric metric in _metrics)
            {
                try
                {
                    var vals = new List<double>();
                    foreach (PerformanceCounter ctr in metric.Counters)
                    {
                        double val = ctr.NextValue();
                        val = val * metric.Multiplier;

                        if (metric.DecimalPlaces >= 0)
                            val = Math.Round(val, metric.DecimalPlaces);
                        vals.Add(val);
                    }

                    var metricValue = new MetricValue
                    {
                        HostName = _hostName,
                        PluginName = metric.CollectdPlugin,
                        PluginInstanceName = metric.CollectdPluginInstance,
                        TypeName = metric.CollectdType,
                        TypeInstanceName = metric.CollectdTypeInstance,
                        Values = vals.ToArray(),
                        FriendlyNames = metric.FriendlyNames

                    };

                    metricValue.Epoch = Util.toEpoch(DateTime.UtcNow);

                    metricValueList.Add(metricValue);
                }
                catch (Exception ex)
                {
                    Logger.Warn(string.Format("Failed to collect metric: {0}, {1}, {2}", metric.Category, metric.Instance, metric.CounterName), ex);
                }
            }
            return (metricValueList);
        }
Example #10
0
 public void Write(MetricValue metric)
 {
     Console.WriteLine("ConsolePlugin: {0}", metric.GetMetricJsonStr());
 }
Example #11
0
        public IList <MetricValue> Read()
        {
            if (DateTime.Now > _configurationReloadTime.AddSeconds(_reloadConfigurationInterval))
            {
                Logger.Info("WindowsPerformanceCounter reloading configuration");
                Configure();
            }
            var metricValueList = new List <MetricValue>();

            foreach (Metric metric in _metrics)
            {
                var vals             = new List <double>();
                var missingInstances = new List <PerformanceCounter>();
                foreach (PerformanceCounter ctr in metric.Counters)
                {
                    double val;
                    try
                    {
                        val = ctr.NextValue();
                    }
                    catch (InvalidOperationException)
                    {
                        // The instance is gone
                        missingInstances.Add(ctr);
                        continue;
                    }
                    if (metric.ScaleUpFactor > 0)
                    {
                        val = val * metric.ScaleUpFactor;
                    }
                    else
                    {
                        if (metric.ScaleDownFactor > 0)
                        {
                            val = val / metric.ScaleDownFactor;
                        }
                    }
                    vals.Add(val);
                }

                foreach (PerformanceCounter missingInstance in missingInstances)
                {
                    string logstr =
                        string.Format(
                            "Category:{0} - Instance:{1} - counter:{2} - ScaleUpFactor:{3} - ScaleDownFactor:{4} -  CollectdPlugin:{5} - CollectdPluginInstance:{6} - CollectdType:{7} - CollectdTypeInstance:{8}",
                            metric.Category, metric.Instance, metric.CounterName, metric.ScaleUpFactor, metric.ScaleDownFactor, metric.CollectdPlugin, metric.CollectdPluginInstance,
                            metric.CollectdType, metric.CollectdTypeInstance);
                    Logger.Info("Removed Performance COUNTER : {0}", logstr);
                    metric.Counters.Remove(missingInstance);
                }

                var metricValue = new MetricValue
                {
                    HostName           = _hostName,
                    PluginName         = metric.CollectdPlugin,
                    PluginInstanceName = metric.CollectdPluginInstance,
                    TypeName           = metric.CollectdType,
                    TypeInstanceName   = metric.CollectdTypeInstance,
                    Values             = vals.ToArray()
                };

                TimeSpan t     = DateTime.UtcNow - new DateTime(1970, 1, 1);
                double   epoch = t.TotalMilliseconds / 1000;
                metricValue.Epoch = Math.Round(epoch, 3);

                metricValueList.Add(metricValue);
            }
            return(metricValueList);
        }
Example #12
0
        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");
        }
        private void WriteThreadProc()
        {
            Logger.Trace("WriteThreadProc() begin");
            bool needToFlush = false;

            while (_runWriteThread)
            {
                try
                {
                    while (_metricValueQueue.Count > 0)
                    {
                        MetricValue metricValue = null;
                        lock (_queueLock)
                        {
                            if (_metricValueQueue.Count > 0)
                            {
                                metricValue = _metricValueQueue.Dequeue();
                            }
                        }
                        if (metricValue != null)
                        {
                            needToFlush          = true;
                            metricValue.Interval = _interval;

                            _aggregator.Aggregate(ref metricValue);
                            metricValue.AddMetaData(_metaData);

                            foreach (IMetricsPlugin plugin in _plugins)
                            {
                                var writePlugin = plugin as IMetricsWritePlugin;
                                if (writePlugin == null)
                                {
                                    // skip if plugin is not a writeplugin, it might be a readplugin
                                    continue;
                                }
                                writePlugin.Write(metricValue);
                            }
                        }
                    }
                    if (needToFlush)
                    {
                        needToFlush = false;
                        foreach (IMetricsPlugin plugin in _plugins)
                        {
                            var writePlugin = plugin as IMetricsWritePlugin;
                            if (writePlugin != null)
                            {
                                // flush only if it is a Write plugin
                                writePlugin.Flush();
                            }
                        }
                    }
                    if (_metricValueQueue.Count <= 0)
                    {
                        Thread.Sleep(1000);
                    }
                }
                catch (Exception exp)
                {
                    Logger.Error("WriteThreadProc() got exception : ", exp);
                }
            }
            Logger.Trace("WriteThreadProc() return");
        }
Example #14
0
 public void Write(MetricValue metric)
 {
     Console.WriteLine("ConsolePlugin: {0}", metric.GetMetricJsonStr());
 }
 public CacheEntry(MetricValue metricValue)
 {
     MetricRate = metricValue;
     RawValues  = (double[])metricValue.Values.Clone();
 }
Example #16
0
        private string GetAmqpRoutingKey(MetricValue metric)
        {
            string routingKey = _routingKeyPrefix + "." + metric.HostName + "." + metric.PluginName + "." +
                                metric.PluginInstanceName + "." + metric.TypeName + "." + metric.TypeInstanceName;

            return (routingKey);
        }
        public void Aggregate(ref MetricValue metricValue)
        {
            // If rates are not stored then there is nothing to aggregate
            if (!_storeRates)
            {
                return;
            }
            IList <DataSource> dsl = DataSetCollection.Instance.GetDataSource(metricValue.TypeName);

            if (dsl == null || metricValue.Values.Length != dsl.Count)
            {
                return;
            }

            double now = Util.GetNow();

            lock (_cacheLock)
            {
                CacheEntry cEntry;
                string     key = metricValue.Key();

                if (!(_cache.TryGetValue(key, out cEntry)))
                {
                    cEntry = new CacheEntry(metricValue.DeepCopy());
                    for (int i = 0; i < metricValue.Values.Length; i++)
                    {
                        if (dsl[i].Type == DsType.Derive ||
                            dsl[i].Type == DsType.Absolute ||
                            dsl[i].Type == DsType.Counter)
                        {
                            metricValue.Values[i]       = double.NaN;
                            cEntry.MetricRate.Values[i] = double.NaN;
                        }
                    }
                    cEntry.MetricRate.Timestamp = now;
                    _cache[key] = cEntry;
                    return;
                }
                for (int i = 0; i < metricValue.Values.Length; i++)
                {
                    double rawValNew  = metricValue.Values[i];
                    double rawValOld  = cEntry.RawValues[i];
                    double rawValDiff = rawValNew - rawValOld;
                    double timeDiff   = cEntry.MetricRate.Timestamp - now;

                    double rateNew = rawValDiff / timeDiff;

                    switch (dsl[i].Type)
                    {
                    case DsType.Gauge:
                        // no rates calculations are done, values are stored as-is for gauge
                        cEntry.RawValues[i]         = rawValNew;
                        cEntry.MetricRate.Values[i] = rawValNew;
                        break;

                    case DsType.Absolute:
                        // similar to gauge, except value will be divided by time diff
                        cEntry.MetricRate.Values[i] = metricValue.Values[i] / timeDiff;
                        cEntry.RawValues[i]         = rawValNew;
                        metricValue.Values[i]       = cEntry.MetricRate.Values[i];
                        break;

                    case DsType.Derive:
                        cEntry.RawValues[i]         = rawValNew;
                        cEntry.MetricRate.Values[i] = rateNew;
                        metricValue.Values[i]       = rateNew;

                        break;

                    case DsType.Counter:
                        // Counters are very simlar to derive except when counter wraps around
                        if (rawValNew < rawValOld)
                        {
                            // counter has wrapped around
                            cEntry.MetricRate.Values[i] = metricValue.Values[i] / timeDiff;
                            cEntry.RawValues[i]         = rawValNew;
                            metricValue.Values[i]       = cEntry.MetricRate.Values[i];
                        }
                        else
                        {
                            cEntry.MetricRate.Values[i] = rateNew;
                            cEntry.RawValues[i]         = rawValNew;
                            metricValue.Values[i]       = rateNew;
                        }
                        break;
                    }

                    // range checks
                    if (metricValue.Values[i] < dsl[i].Min)
                    {
                        metricValue.Values[i] = dsl[i].Min;
                        cEntry.RawValues[i]   = metricValue.Values[i];
                    }
                    if (metricValue.Values[i] > dsl[i].Max)
                    {
                        metricValue.Values[i] = dsl[i].Max;
                        cEntry.RawValues[i]   = metricValue.Values[i];
                    }

                    cEntry.MetricRate.Timestamp = now;
                    _cache[key] = cEntry;
                }
            }
        }
Example #18
0
 public CacheEntry(MetricValue metricValue)
 {
     MetricRate = metricValue;
     RawValues = (double[]) metricValue.Values.Clone();
 }
Example #19
0
        public IList <MetricValue> Read()
        {
            lock (_lock)
            {
                var res        = new List <MetricValue>();
                var removeList = new List <string>();
                foreach (var pair in _metrics)
                {
                    StatsdMetric metric = pair.Value;
                    if (metric.NumUpdates <= 0 &&
                        ((_delCounter && metric.Type == StatsdMetric.StatsdType.StatsdCounter) ||
                         (_delTimer && metric.Type == StatsdMetric.StatsdType.StatsdTimer) ||
                         (_delGauge && metric.Type == StatsdMetric.StatsdType.StatsdGauge) ||
                         (_delSet && metric.Type == StatsdMetric.StatsdType.StatsdSet)))
                    {
                        removeList.Add(pair.Key);
                        continue;
                    }
                    var metricVal = new MetricValue
                    {
                        HostName           = _hostName,
                        PluginName         = "statsd",
                        PluginInstanceName = "",
                        TypeInstanceName   = metric.Name,
                        Values             = new[] { metric.GetMetric() }
                    };
                    switch (metric.Type)
                    {
                    case StatsdMetric.StatsdType.StatsdGauge:
                        metricVal.TypeName = "gauge";
                        break;

                    case StatsdMetric.StatsdType.StatsdTimer:
                        metricVal.TypeName          = "latency";
                        metricVal.TypeInstanceName += "-average";
                        break;

                    case StatsdMetric.StatsdType.StatsdSet:
                        metricVal.TypeName = "objects";
                        break;

                    default:
                        metricVal.TypeName = "derive";
                        break;
                    }
                    TimeSpan t     = DateTime.UtcNow - new DateTime(1970, 1, 1);
                    double   epoch = t.TotalMilliseconds / 1000;
                    metricVal.Epoch = Math.Round(epoch, 3);

                    res.Add(metricVal);

                    if (metric.Type == StatsdMetric.StatsdType.StatsdTimer)
                    {
                        if (_timerLower)
                        {
                            MetricValue lowerValue = metricVal.DeepCopy();
                            lowerValue.TypeInstanceName = metric.Name + "-lower";
                            lowerValue.Values[0]        = metric.Lat.Min;
                            res.Add(lowerValue);
                        }
                        if (_timerUpper)
                        {
                            MetricValue upperValue = metricVal.DeepCopy();
                            upperValue.TypeInstanceName = metric.Name + "-upper";
                            upperValue.Values[0]        = metric.Lat.Max;
                            res.Add(upperValue);
                        }

                        if (_timerSum)
                        {
                            MetricValue upperSum = metricVal.DeepCopy();
                            upperSum.TypeInstanceName = metric.Name + "-Sum";
                            upperSum.Values[0]        = metric.Lat.Sum;
                            res.Add(upperSum);
                        }
                        if (_timerCount)
                        {
                            MetricValue upperCount = metricVal.DeepCopy();
                            upperCount.TypeInstanceName = metric.Name + "-count";
                            upperCount.Values[0]        = metric.Lat.Num;
                            res.Add(upperCount);
                        }
                        Histogram histogram = metric.Lat.Histogram;
                        if (_percentiles != null && _percentiles.Length > 0 && histogram != null)
                        {
                            foreach (float percentile in _percentiles)
                            {
                                double val = histogram.GetPercentile(percentile);

                                MetricValue mv = metricVal.DeepCopy();
                                mv.TypeInstanceName = metric.Name + "-percentile-" + percentile;
                                mv.Values[0]        = val;
                                res.Add(mv);
                            }
                        }
                    }
                    metric.Reset();
                }
                Logger.Debug("Removing entries that were not updated:{0}", removeList.Count);
                foreach (string key in removeList)
                {
                    _metrics.Remove(key);
                }
                return(res);
            }
        }
        public MetricValue GetMetricValue(List<double> vals)
        {
            var metricValue = new MetricValue
            {
                HostName = s_hostName,
                PluginName = CollectdPlugin,
                PluginInstanceName = CollectdPluginInstance,
                TypeName = CollectdType,
                TypeInstanceName = CollectdTypeInstance,
                Values = vals.ToArray()
            };

            TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
            double epoch = t.TotalMilliseconds / 1000;
            metricValue.Epoch = Math.Round(epoch, 3);
            return metricValue;
        }
        public void GetIngestMetrics(MetricValue metric, out List<IngestMetric> metrics, out List<IngestSample> samples)
        {
            metrics = new List<IngestMetric>();
            samples = new List<IngestSample>();

            string metricId = metric.PluginName;
            if (metric.PluginInstanceName.Length > 0)
                metricId += "." + metric.PluginInstanceName.Replace(".", "_");
            if (metric.TypeInstanceName.Length > 0)
                metricId += "." + metric.TypeInstanceName;

            metricId = Regex.Replace(metricId, "[ ]", "_"); // Keep spaces as underscores
            metricId = Regex.Replace(metricId, "[^a-zA-Z0-9\\._-]", ""); // Remove punctuation
            if (metric.Values.Length == 1)
            {
                // Simple case - just one metric in type
                metrics.Add(new IngestMetric(metricId, metric.FriendlyNames[0], metric.TypeName));
                samples.Add(new IngestSample(metricId, (long)metric.Epoch * 1000, metric.Values[0]));
            }
            else if (metric.Values.Length > 1)
            {
                // Compound type with multiple metrics
                IList<DataSource> dsList = DataSetCollection.Instance.GetDataSource(metric.TypeName);
                if (dsList == null)
                {
                    Logger.Debug("Invalid type : {0}, not found in types.db", metric.TypeName);
                }
                else
                {
                    int ix = 0;
                    foreach (DataSource ds in dsList)
                    {
                        // Include the Types.db suffix in the metric name
                        metrics.Add(new IngestMetric(metricId + "." + ds.Name, metric.FriendlyNames[ix], metric.TypeName));
                        samples.Add(new IngestSample(metricId + "." + ds.Name, (long)metric.Epoch * 1000, metric.Values[ix]));
                        ix++;
                    }
                }
            }
        }