public void CreateTraceMonitor_SlidingWindow()
        {
            ParameterInfo parameter = typeof(Functions).GetMethod("SlidingWindowErrorHandler").GetParameters()[0];

            TraceMonitor traceMonitor = ErrorTriggerListener.CreateTraceMonitor(parameter, _mockExecutor.Object);

            SlidingWindowTraceFilter traceFilter = (SlidingWindowTraceFilter)traceMonitor.Filters.Single();

            Assert.Equal(5, traceFilter.Threshold);
            Assert.Equal("5 events at level 'Error' or lower have occurred within time window 00:05:00.", traceFilter.Message);
        }
        public void CreateTraceMonitor_SlidingWindow_Customized()
        {
            ParameterInfo parameter = typeof(Functions).GetMethod("SlidingWindowErrorHandler_Customized").GetParameters()[0];

            TraceMonitor traceMonitor = ErrorTriggerListener.CreateTraceMonitor(parameter, _mockExecutor.Object);

            SlidingWindowTraceFilter traceFilter = (SlidingWindowTraceFilter)traceMonitor.Filters.Single();

            Assert.Equal(5, traceFilter.Threshold);
            Assert.Equal("Custom Message", traceFilter.Message);
        }
        public void Constructor_DefaultsMessage()
        {
            SlidingWindowTraceFilter filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 5);
            Assert.Equal("5 events at level 'Error' or lower have occurred within time window 00:10:00.", filter.Message);

            filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 5, message: "Custom Message");
            Assert.Equal("Custom Message", filter.Message);

            filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 5, level: TraceLevel.Warning);
            Assert.Equal("5 events at level 'Warning' or lower have occurred within time window 00:10:00.", filter.Message);
        }
示例#4
0
        public void Constructor_DefaultsMessage()
        {
            SlidingWindowTraceFilter filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 5);

            Assert.Equal("5 events at level 'Error' or lower have occurred within time window 00:10:00.", filter.Message);

            filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 5, message: "Custom Message");
            Assert.Equal("Custom Message", filter.Message);

            filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 5, level: TraceLevel.Warning);
            Assert.Equal("5 events at level 'Warning' or lower have occurred within time window 00:10:00.", filter.Message);
        }
示例#5
0
        public void Filter_ReturnsTrueWhenThresholdReached()
        {
            SlidingWindowTraceFilter filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 3);

            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 1")));
            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 2")));
            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Info, "Error 3")));  // expect this to be ignored based on Level
            Assert.True(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 4")));

            Assert.Equal(3, filter.Events.Count);
            Assert.Equal("Error 1", filter.Events[0].Message);
            Assert.Equal("Error 2", filter.Events[1].Message);
            Assert.Equal("Error 4", filter.Events[2].Message);
        }
        public void Filter_ReturnsTrueWhenThresholdReached()
        {
            SlidingWindowTraceFilter filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 3);

            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 1")));
            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 2")));
            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Info, "Error 3")));  // expect this to be ignored based on Level
            Assert.True(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 4")));

            Assert.Equal(3, filter.Events.Count);
            Assert.Equal("Error 1", filter.Events[0].Message);
            Assert.Equal("Error 2", filter.Events[1].Message);
            Assert.Equal("Error 4", filter.Events[2].Message);
        }
示例#7
0
        public void RemoveOldEvents_RemovesEventsOutsideWindow()
        {
            SlidingWindowTraceFilter filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 5);

            DateTime now = DateTime.Now - TimeSpan.FromMinutes(10);

            Assert.Equal(0, filter.GetEvents().Count());
            filter.RemoveOldEvents(now);
            Assert.Equal(0, filter.GetEvents().Count());

            // add some events over a few minutes
            for (int i = 0; i < 10; i++)
            {
                now += TimeSpan.FromMinutes(1);
                var traceEvent = new TraceEvent(TraceLevel.Error, string.Format("Error {0}", i))
                {
                    Timestamp = now
                };
                filter.AddEvent(traceEvent);
            }

            Assert.Equal(10, filter.GetEvents().Count());
            filter.RemoveOldEvents(now);
            IEnumerable <TraceEvent> traceEvents = filter.GetEvents();

            Assert.Equal(10, traceEvents.Count());
            Assert.Equal("Error 0", traceEvents.First().Message);
            Assert.Equal("Error 9", traceEvents.Last().Message);

            // now advance forward a minute
            now += TimeSpan.FromMinutes(1);
            filter.RemoveOldEvents(now);
            traceEvents = filter.GetEvents();
            Assert.Equal(9, traceEvents.Count());
            Assert.Equal("Error 1", traceEvents.First().Message);
            Assert.Equal("Error 9", traceEvents.Last().Message);

            // now advance forward a few more minutes
            now += TimeSpan.FromMinutes(5);
            filter.RemoveOldEvents(now);
            traceEvents = filter.GetEvents();
            Assert.Equal(4, traceEvents.Count());
            Assert.Equal("Error 6", traceEvents.First().Message);
            Assert.Equal("Error 9", traceEvents.Last().Message);

            // finally advance forward past all existing events
            now += TimeSpan.FromMinutes(5);
            filter.RemoveOldEvents(now);
            Assert.Equal(0, filter.GetEvents().Count());
        }
示例#8
0
        public void Filter_AppliesInnerFilter()
        {
            Func <TraceEvent, bool> innerFilter = p => !p.Message.Contains("Ignore");

            SlidingWindowTraceFilter filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 3, innerFilter);

            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 1")));
            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 2")));
            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Info, "Error 3")));          // expect this to be ignored based on Level
            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Info, "Error 4 (Ignore)"))); // expect this to be ignored based inner filter
            Assert.True(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 5")));

            Assert.Equal(3, filter.Events.Count);
            Assert.Equal("Error 1", filter.Events[0].Message);
            Assert.Equal("Error 2", filter.Events[1].Message);
            Assert.Equal("Error 5", filter.Events[2].Message);
        }
        public void RemoveOldEvents_RemovesEventsOutsideWindow()
        {
            SlidingWindowTraceFilter filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 5);

            DateTime now = DateTime.UtcNow - TimeSpan.FromMinutes(10);

            Assert.Equal(0, filter.Events.Count);
            filter.RemoveOldEvents(now);
            Assert.Equal(0, filter.Events.Count);

            // add some events over a few minutes
            for (int i = 0; i < 10; i++)
            {
                now += TimeSpan.FromMinutes(1);
                var traceEvent = new TraceEvent(TraceLevel.Error, string.Format("Error {0}", i))
                {
                    Timestamp = now
                };
                filter.Events.Add(traceEvent);
            }

            Assert.Equal(10, filter.Events.Count);
            filter.RemoveOldEvents(now);
            Assert.Equal(10, filter.Events.Count);
            Assert.Equal("Error 0", filter.Events.First().Message);
            Assert.Equal("Error 9", filter.Events.Last().Message);

            // now advance forward a minute
            now += TimeSpan.FromMinutes(1);
            filter.RemoveOldEvents(now);
            Assert.Equal(9, filter.Events.Count);
            Assert.Equal("Error 1", filter.Events.First().Message);
            Assert.Equal("Error 9", filter.Events.Last().Message);

            // now advance forward a few more minutes
            now += TimeSpan.FromMinutes(5);
            filter.RemoveOldEvents(now);
            Assert.Equal(4, filter.Events.Count);
            Assert.Equal("Error 6", filter.Events.First().Message);
            Assert.Equal("Error 9", filter.Events.Last().Message);

            // finally advance forward past all existing events
            now += TimeSpan.FromMinutes(5);
            filter.RemoveOldEvents(now);
            Assert.Equal(0, filter.Events.Count);
        }
        internal static TraceMonitor CreateTraceMonitor(ParameterInfo parameter, ITriggeredFunctionExecutor executor)
        {
            ErrorTriggerAttribute attribute = parameter.GetCustomAttribute<ErrorTriggerAttribute>(inherit: false);

            // Determine whether this is a method level filter, and if so, create the filter
            Func<TraceEvent, bool> methodFilter = null;
            MethodInfo method = (MethodInfo)parameter.Member;
            string functionLevelMessage = null;
            if (method.Name.EndsWith(ErrorHandlerSuffix, StringComparison.OrdinalIgnoreCase))
            {
                string sourceMethodName = method.Name.Substring(0, method.Name.Length - ErrorHandlerSuffix.Length);
                MethodInfo sourceMethod = method.DeclaringType.GetMethod(sourceMethodName);
                if (sourceMethod != null)
                {
                    string sourceMethodFullName = string.Format("{0}.{1}", method.DeclaringType.FullName, sourceMethod.Name);
                    methodFilter = p =>
                    {
                        FunctionInvocationException functionException = p.Exception as FunctionInvocationException;
                        return p.Level == System.Diagnostics.TraceLevel.Error && functionException != null &&
                               string.Compare(functionException.MethodName, sourceMethodFullName, StringComparison.OrdinalIgnoreCase) == 0;
                    };

                    string sourceMethodShortName = string.Format("{0}.{1}", method.DeclaringType.Name, sourceMethod.Name);
                    functionLevelMessage = string.Format("Function '{0}' failed.", sourceMethodShortName);
                }
            }

            string errorHandlerFullName = string.Format("{0}.{1}", method.DeclaringType.FullName, method.Name);
            ErrorHandlers.Add(errorHandlerFullName);

            // Create the TraceFilter instance
            TraceFilter traceFilter = null;
            if (attribute.FilterType != null)
            {
                if (methodFilter != null)
                {
                    TraceFilter innerTraceFilter = (TraceFilter)Activator.CreateInstance(attribute.FilterType);
                    traceFilter = new CompositeTraceFilter(innerTraceFilter, methodFilter, attribute.Message ?? functionLevelMessage);
                }
                else
                {
                    traceFilter = (TraceFilter)Activator.CreateInstance(attribute.FilterType);
                }
            }
            else if (!string.IsNullOrEmpty(attribute.Window))
            {
                TimeSpan window = TimeSpan.Parse(attribute.Window);
                traceFilter = new SlidingWindowTraceFilter(window, attribute.Threshold, methodFilter, attribute.Message);
            }
            else
            {
                traceFilter = TraceFilter.Create(methodFilter, attribute.Message ?? functionLevelMessage);
            }
            TraceMonitor traceMonitor = new TraceMonitor().Filter(traceFilter);

            // Apply any additional monitor options
            if (!string.IsNullOrEmpty(attribute.Throttle))
            {
                TimeSpan throttle = TimeSpan.Parse(attribute.Throttle);
                traceMonitor.Throttle(throttle);
            }

            // Subscribe the error handler function to the error stream
            traceMonitor.Subscribe(p =>
            {
                TriggeredFunctionData triggerData = new TriggeredFunctionData
                {
                    TriggerValue = p
                };
                Task<FunctionResult> task = executor.TryExecuteAsync(triggerData, CancellationToken.None);
                task.Wait();
            });

            return traceMonitor;
        }
示例#11
0
        internal static TraceMonitor CreateTraceMonitor(ParameterInfo parameter, ITriggeredFunctionExecutor executor)
        {
            ErrorTriggerAttribute attribute = parameter.GetCustomAttribute <ErrorTriggerAttribute>(inherit: false);

            // Determine whether this is a method level filter, and if so, create the filter
            Func <TraceEvent, bool> methodFilter = null;
            MethodInfo method = (MethodInfo)parameter.Member;
            string     functionLevelMessage = null;

            if (method.Name.EndsWith(ErrorHandlerSuffix, StringComparison.OrdinalIgnoreCase))
            {
                string     sourceMethodName = method.Name.Substring(0, method.Name.Length - ErrorHandlerSuffix.Length);
                MethodInfo sourceMethod     = method.DeclaringType.GetMethod(sourceMethodName);
                if (sourceMethod != null)
                {
                    string sourceMethodFullName = string.Format("{0}.{1}", method.DeclaringType.FullName, sourceMethod.Name);
                    methodFilter = p =>
                    {
                        FunctionInvocationException functionException = p.Exception as FunctionInvocationException;
                        return(p.Level == System.Diagnostics.TraceLevel.Error && functionException != null &&
                               string.Compare(functionException.MethodName, sourceMethodFullName, StringComparison.OrdinalIgnoreCase) == 0);
                    };

                    string sourceMethodShortName = string.Format("{0}.{1}", method.DeclaringType.Name, sourceMethod.Name);
                    functionLevelMessage = string.Format("Function '{0}' failed.", sourceMethodShortName);
                }
            }

            string errorHandlerFullName = string.Format("{0}.{1}", method.DeclaringType.FullName, method.Name);

            ErrorHandlers.Add(errorHandlerFullName);

            // Create the TraceFilter instance
            TraceFilter traceFilter = null;

            if (attribute.FilterType != null)
            {
                if (methodFilter != null)
                {
                    TraceFilter innerTraceFilter = (TraceFilter)Activator.CreateInstance(attribute.FilterType);
                    traceFilter = new CompositeTraceFilter(innerTraceFilter, methodFilter, attribute.Message ?? functionLevelMessage);
                }
                else
                {
                    traceFilter = (TraceFilter)Activator.CreateInstance(attribute.FilterType);
                }
            }
            else if (!string.IsNullOrEmpty(attribute.Window))
            {
                TimeSpan window = TimeSpan.Parse(attribute.Window);
                traceFilter = new SlidingWindowTraceFilter(window, attribute.Threshold, methodFilter, attribute.Message);
            }
            else
            {
                traceFilter = TraceFilter.Create(methodFilter, attribute.Message ?? functionLevelMessage);
            }
            TraceMonitor traceMonitor = new TraceMonitor().Filter(traceFilter);

            // Apply any additional monitor options
            if (!string.IsNullOrEmpty(attribute.Throttle))
            {
                TimeSpan throttle = TimeSpan.Parse(attribute.Throttle);
                traceMonitor.Throttle(throttle);
            }

            // Subscribe the error handler function to the error stream
            traceMonitor.Subscribe(p =>
            {
                TriggeredFunctionData triggerData = new TriggeredFunctionData
                {
                    TriggerValue = p
                };
                Task <FunctionResult> task = executor.TryExecuteAsync(triggerData, CancellationToken.None);
                task.Wait();
            });

            return(traceMonitor);
        }
        public void Filter_AppliesInnerFilter()
        {
            Func<TraceEvent, bool> innerFilter = p => !p.Message.Contains("Ignore");

            SlidingWindowTraceFilter filter = new SlidingWindowTraceFilter(TimeSpan.FromMinutes(10), 3, innerFilter);

            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 1")));
            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 2")));
            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Info, "Error 3")));  // expect this to be ignored based on Level
            Assert.False(filter.Filter(new TraceEvent(TraceLevel.Info, "Error 4 (Ignore)")));  // expect this to be ignored based inner filter
            Assert.True(filter.Filter(new TraceEvent(TraceLevel.Error, "Error 5")));

            Assert.Equal(3, filter.Events.Count);
            Assert.Equal("Error 1", filter.Events[0].Message);
            Assert.Equal("Error 2", filter.Events[1].Message);
            Assert.Equal("Error 5", filter.Events[2].Message);
        }