//------------------------------------------------------------------------------
        //
        // Method: ProcessIntervalMetricEvent
        //
        //------------------------------------------------------------------------------
        /// <summary>
        /// Writes an interval metric event to the database.
        /// </summary>
        /// <param name="intervalMetricEvent">The interval metric event to write.</param>
        /// <param name="duration">The duration of the interval metric event in milliseconds.</param>
        protected override void ProcessIntervalMetricEvent(IntervalMetricEventInstance intervalMetricEvent, long duration)
        {
            StringBuilder sqlInsertStatement = new StringBuilder();

            sqlInsertStatement.Append("INSERT ");
            sqlInsertStatement.Append("INTO    IntervalMetricInstances ");
            sqlInsertStatement.Append("        ( CtgrId, ");
            sqlInsertStatement.Append("          ImetId, ");
            sqlInsertStatement.Append("          MilliSeconds, ");
            sqlInsertStatement.Append("          [Timestamp] ");
            sqlInsertStatement.Append("          ) ");
            sqlInsertStatement.Append("SELECT  Ctgr.CtgrId, ");
            sqlInsertStatement.Append("        Imet.ImetId, ");
            sqlInsertStatement.Append("        " + duration.ToString() + ", ");
            sqlInsertStatement.Append("        '" + intervalMetricEvent.EventTime.ToString("yyyy-MM-dd HH:mm:ss") + "' ");
            sqlInsertStatement.Append("FROM    IntervalMetrics Imet, ");
            sqlInsertStatement.Append("        Categories Ctgr ");
            sqlInsertStatement.Append("WHERE   Imet.Name = '" + intervalMetricEvent.Metric.Name + "' ");
            sqlInsertStatement.Append("  AND   Ctgr.Name = '" + metricCategoryName + "';");

            dbCommand.CommandText = sqlInsertStatement.ToString();

            try
            {
                dbCommand.ExecuteNonQuery();
            }
            catch (Exception e)
            {
                exceptionHandler.Handle(new Exception("Failed to insert instance of interval metric '" + intervalMetricEvent.Metric.Name + "'.", e));
            }
        }
 //------------------------------------------------------------------------------
 //
 // Method: ProcessIntervalMetricEvent
 //
 //------------------------------------------------------------------------------
 /// <summary>
 /// Adds the duration for the specified interval metric event to the stored total.
 /// </summary>
 /// <param name="intervalMetricEvent">The interval metric event.</param>
 /// <param name="duration">The duration of the interval metric event in milliseconds.</param>
 protected override void ProcessIntervalMetricEvent(IntervalMetricEventInstance intervalMetricEvent, long duration)
 {
     if (intervalMetricTotals.ContainsKey(intervalMetricEvent.MetricType) == false)
     {
         intervalMetricTotals.Add(intervalMetricEvent.MetricType, new IntervalMetricTotalContainer(intervalMetricEvent.Metric));
     }
     intervalMetricTotals[intervalMetricEvent.MetricType].Add(duration);
 }
Ejemplo n.º 3
0
        protected override void ProcessIntervalMetricEvent(IntervalMetricEventInstance intervalMetricEvent, long duration)
        {
            StringBuilder stringBuilder = InitializeStringBuilder(intervalMetricEvent.EventTime.ToLocalTime());

            stringBuilder.Append(intervalMetricEvent.Metric.Name);
            AppendSeparatorCharacter(stringBuilder);
            stringBuilder.Append(duration);
            streamWriter.WriteLine(stringBuilder.ToString());
            streamWriter.Flush();
        }
        //------------------------------------------------------------------------------
        //
        // Method: DequeueAndProcessIntervalMetricEvents
        //
        //------------------------------------------------------------------------------
        /// <summary>
        /// Dequeues interval metric events stored in the internal buffer and calls abstract method ProcessIntervalMetricEvent() to process them.
        /// </summary>
        private void DequeueAndProcessIntervalMetricEvents()
        {
            Queue <IntervalMetricEventInstance> tempQueue;

            // Lock the interval metric queue and move all items to the temporary queue
            lock (intervalMetricEventQueueLock)
            {
                tempQueue = new Queue <IntervalMetricEventInstance>(intervalMetricEventQueue);
                intervalMetricEventQueue.Clear();
                bufferProcessingStrategy.NotifyIntervalMetricEventBufferCleared();
            }

            // Process all items in the temporary queue
            while (tempQueue.Count > 0)
            {
                IntervalMetricEventInstance currentIntervalMetricEvent = tempQueue.Dequeue();

                switch (currentIntervalMetricEvent.TimePoint)
                {
                // If the current interval metric represents the start of the interval, put it in the dictionary object
                case IntervalMetricEventTimePoint.Start:
                    if (startIntervalMetricEventStore.ContainsKey(currentIntervalMetricEvent.MetricType) == true)
                    {
                        // If a start interval event of this type was already received and checking is enabled, throw an exception
                        if (intervalMetricChecking == true)
                        {
                            exceptionHandler.Handle(new InvalidOperationException("Received duplicate begin '" + currentIntervalMetricEvent.Metric.Name + "' metrics."));
                        }
                        // If checking is not enabled, replace the currently stored begin interval event with the new one
                        else
                        {
                            startIntervalMetricEventStore.Remove(currentIntervalMetricEvent.MetricType);
                            startIntervalMetricEventStore.Add(currentIntervalMetricEvent.MetricType, currentIntervalMetricEvent);
                        }
                    }
                    else
                    {
                        startIntervalMetricEventStore.Add(currentIntervalMetricEvent.MetricType, currentIntervalMetricEvent);
                    }
                    break;

                // If the current interval metric represents the end of the interval, call the method to process it
                case IntervalMetricEventTimePoint.End:
                    if (startIntervalMetricEventStore.ContainsKey(currentIntervalMetricEvent.MetricType) == true)
                    {
                        TimeSpan intervalDuration = currentIntervalMetricEvent.EventTime.Subtract(startIntervalMetricEventStore[currentIntervalMetricEvent.MetricType].EventTime);
                        double   intervalDurationMillisecondsDouble = intervalDuration.TotalMilliseconds;
                        // If the duration is less then 0 set back to 0, as the start time could be after the end time in the case the metric event occurred across a system time update
                        if (intervalDurationMillisecondsDouble < 0)
                        {
                            intervalDurationMillisecondsDouble = 0;
                        }
                        // Convert double to long
                        //   There should not be a risk of overflow here, as the number of milliseconds between DateTime.MinValue and DateTime.MaxValue is 315537897600000, which is a valid long value
                        long intervalDurationMillisecondsLong = Convert.ToInt64(intervalDurationMillisecondsDouble);

                        ProcessIntervalMetricEvent(startIntervalMetricEventStore[currentIntervalMetricEvent.MetricType], intervalDurationMillisecondsLong);

                        startIntervalMetricEventStore.Remove(currentIntervalMetricEvent.MetricType);
                    }
                    else
                    {
                        // If no corresponding start interval event of this type exists and checking is enabled, throw an exception
                        if (intervalMetricChecking == true)
                        {
                            exceptionHandler.Handle(new InvalidOperationException("Received end '" + currentIntervalMetricEvent.Metric.Name + "' with no corresponding start interval metric."));
                        }
                        // If checking is not enabled discard the interval event
                    }
                    break;

                // If the current interval metric represents the cancelling of the interval, remove it from the dictionary object
                case IntervalMetricEventTimePoint.Cancel:
                    if (startIntervalMetricEventStore.ContainsKey(currentIntervalMetricEvent.MetricType) == true)
                    {
                        startIntervalMetricEventStore.Remove(currentIntervalMetricEvent.MetricType);
                    }
                    else
                    {
                        // If no corresponding start interval event of this type exists and checking is enabled, throw an exception
                        if (intervalMetricChecking == true)
                        {
                            exceptionHandler.Handle(new InvalidOperationException("Received cancel '" + currentIntervalMetricEvent.Metric.Name + "' with no corresponding start interval metric."));
                        }
                        // If checking is not enabled discard the interval event
                    }
                    break;
                }
            }
        }
 //------------------------------------------------------------------------------
 //
 // Method: ProcessIntervalMetricEvent
 //
 //------------------------------------------------------------------------------
 /// <summary>
 /// Processes a logged interval metric event.
 /// </summary>
 /// <param name="intervalMetricEvent">The interval metric event to process.</param>
 /// <param name="duration">The duration of the interval metric event in milliseconds.</param>
 /// <remarks>Implementations of this method define how an interval metric event should be processed after it has been retrieved from the internal buffer queue.  The event could for example be written to a database, or to the console.</remarks>
 protected abstract void ProcessIntervalMetricEvent(IntervalMetricEventInstance intervalMetricEvent, long duration);