public MetricEvent Clone() { MetricEvent metricEvent = new MetricEvent() { TimeCreated = this.TimeCreated, EventSource = this.EventSource, TenantId = this.TenantId, InstanceId = this.InstanceId, AdditionalData = this.AdditionalData, Name = this.Name, TimeWindow = this.TimeWindow, Count = this.Count, Total = this.Total, Average = this.Average, Minimum = this.Minimum, Maximum = this.Maximum }; foreach (KeyValuePair <string, string> pair in this.Dimensions) { metricEvent.Dimensions.Add(pair.Key, pair.Value); } return(metricEvent); }
static void UpdateMultipleTimeWindows(MetricEvent metricEvent, RollupAggregateTimeWindow[] aggregateTimeWindows) { Fx.Assert(aggregateTimeWindows.Length > 1, "AggregateTimeWindows array length greater than 1"); int countIncrement = metricEvent.Count / aggregateTimeWindows.Length; int countRemainder = metricEvent.Count % aggregateTimeWindows.Length; double total = metricEvent.Average * metricEvent.Count; double totalIncrement = total / aggregateTimeWindows.Length; // Spread the contributions of metricEvent.Count and metricEvent.Value evenly across the different time windows. MetricEvent tempMetricEvent = metricEvent.Clone(); tempMetricEvent.Count = countIncrement; tempMetricEvent.Total = totalIncrement; tempMetricEvent.Average = totalIncrement / tempMetricEvent.Count; for (int i = 0; i < aggregateTimeWindows.Length - 1; i++) { aggregateTimeWindows[i].Update(tempMetricEvent); } // Any remaining contribution is added to the last time window. tempMetricEvent.Count = countIncrement + countRemainder; tempMetricEvent.Total = total - ((aggregateTimeWindows.Length - 1) * totalIncrement); tempMetricEvent.Average = tempMetricEvent.Total / tempMetricEvent.Count; aggregateTimeWindows[aggregateTimeWindows.Length - 1].Update(tempMetricEvent); }
void ConsumeMetricEvent(MetricEvent metricEvent) { if (this.processEventTestHook != null) { this.processEventTestHook(metricEvent); } }
// Check if we need to produce output events. Return true if we issued output protected bool CleanExpiredTimeWindows() { bool issuedOutput = false; // We only consider application time when computing the expiration time, not system time DateTime cutOffTime = this.NewestEventTimeCreated - this.Settings.ExtraExpirationWaitTime; // Find expired time windows while (this.TimeWindowList.Count > 0) { AggregateTimeWindowBase timeWindow = this.TimeWindowList[0]; if (cutOffTime < timeWindow.EndTime) { break; } MetricEvent metricEvent = timeWindow.ProduceOutput(); issuedOutput = true; // If the last output was a zero metric, don't continue to produce zero metrics if (metricEvent.Count != 0) { this.OutputEventQueue.Enqueue(metricEvent); } this.EndTimeLastProducedEvent = timeWindow.EndTime; this.TimeWindowList.RemoveAt(0); } return(issuedOutput); }
public override MetricEvent ProduceOutput() { MetricEvent metricEvent = new MetricEvent() { Name = this.AggregateTimeWindow.Key.Metric, TenantId = this.AggregateTimeWindow.Key.TenantId, EventSource = this.AggregateTimeWindow.Key.EventSource, InstanceId = this.AggregateTimeWindow.Key.InstanceId, TimeCreated = this.AggregateTimeWindow.StartTime, TimeWindow = this.AggregateTimeWindow.EndTime - this.AggregateTimeWindow.StartTime, AdditionalData = this.AdditionalData, Average = this.Value, Total = this.Total, Count = this.Count, Minimum = this.Minimum.HasValue ? this.Minimum.Value : 0, Maximum = this.Maximum.HasValue ? this.Maximum.Value : 0 }; if (this.AggregateTimeWindow.Key.Dimensions != null && this.AggregateTimeWindow.Key.Dimensions.Count > 0) { foreach (KeyValuePair <string, string> pair in this.AggregateTimeWindow.Key.Dimensions) { metricEvent.Dimensions.Add(pair.Key, pair.Value); } } return(metricEvent); }
public void Update(MetricEvent metricEvt) { AggregateGroupKey key = new AggregateGroupKey( metricEvt.EventSource, metricEvt.InstanceId, metricEvt.TenantId, metricEvt.Dimensions, metricEvt.Name); Queue <MetricEvent> writeOutputEventQueue = null; lock (this.ThisLock) { // Lookup the correct time window queue RollupAggregateTimeWindowQueue timeWindowQueue = this.GetOrCreateAggregateTimeWindowQueue(key); // Update the time window queue timeWindowQueue.Update(key, metricEvt); // Check if we need to produce output events writeOutputEventQueue = this.ProduceOutputEvents(); } this.EnqueueOutputEvents(writeOutputEventQueue); }
protected void EnqueueOutputEvents(Queue <MetricEvent> writeOutputEventQueue) { if (writeOutputEventQueue != null) { while (writeOutputEventQueue.Count > 0) { MetricEvent outputEvent = writeOutputEventQueue.Dequeue(); this.outputEventCallback(outputEvent); } } }
protected bool ShouldDiscard(MetricEvent evt) { if (evt.TimeCreated < this.EndTimeLastProducedEvent) { /* * ManagementEtwProvider.Provider.EventWriteMonitoringDropEvent( * evt.Name, evt.EventSource, evt.TimeCreated.ToString(CultureInfo.InvariantCulture), this.EndTimeLastProducedEvent.ToString(CultureInfo.InvariantCulture)); */ return(true); } return(false); }
public override void Update(MetricEvent evt) { this.Count += evt.Count; this.Total += evt.Total; if (!string.IsNullOrEmpty(evt.AdditionalData)) { this.AdditionalData = evt.AdditionalData; } if (!this.Maximum.HasValue || evt.Maximum > this.Maximum) { this.Maximum = evt.Maximum; } if (!this.Minimum.HasValue || evt.Minimum < this.Minimum) { this.Minimum = evt.Minimum; } }
void ProduceCurrentOutput() { if (this.TimeWindowList.Count > 0) { // Current output should be calculated over all existing time windows that are being tracking. The timestamp should be set to the earliest metric event. MetricEvent currentMetricEvent = this.TimeWindowList[0].ProduceOutput(); currentMetricEvent.TimeWindow = AggregationDefaults.TimeWindowCurrent; for (int i = 1; i < this.TimeWindowList.Count; i++) { MetricEvent metricEvent = this.TimeWindowList[i].ProduceOutput(); if (metricEvent.Count > 0) { currentMetricEvent.Total += metricEvent.Total; currentMetricEvent.Count += metricEvent.Count; if (metricEvent.Maximum > currentMetricEvent.Maximum) { currentMetricEvent.Maximum = metricEvent.Maximum; } if (metricEvent.Minimum > currentMetricEvent.Minimum) { currentMetricEvent.Minimum = metricEvent.Minimum; } if (!string.IsNullOrEmpty(metricEvent.AdditionalData)) { currentMetricEvent.AdditionalData = metricEvent.AdditionalData; } } } if (currentMetricEvent.Count > 0) { currentMetricEvent.Average = currentMetricEvent.Total / currentMetricEvent.Count; } this.OutputEventQueue.Enqueue(currentMetricEvent); } }
public void Update(AggregateGroupKey key, MetricEvent evt) { Fx.Assert(evt.TimeWindow != AggregationDefaults.TimeWindowCurrent, "We don't support processing speculative metric events"); if (this.ShouldDiscard(evt)) { return; } RollupAggregateTimeWindow[] aggregateTimeWindows = this.GetOrCreateAggregateTimeWindow(key, evt); if (aggregateTimeWindows.Length == 1) { aggregateTimeWindows[0].Update(evt); } else { UpdateMultipleTimeWindows(evt, aggregateTimeWindows); } this.AdvanceTime(evt.TimeCreated); this.ProduceCurrentOutput(); }
public abstract void Update(MetricEvent evt);
public void Update(MetricEvent evt) { this.State.Update(evt); }
public void Publish(MetricEvent evt) { this.synopsis.Update(evt); }
// Handles interval based events RollupAggregateTimeWindow[] GetOrCreateAggregateTimeWindow(AggregateGroupKey key, MetricEvent metricEvent) { TimeSpan timeWindow = metricEvent.TimeWindow; DateTimeOffset metricEndTime = metricEvent.TimeCreated.Add(timeWindow); List <RollupAggregateTimeWindow> foundAggregateTimeWindows = new List <RollupAggregateTimeWindow>(); // Find the correct TimeWindow that the input event belongs to foreach (RollupAggregateTimeWindow aggregateTimeWindow in this.TimeWindowList) { if ((metricEvent.TimeCreated >= aggregateTimeWindow.StartTime && metricEndTime <= aggregateTimeWindow.EndTime) || (metricEvent.TimeCreated <= aggregateTimeWindow.StartTime && metricEndTime >= aggregateTimeWindow.EndTime)) { foundAggregateTimeWindows.Add(aggregateTimeWindow); } if (metricEndTime < aggregateTimeWindow.StartTime) { break; } } // If the TimeWindow does not exist, create a new TimeWindow if (foundAggregateTimeWindows.Count == 0) { RollupAggregateTimeWindow foundAggregateTimeWindow = RollupAggregateTimeWindow.Create(key, metricEvent.TimeCreated, timeWindow); foundAggregateTimeWindows.Add(foundAggregateTimeWindow); if (this.TimeWindowList.Count == 0) { this.AppendNewFoundTimeWindow(foundAggregateTimeWindow, RollupAggregateTimeWindow.Create(key, metricEvent.TimeCreated.Add(timeWindow), timeWindow)); } else if (foundAggregateTimeWindow.StartTime >= this.TimeWindowList[this.TimeWindowList.Count - 1].EndTime) { // New TimeWindow belongs at the end. this.FillMissingTimeWindowAtEnd(key, metricEvent.TimeCreated, timeWindow); this.AppendNewFoundTimeWindow(foundAggregateTimeWindow, RollupAggregateTimeWindow.Create(key, metricEvent.TimeCreated.Add(timeWindow), timeWindow)); } else { // New TimeWindow belongs at the beginning of the list. this.FillMissingTimeWindowAtBeginning(key, foundAggregateTimeWindow.EndTime, timeWindow); this.TimeWindowList.Insert(0, foundAggregateTimeWindow); } } else { // In this case, we found matching time windows. if (foundAggregateTimeWindows[foundAggregateTimeWindows.Count - 1].EndTime < metricEndTime) { // In this case, the input event partially overlaps existing time window objects. We need to create the remaining windows on the right side. DateTime currentStartTime = foundAggregateTimeWindows[foundAggregateTimeWindows.Count - 1].EndTime; TimeSpan currentTimeWindowSpan = foundAggregateTimeWindows[foundAggregateTimeWindows.Count - 1].TimeWindow; while (currentStartTime < metricEndTime) { RollupAggregateTimeWindow currentTimeWindow = RollupAggregateTimeWindow.Create(key, currentStartTime, currentTimeWindowSpan); foundAggregateTimeWindows.Add(currentTimeWindow); this.TimeWindowList.Add(currentTimeWindow); currentStartTime = currentStartTime.Add(currentTimeWindowSpan); } } if (metricEvent.TimeCreated < foundAggregateTimeWindows[0].StartTime) { // In this case, the input event partially overlaps existing time window objects. We need to create the remaining windows on the left side. DateTime currentStartTime = metricEvent.TimeCreated; TimeSpan currentTimeWindowSpan = foundAggregateTimeWindows[0].TimeWindow; List <RollupAggregateTimeWindow> tempTimeWindowList = new List <RollupAggregateTimeWindow>(); while (currentStartTime < foundAggregateTimeWindows[0].StartTime) { RollupAggregateTimeWindow currentTimeWindow = RollupAggregateTimeWindow.Create(key, currentStartTime, currentTimeWindowSpan); tempTimeWindowList.Add(currentTimeWindow); currentStartTime = currentStartTime.Add(currentTimeWindowSpan); } this.TimeWindowList.InsertRange(0, tempTimeWindowList); foundAggregateTimeWindows.InsertRange(0, tempTimeWindowList); } } return(foundAggregateTimeWindows.ToArray()); }
public MetricEvent Clone() { MetricEvent metricEvent = new MetricEvent() { TimeCreated = this.TimeCreated, EventSource = this.EventSource, TenantId = this.TenantId, InstanceId = this.InstanceId, AdditionalData = this.AdditionalData, Name = this.Name, TimeWindow = this.TimeWindow, Count = this.Count, Total = this.Total, Average = this.Average, Minimum = this.Minimum, Maximum = this.Maximum }; foreach (KeyValuePair<string, string> pair in this.Dimensions) { metricEvent.Dimensions.Add(pair.Key, pair.Value); } return metricEvent; }
public override MetricEvent ProduceOutput() { MetricEvent metricEvent = new MetricEvent() { Name = this.AggregateTimeWindow.Key.Metric, TenantId = this.AggregateTimeWindow.Key.TenantId, EventSource = this.AggregateTimeWindow.Key.EventSource, InstanceId = this.AggregateTimeWindow.Key.InstanceId, TimeCreated = this.AggregateTimeWindow.StartTime, TimeWindow = this.AggregateTimeWindow.EndTime - this.AggregateTimeWindow.StartTime, AdditionalData = this.AdditionalData, Average = this.Value, Total = this.Total, Count = this.Count, Minimum = this.Minimum.HasValue ? this.Minimum.Value : 0, Maximum = this.Maximum.HasValue ? this.Maximum.Value : 0 }; if (this.AggregateTimeWindow.Key.Dimensions != null && this.AggregateTimeWindow.Key.Dimensions.Count > 0) { foreach (KeyValuePair<string, string> pair in this.AggregateTimeWindow.Key.Dimensions) { metricEvent.Dimensions.Add(pair.Key, pair.Value); } } return metricEvent; }