private static void WriteStatToConsole(StatHatStatistic stat) { var type = stat.Value != null ? "V" : "C"; object value = stat.Count ?? stat.Value; Console.WriteLine($"[STATHAT] [{EpochUtility.ToDateTimeOffset(stat.UnixTimestamp):o}] [{stat.Name} ({type})]: {value}"); }
/* Add a single line to _buffer. Callable from any thread */ public void Record(StatHatStatistic stat) { lock (_lock) { if (_count >= MaxBufferCount) { return; } var update = _buffer.Valn(stat.UnixTimestamp).Vald(stat.Name, () => stat); if (ReferenceEquals(update, stat) == false) { if (stat.Value.HasValue) { update.Count += stat.Count; } else { // Replace (old) value update.Value = stat.Value; } } else { // we added a new stat ++_count; } if (_count >= FlushCount) { if (_timerScheduled) { _timerScheduled = false; _timer.Change(Timeout.Infinite, Timeout.Infinite); // cancel the timer } Monitor.Pulse(_lock); } else if (!_timerScheduled) { _timerScheduled = true; _timer.Change(HysteresisMillis, Timeout.Infinite); } // else timer will get it later } }
// ///////////////////////////////////////////////////////////// // Accounting // ///////////////////////////////////////////////////////////// private static void Record(string statName, long?count, double?value, DateTimeOffset timestamp) { if (!StatHatPrefix.IsNullOrWhiteSpace()) { statName = StatHatPrefix + statName; } #if DEBUG Debug.Assert(!statName.IsNullOrWhiteSpace(), $"Invalid StatHat name: '{statName}'"); Debug.Assert(statName.Length <= 255, $"Invalid StatHat name (too long): '{statName}'"); Debug.Assert(count.HasValue != value.HasValue, $"Statistics must have a count or a value but not both. ({statName})"); #endif if (StatHatApiKey.IsNullOrWhiteSpace()) { return; } if (statName.IsNullOrWhiteSpace()) { return; } var stat = new StatHatStatistic() { Name = statName, Count = count, Value = value, UnixTimestamp = (int)EpochUtility.ToEpoch(timestamp) }; Sink.Record(stat); #if DEBUG WriteStatToConsole(stat); #endif }