Once you deploy your Azure Functions on Azure, you need to monitor them to check when something goes wrong.
The signature of an Azure Function Run method provides the instance of ILogger that you can use to log information about your code.
Using ILogger, you can collect information from your code execution to monitor and triage errors and exceptions.
The Azure Functions platform offers built-in integration with Azure Application Insights. Using Application Insights, you can easily collect and log performance and error data, and Application Insights gives you powerful analytic tools to aggregate log traces to have a better diagnostic experience.
Enabling Application Insights for your function is very easy: just put the Application Insights instrumentation key in the function app settings with the key APPINSIGHTS_INSTRUMENTATIONKEY, as shown in the following screenshot:
You can find the Application Insights instrumentation key in the Application Insights blade, in the Overview section:
When you connect Application Insights with your function, all of your log traces that were written using the ILogger interface will be stored in Application Insights, but the Application Insights logger provider will also capture other information about your function.
For example, say that you have the following Azure Function:
public static class MonitoringFunctions
{
[FunctionName("TimerTriggerFunction")]
public static void Run(
[TimerTrigger("0 */3 * * * *")]TimerInfo myTimer,
ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}
}
If you publish it in a function app on Azure, you can go on the Application Insights instance and look at the traces written by the platform:
You can see three different traces for each execution, but only one is the trace that you wrote with the log.TraceInformation() method.
The other two traces are written by the platform, and each of them contains some important information about the execution context:
This information depends on the type of the function—for example, if you are monitoring an HTTP trigger function, you can find information about the HTTP request.
The platform writes, by default, some metric information (without you have to add lines of code of your functions but simply enable the monitoring) that you can retrieve using the following query in the analytic interface for Application Insights:
customMetrics
| order by timestamp desc
This can be seen in the following screenshot:
As you can see in the preceding screenshot, the runtime has logged the duration of your functions or the number of functions that succeeded or failed.
Finally, the platform records information about performance counters of the servers that host your function:
performanceCounters
| order by timestamp desc
This can be seen in the following screenshot:
Of course, you can log whatever you need inside your functions simply by using the ILogger instance the platform gives you, and you can use different degrees of severity for your traces:
[FunctionName("TimerTriggerFunction")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer,ILogger log)
{
var executionTimestamp = DateTime.Now;
log.LogInformation($"C# Timer trigger function executed at: {executionTimestamp}");
log.LogTrace($"Is past due: {myTimer.IsPastDue}");
log.LogTrace($"Schedule: {myTimer.Schedule}");
log.LogTrace($"Schedule Status Last: {myTimer.ScheduleStatus.Last}");
log.LogTrace($"Schedule Status Next: {myTimer.ScheduleStatus.Next}");
log.LogTrace($"Schedule Status LastUpdated: {myTimer.ScheduleStatus.LastUpdated}");
if (IsErrorOccurs())
log.LogWarning($"Something happened on your function!!!");
log.LogMetric("MyCustomMetric", CalculateMyCustomMetric());
}
In the preceding snippet, you can see different types of log tracks—for example, you can use the LogMetric method to write your own custom metric:
You can also use the LogWarning method to signal that something strange happened in your execution:
If you look at the traces shown in the preceding screenshot, you can see a column called SeverityLevel. The correspondence between LogLevel and SeverityLevel is shown in the following table:
LogLevel | SeverityLevel |
Trace | 0 |
Debug | 1 |
Information | 2 |
Warning | 3 |
Error | 4 |
Critical | 5 |
None | 6 |
You can decide which type of tracks should be written from the log of your function app by editing the host.json file. In particular, you have to edit the logging section as shown in the following snippet:
{
"version": "2.0",
"logging": {
"fileLoggingMode": "always",
"logLevel": {
"default": "Information",
"Function": "Warning"
}
}
}
The Azure Functions Runtime supports the .NET Core logging filter hierarchy, which allows you to filter the types of traces you want in the log category by category.
If you configure your host.json as shown in the preceding snippet, then the logger provider used by the Azure Functions Runtime will send only the error and critical traces from your functions to Application Insights:
To complete the section, you need to know that Application Insights divides all the tracks it receives into the following categories:
- traces: The traces generated by the log of the runtime or the function code
- requests: One request for each function invocation
- exceptions: The exceptions thrown by the runtime
- customMetrics: The count of successful and failed invocations, the success rate, and duration
- customEvents: Events tracked by the runtime—for example, HTTP requests that trigger a function
- performanceCounters: Information about the performance of the servers that the functions are running on
You must choose the right category to do your analysis.