public object BeginEvent(string eventName, string functionName = null)
            {
                string key = MetricsEventManager.GetAggregateKey(eventName, functionName);

                EventsBegan.Add(key);
                return(key);
            }
Exemple #2
0
        public async Task Scenario_Logging()
        {
            string  testData = Guid.NewGuid().ToString();
            JObject input    = new JObject
            {
                { "scenario", "logging" },
                { "input", testData },
            };

            Fixture.Host.ClearLogMessages();
            Fixture.MetricsLogger.ClearCollections();

            await Fixture.Host.BeginFunctionAsync("Scenarios", input);

            string         userCategory = LogCategories.CreateFunctionUserCategory("Scenarios");
            IList <string> logs         = null;
            await TestHelpers.Await(() =>
            {
                logs = Fixture.Host.GetLogMessages(userCategory).Select(p => p.FormattedMessage).ToList();
                return(logs.Count == 10);
            }, userMessageCallback : Fixture.Host.GetLog);

            // verify use of context.log to log complex objects
            LogMessage scriptTrace = Fixture.Host.GetLogMessages(userCategory).Single(p => p.FormattedMessage != null && p.FormattedMessage.Contains(testData));

            Assert.Equal(LogLevel.Information, scriptTrace.Level);
            JObject logEntry = JObject.Parse(scriptTrace.FormattedMessage);

            Assert.Equal("This is a test", logEntry["message"]);
            Assert.Equal(testData, logEntry["input"]);

            // verify log levels in traces
            LogMessage[] traces = Fixture.Host.GetLogMessages(userCategory).Where(t => t.FormattedMessage != null && t.FormattedMessage.Contains("loglevel")).ToArray();
            Assert.Equal(LogLevel.Information, traces[0].Level);
            Assert.Equal("loglevel default", traces[0].FormattedMessage);
            Assert.Equal(LogLevel.Information, traces[1].Level);
            Assert.Equal("loglevel info", traces[1].FormattedMessage);
            Assert.Equal(LogLevel.Trace, traces[2].Level);
            Assert.Equal("loglevel verbose", traces[2].FormattedMessage);
            Assert.Equal(LogLevel.Warning, traces[3].Level);
            Assert.Equal("loglevel warn", traces[3].FormattedMessage);
            Assert.Equal(LogLevel.Error, traces[4].Level);
            Assert.Equal("loglevel error", traces[4].FormattedMessage);

            // verify most of the logs look correct
            Assert.EndsWith("Mathew Charles", logs[1]);
            Assert.EndsWith("null", logs[2]);
            Assert.EndsWith("1234", logs[3]);
            Assert.EndsWith("true", logs[4]);
            Assert.EndsWith("loglevel default", logs[5]);
            Assert.EndsWith("loglevel info", logs[6]);

            // We only expect 9 user log metrics to be counted, since
            // verbose logs are filtered by default (the TestLogger explicitly
            // allows all levels for testing purposes)
            var key = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog, "Scenarios");

            Assert.Equal(9, Fixture.MetricsLogger.LoggedEvents.Where(p => p == key).Count());
        }
        public async Task Validate_Manual()
        {
            string functionName    = "Scenarios";
            int    invocationCount = 5;

            List <string> functionTraces = new List <string>();

            // We want to invoke this multiple times specifically to make sure Node invocationIds
            // are correctly being set. Invoke them all first, then come back and validate all.
            for (int i = 0; i < invocationCount; i++)
            {
                string functionTrace = $"Function trace: {Guid.NewGuid().ToString()}";
                functionTraces.Add(functionTrace);

                JObject input = new JObject()
                {
                    { "scenario", "appInsights" },
                    { "container", "not-used" },
                    { "value", functionTrace }
                };

                await _fixture.TestHost.BeginFunctionAsync(functionName, input);
            }

            // Now validate each function invocation.
            foreach (string functionTrace in functionTraces)
            {
                await WaitForFunctionTrace(functionName, functionTrace);

                string invocationId = await ValidateEndToEndTestAsync(functionName, functionTrace, true);

                // TODO: Remove this check when metrics are supported in Node:
                // https://github.com/Azure/azure-functions-host/issues/2189
                if (this is ApplicationInsightsCSharpEndToEndTests)
                {
                    // Do some additional metric validation
                    MetricTelemetry metric = _fixture.Channel.Telemetries
                                             .OfType <MetricTelemetry>()
                                             .Where(t => GetInvocationId(t) == invocationId)
                                             .Single();
                    ValidateMetric(metric, invocationId, functionName);
                }
            }

            // App Insights logs first, so wait until this metric appears
            string metricKey = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog, functionName);

            IEnumerable <string> GetMetrics() => _fixture.MetricsLogger.LoggedEvents.Where(p => p == metricKey);

            // TODO: Remove this check when metrics are supported in Node:
            // https://github.com/Azure/azure-functions-host/issues/2189
            int expectedCount = this is ApplicationInsightsCSharpEndToEndTests ? 10 : 5;
            await TestHelpers.Await(() => GetMetrics().Count() == expectedCount,
                                    timeout : 15000, userMessageCallback : () => string.Join(Environment.NewLine, GetMetrics().Select(p => p.ToString())));
        }
        public void Log_WritesMetric_ForUserLogs_WithoutFunctionName()
        {
            var metrics = new TestMetricsLogger();
            var logger  = new UserLogMetricsLogger(_functionCategory, metrics, _scopeProvider);

            // If for some reason the scope doesn't exist, we still want this to suceed, but
            // without a function name.
            logger.LogInformation("Message");

            var    expectedEvent = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog);
            string eventName     = metrics.LoggedEvents.Single();

            Assert.Equal(expectedEvent, eventName);
        }
Exemple #5
0
        public async Task FunctionLogging_Succeeds()
        {
            Fixture.Host.ClearLogMessages();

            string functionName = "Scenarios";
            string guid1        = Guid.NewGuid().ToString();
            string guid2        = Guid.NewGuid().ToString();

            var inputObject = new JObject
            {
                { "Scenario", "logging" },
                { "Container", "scenarios-output" },
                { "Value", $"{guid1};{guid2}" }
            };
            await Fixture.Host.BeginFunctionAsync(functionName, inputObject);

            IList <string> logs = null;
            await TestHelpers.Await(() =>
            {
                logs = Fixture.Host.GetScriptHostLogMessages().Select(p => p.FormattedMessage).Where(p => p != null).ToArray();
                return(logs.Any(p => p.Contains(guid2)));
            });

            logs.Single(p => p.EndsWith($"From TraceWriter: {guid1}"));
            logs.Single(p => p.EndsWith($"From ILogger: {guid2}"));

            // Make sure we get a metric logged from both ILogger and TraceWriter
            var key = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog, "Scenarios");

            Assert.Equal(2, Fixture.MetricsLogger.LoggedEvents.Where(p => p == key).Count());

            // Make sure we've gotten a log from the aggregator
            IEnumerable <LogMessage> getAggregatorLogs() => Fixture.Host.GetScriptHostLogMessages().Where(p => p.Category == LogCategories.Aggregator);

            await TestHelpers.Await(() => getAggregatorLogs().Any());

            var aggregatorLogs = getAggregatorLogs();

            Assert.Equal(1, aggregatorLogs.Count());

            // Make sure that no user logs made it to the EventGenerator (which the SystemLogger writes to)
            IEnumerable <FunctionTraceEvent> allLogs = Fixture.EventGenerator.GetFunctionTraceEvents();

            Assert.False(allLogs.Any(l => l.Summary.Contains("From ")));
            Assert.False(allLogs.Any(l => l.Source.EndsWith(".User")));
            Assert.False(allLogs.Any(l => l.Source == OutOfProcConstants.FunctionConsoleLogCategoryName));
            Assert.NotEmpty(allLogs);
        }
        public void Log_WritesMetric_ForUserLogs()
        {
            var metrics = new TestMetricsLogger();
            var logger  = new UserLogMetricsLogger(_functionCategory, metrics, _scopeProvider);

            // function executions will include this scope
            using (CreateFunctionScope(logger))
            {
                logger.LogInformation("Message");
            }

            var    expectedEvent = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog, _functionName);
            string eventName     = metrics.LoggedEvents.Single();

            Assert.Equal(expectedEvent, eventName);
        }
Exemple #7
0
        public void EndEvent_Function_AggregatesIntoExistingEvent()
        {
            SystemMetricEvent metricEvent;

            for (int i = 0; i < 10; i++)
            {
                metricEvent = (SystemMetricEvent)_metricsLogger.BeginEvent("Event1", "Function1");
                Thread.Sleep(50);
                _metricsLogger.EndEvent(metricEvent);
            }

            for (int i = 0; i < 5; i++)
            {
                metricEvent = (SystemMetricEvent)_metricsLogger.BeginEvent("Event1", "Function2");
                Thread.Sleep(50);
                _metricsLogger.EndEvent(metricEvent);
            }

            for (int i = 0; i < 15; i++)
            {
                metricEvent = (SystemMetricEvent)_metricsLogger.BeginEvent("Event2");
                Thread.Sleep(50);
                _metricsLogger.EndEvent(metricEvent);
            }

            Assert.Equal(3, _metricsEventManager.QueuedEvents.Count);

            string key = MetricsEventManager.GetAggregateKey("Event1", "Function1");

            metricEvent = _metricsEventManager.QueuedEvents[key];
            Assert.Equal(10, metricEvent.Count);
            Assert.Equal("event1", metricEvent.EventName);
            Assert.Equal("Function1", metricEvent.FunctionName);

            key         = MetricsEventManager.GetAggregateKey("Event1", "Function2");
            metricEvent = _metricsEventManager.QueuedEvents[key];
            Assert.Equal(5, metricEvent.Count);
            Assert.Equal("event1", metricEvent.EventName);
            Assert.Equal("Function2", metricEvent.FunctionName);

            key         = MetricsEventManager.GetAggregateKey("Event2");
            metricEvent = _metricsEventManager.QueuedEvents[key];
            Assert.Equal(15, metricEvent.Count);
            Assert.Equal("event2", metricEvent.EventName);
            Assert.Null(metricEvent.FunctionName);
        }
Exemple #8
0
        public async Task FunctionLogging_Succeeds()
        {
            Fixture.Host.ClearLogMessages();

            string functionName = "Scenarios";
            string guid1        = Guid.NewGuid().ToString();
            string guid2        = Guid.NewGuid().ToString();

            var inputObject = new JObject
            {
                { "Scenario", "logging" },
                { "Container", "scenarios-output" },
                { "Value", $"{guid1};{guid2}" }
            };
            await Fixture.Host.BeginFunctionAsync(functionName, inputObject);

            IList <string> logs = null;
            await TestHelpers.Await(() =>
            {
                logs = Fixture.Host.GetLogMessages().Select(p => p.FormattedMessage).Where(p => p != null).ToArray();
                return(logs.Any(p => p.Contains(guid2)));
            });

            logs.Single(p => p.EndsWith($"From TraceWriter: {guid1}"));
            logs.Single(p => p.EndsWith($"From ILogger: {guid2}"));

            // TODO: Re-enable once we can override the IMetricsLogger
            // Make sure we get a metric logged from both ILogger and TraceWriter
            var key = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog, "Scenarios");

            // Assert.Equal(2, Fixture.MetricsLogger.LoggedEvents.Where(p => p == key).Count());

            // Make sure we've gotten a log from the aggregator
            IEnumerable <LogMessage> getAggregatorLogs() => Fixture.Host.GetLogMessages().Where(p => p.Category == LogCategories.Aggregator);

            await TestHelpers.Await(() => getAggregatorLogs().Any());

            var aggregatorLogs = getAggregatorLogs();

            Assert.Equal(1, aggregatorLogs.Count());
        }
Exemple #9
0
        public void LogEvent_Function_AggregatesIntoExistingEvent()
        {
            Assert.Equal(0, _metricsEventManager.QueuedEvents.Count);

            for (int i = 0; i < 10; i++)
            {
                _metricsLogger.LogEvent("Event1", "Function1");
            }

            for (int i = 0; i < 5; i++)
            {
                _metricsLogger.LogEvent("Event1", "Function2");
            }

            for (int i = 0; i < 15; i++)
            {
                _metricsLogger.LogEvent("Event3");
            }

            Assert.Equal(3, _metricsEventManager.QueuedEvents.Count);

            string key         = MetricsEventManager.GetAggregateKey("Event1", "Function1");
            var    metricEvent = _metricsEventManager.QueuedEvents[key];

            Assert.Equal(10, metricEvent.Count);
            Assert.Equal("event1", metricEvent.EventName);
            Assert.Equal("Function1", metricEvent.FunctionName);

            key         = MetricsEventManager.GetAggregateKey("Event1", "Function2");
            metricEvent = _metricsEventManager.QueuedEvents[key];
            Assert.Equal(5, metricEvent.Count);
            Assert.Equal("event1", metricEvent.EventName);
            Assert.Equal("Function2", metricEvent.FunctionName);

            key         = MetricsEventManager.GetAggregateKey("Event3");
            metricEvent = _metricsEventManager.QueuedEvents[key];
            Assert.Equal(15, metricEvent.Count);
            Assert.Equal("event3", metricEvent.EventName);
            Assert.Null(metricEvent.FunctionName);
        }
Exemple #10
0
        public void GetAggregateKey_ReturnsExpectedValue(string eventName, string functionName, string expected)
        {
            string result = MetricsEventManager.GetAggregateKey(eventName, functionName);

            Assert.Equal(expected, result);
        }
 public void LogEvent(string eventName, string functionName = null)
 {
     LoggedEvents.Add(MetricsEventManager.GetAggregateKey(eventName, functionName));
 }
        public async Task Scenario_Logging()
        {
            string  testData = Guid.NewGuid().ToString();
            JObject input    = new JObject
            {
                { "scenario", "logging" },
                { "input", testData },
            };

            Fixture.Host.ClearLogMessages();
            Fixture.MetricsLogger.ClearCollections();

            await Fixture.Host.BeginFunctionAsync("Scenarios", input);

            string         userCategory = LogCategories.CreateFunctionUserCategory("Scenarios");
            IList <string> userLogs     = null;
            string         consoleLog   = null;
            await TestHelpers.Await(() =>
            {
                userLogs   = Fixture.Host.GetScriptHostLogMessages(userCategory).Select(p => p.FormattedMessage).ToList();
                consoleLog = Fixture.Host.GetScriptHostLogMessages(WorkerConstants.FunctionConsoleLogCategoryName).Select(p => p.FormattedMessage).SingleOrDefault();
                return(userLogs.Count == 10 && consoleLog != null);
            }, userMessageCallback : Fixture.Host.GetLog);

            // verify use of context.log to log complex objects
            LogMessage scriptTrace = Fixture.Host.GetScriptHostLogMessages(userCategory).Single(p => p.FormattedMessage != null && p.FormattedMessage.Contains(testData));

            Assert.Equal(LogLevel.Information, scriptTrace.Level);
            JObject logEntry = JObject.Parse(scriptTrace.FormattedMessage);

            Assert.Equal("This is a test", logEntry["message"]);
            Assert.Equal(testData, logEntry["input"]);

            // verify log levels in traces
            LogMessage[] traces = Fixture.Host.GetScriptHostLogMessages(userCategory).Where(t => t.FormattedMessage != null && t.FormattedMessage.Contains("loglevel")).ToArray();
            Assert.Equal(LogLevel.Information, traces[0].Level);
            Assert.Equal("loglevel default", traces[0].FormattedMessage);
            Assert.Equal(LogLevel.Information, traces[1].Level);
            Assert.Equal("loglevel info", traces[1].FormattedMessage);
            Assert.Equal(LogLevel.Trace, traces[2].Level);
            Assert.Equal("loglevel verbose", traces[2].FormattedMessage);
            Assert.Equal(LogLevel.Warning, traces[3].Level);
            Assert.Equal("loglevel warn", traces[3].FormattedMessage);
            Assert.Equal(LogLevel.Error, traces[4].Level);
            Assert.Equal("loglevel error", traces[4].FormattedMessage);

            // verify most of the logs look correct
            Assert.EndsWith("Mathew Charles", userLogs[1]);
            Assert.EndsWith("null", userLogs[2]);
            Assert.EndsWith("1234", userLogs[3]);
            Assert.EndsWith("true", userLogs[4]);
            Assert.EndsWith("loglevel default", userLogs[5]);
            Assert.EndsWith("loglevel info", userLogs[6]);

            // verify the console log
            Assert.Equal("console log", consoleLog);

            // We only expect 9 user log metrics to be counted, since
            // verbose logs are filtered by default (the TestLogger explicitly
            // allows all levels for testing purposes)
            var key = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog, "Scenarios");

            Assert.Equal(9, Fixture.MetricsLogger.LoggedEvents.Where(p => p == key).Count());

            // Make sure that no user logs made it to the EventGenerator (which the SystemLogger writes to)
            IEnumerable <FunctionTraceEvent> allLogs = Fixture.EventGenerator.GetFunctionTraceEvents();

            Assert.False(allLogs.Any(l => l.Summary.Contains("loglevel")));
            Assert.False(allLogs.Any(l => l.Summary.Contains("after done")));
            Assert.False(allLogs.Any(l => l.Source.EndsWith(".User")));
            Assert.False(allLogs.Any(l => l.Source == WorkerConstants.FunctionConsoleLogCategoryName));
            Assert.NotEmpty(allLogs);
        }