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 TQueue GetOrCreateAggregateTimeWindowQueue(AggregateGroupKey key) { TQueue timeWindowQueue; if (!this.timeWindowQueueMap.TryGetValue(key, out timeWindowQueue)) { timeWindowQueue = this.CreateAggregateTimeWindowQueue(this.OutputEventQueue); this.timeWindowQueueMap.Add(key, timeWindowQueue); } return(timeWindowQueue); }
public void Update(AggregateGroupKey key, ResourceEvent evt) { if (this.ShouldDiscard(evt)) { return; } AggregateTimeWindow aggregateTimeWindow = this.GetOrCreateAggregateTimeWindow(key, evt, this.Settings.TimeWindow); aggregateTimeWindow.Update(evt); this.AdvanceTime(evt.TimeCreated); }
public override bool Equals(object obj) { AggregateGroupKey otherKey = obj as AggregateGroupKey; if (otherKey != null) { return(this.EventSource.Equals(otherKey.EventSource) && this.InstanceId.Equals(otherKey.InstanceId) && this.TenantId.Equals(otherKey.TenantId) && this.DimensionsKey.Equals(otherKey.DimensionsKey) && this.Metric.Equals(otherKey.Metric)); } return(false); }
protected void FillMissingTimeWindowAtEnd(AggregateGroupKey key, DateTime metricStartTime, TimeSpan metricTimeWindowSpan) { DateTime currentStartTime = this.TimeWindowList[this.TimeWindowList.Count - 1].EndTime; if (currentStartTime < metricStartTime) { // We need to construct TimeWindows to fill in missing gaps. // Use the smaller of the time intervals so that the missing gaps can be constructed to cover the timeline. TimeSpan currentTimeWindow = MinimumTimeSpan(this.TimeWindowList[this.TimeWindowList.Count - 1].TimeWindow, metricTimeWindowSpan); while (currentStartTime < metricStartTime) { this.TimeWindowList.Add(this.CreateAggregateTimeWindow(key, currentStartTime, currentTimeWindow)); currentStartTime = currentStartTime.Add(currentTimeWindow); } } }
AggregateTimeWindow GetOrCreateAggregateTimeWindow(AggregateGroupKey key, ResourceEvent evt, TimeSpan timeWindow) { AggregateTimeWindow foundAggregateTimeWindow = null; // Find the correct TimeWindow that the input event belongs to foreach (AggregateTimeWindow aggregateTimeWindow in this.TimeWindowList) { // When checking if an event belongs to a time window, the window is represented as [a, b) if (evt.TimeCreated >= aggregateTimeWindow.StartTime && evt.TimeCreated < aggregateTimeWindow.EndTime) { foundAggregateTimeWindow = aggregateTimeWindow; break; } } // If the TimeWindow does not exist, create a new TimeWindow if (foundAggregateTimeWindow == null) { // We want time windows to start on well defined boundaries DateTime startTime = AggregationUtility.SnapTimeWindowStartTime(evt.TimeCreated, timeWindow); TimeSpan timeWindowSpan = timeWindow; foundAggregateTimeWindow = AggregateTimeWindow.Create(key, startTime, timeWindowSpan); if (this.TimeWindowList.Count == 0) { this.AppendNewFoundTimeWindow(foundAggregateTimeWindow, AggregateTimeWindow.Create(key, startTime.Add(timeWindowSpan), timeWindowSpan)); } else if (foundAggregateTimeWindow.StartTime >= this.TimeWindowList[this.TimeWindowList.Count - 1].EndTime) { // New TimeWindow belongs at the end. this.FillMissingTimeWindowAtEnd(key, startTime, timeWindowSpan); this.AppendNewFoundTimeWindow(foundAggregateTimeWindow, AggregateTimeWindow.Create(key, startTime.Add(timeWindowSpan), timeWindowSpan)); } else { // New TimeWindow belongs at the beginning of the list. this.FillMissingTimeWindowAtBeginning(key, foundAggregateTimeWindow.EndTime, timeWindowSpan); this.TimeWindowList.Insert(0, foundAggregateTimeWindow); } } return(foundAggregateTimeWindow); }
protected void FillMissingTimeWindowAtBeginning(AggregateGroupKey key, DateTime metricEndTime, TimeSpan metricTimeWindowSpan) { DateTime currentStartTime = metricEndTime; if (currentStartTime < this.TimeWindowList[0].StartTime) { List <T> tempTimeWindowList = new List <T>(); // We need to construct TimeWindows to fill in missing gaps. // Use the smaller of the time intervals so that the missing gaps can be constructed to cover the timeline. TimeSpan currentTimeWindow = MinimumTimeSpan(this.TimeWindowList[0].TimeWindow, metricTimeWindowSpan); while (currentStartTime < this.TimeWindowList[0].StartTime) { tempTimeWindowList.Add(this.CreateAggregateTimeWindow(key, currentStartTime, currentTimeWindow)); currentStartTime = currentStartTime.Add(currentTimeWindow); } this.TimeWindowList.InsertRange(0, tempTimeWindowList); } }
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 static RollupAggregateTimeWindow Create(AggregateGroupKey key, DateTime startTime, TimeSpan timeWindow) { DateTime endTime = startTime.Add(timeWindow); return(Create(key, startTime, endTime)); }
public static RollupAggregateTimeWindow Create(AggregateGroupKey key, DateTime startTime, DateTime endTime) { return(new RollupAggregateTimeWindow(key, startTime, endTime)); }
public static RollupAggregateTimeWindow Create(AggregateGroupKey key, DateTime startTime, DateTime endTime) { return new RollupAggregateTimeWindow(key, startTime, endTime); }
private RollupAggregateTimeWindow(AggregateGroupKey key, DateTime startTime, DateTime endTime) : base(key, startTime, endTime) { this.State = new AverageAggregateState(this); }
public static RollupAggregateTimeWindow Create(AggregateGroupKey key, DateTime startTime, TimeSpan timeWindow) { DateTime endTime = startTime.Add(timeWindow); return Create(key, startTime, endTime); }
public AggregateTimeWindowBase(AggregateGroupKey key, DateTime startTime, DateTime endTime) { this.Key = key; this.StartTime = startTime; this.EndTime = endTime; }
protected abstract T CreateAggregateTimeWindow(AggregateGroupKey key, DateTime startTime, TimeSpan timeWindow);
// 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()); }
protected override RollupAggregateTimeWindow CreateAggregateTimeWindow(AggregateGroupKey key, DateTime startTime, TimeSpan timeWindow) { return(RollupAggregateTimeWindow.Create(key, startTime, timeWindow)); }