AzureFunctions

Azure Functions in C# quick FAQs and tips

4 min read

I get pinged once a while about something that doesn’t behave properly in Azure Functions, or about a general question about Azure Functions. I usually direct the developers to the right places. But I figured it would be a great idea to put all the answers I give in a post for future reference.

Questions

I use ILogger<T>, but it is not logging to the console when I deployed to Azure

Bret Samblanet answers this well in a GitHub thread:
This is another subtlety about how that console/debug log works in the portal. It only displays log messages if it knows they come from this function — which means they match the category Function.{FunctionName}.Class. The vanilla ILogger we pass in uses this category automatically but anything you log with an external logger will not use this. We do this so that you don’t get flooded with background messages in this view — and unfortunately it filters out your own custom logger as well.
He proposes a workaround to fix this:
  • Use the ILogger that we pass into the function for your logging
  • Construct a logger yourself from the ILoggerFactory with the category generated from calling Microsoft.Azure.WebJobs.Logging.LogCategories.CreateFunctionUserCategory("{FunctionName}");. All this really does is create the category Function.{FunctionName}.{Class} (you can do this manually as well), which should then route correctly. Those logs will then route to the correct file to show up in streaming logs for {FunctionName}.
My take on it, just add the namespace(s) which contains ILogger<T> in your host.json

If you want to override it on the appsettings side, you can add the following key/value:
Key: AzureFunctionsJobHost__logging__LogLevel__{Namespace}.{Class}
Value: Information

Note: {Namespace} is the namespace of where your function lives and {Class} is the name of your class. They act as placeholders.

Remember that the logging facility is the same one that is being used in ASP.NET Core applications.

I’ve added a Startup class to my function to benefit from Dependency Injection, but I get the following error when I start my function: Method not foundMicrosoft.Azure.Functions.Extensions.DependencyInjection
.IFunctionsHostBuilder.get_Services()

This happens if you reference, in your function, a project that has a dependency to Microsoft.Extensions.DependencyInjection > 3.X. Install the 3.X dependency and it should be ok.

I want to use .NET 5 in my Azure function, is it possible?

Yes, follow the instructions here. Note that as of this post, the .NET 5 support is currently in preview. It also will use an out-of-process model that runs a .NET 5 worker process alongside the runtime. This is the same out-of-process model that all non-.NET Azure Functions languages have used successfully since Azure Functions V2. Read more about it here.

Where are my logs?

You can find your logs in 2 places. By default, Azure Functions log to application insights automatically, as long as you have set an instrumentation key using the app setting variable APPINSIGHTS_INSTRUMENTATIONKEY. The SDK is automatically added (do not add it in your startup file!).

It also logs to a file in the host, if you navigate to the Kudo, in the folder D:\home\LogFiles\Application\Functions\Host.

Also, each functions logs to its own file, under D:\home\LogFiles\Application\Functions\Function\<FunctionName>.

I want to leverage Azure Functions, but the language that I am comfortable with is not supported natively

Use custom handlers. Naveed Zaheer has a good video introduction about them on YouTube.

Can I put multiple functions into 1 project?

Yes, as long as your functions start points are decorated with the FunctionName attribute. The Azure Function Framework will discover them at runtime.

How can I test my function with load?

Do not use Azure as the infrastructure to load test your function scaling. If you do so, the traffic will be routed on the Microsoft backbone and never go out on the internet. Use tools that are outside of Azure to simulate load.

Tips

Do use the dependency injection pattern as much as possible

The pattern is great a great way to apply the D in SOLID.

Read the best practices

Read the Azure Functions best practices if you aren’t aware of them. It can help you avoid problems early on when you’re designing your functions.

Use the storage emulator to develop locally

You don’t need an actual physical storage account to start developing. Use Azurite Docker container (3.X for queues and blob, 2.X for table) or the Microsoft Azure Storage Emulator (5.10).

Understand the difference between the hosting plans

You can host your functions on different plans: Consumption, Premium, Dedicated, ASE, Kubernetes. Understand the different between all of them. You can find them here.

Do not use the Function keys as an authentication mechanism for HTTP triggered functions

As stated in the documentation, unless the HTTP access level on an HTTP triggered function is set to anonymous, requests must include an API access key in the request. While keys provide a default security mechanism, you may want to consider additional options to secure an HTTP endpoint in production.

Instead secure your application using OAUTH2, using an Azure AD application. More information here.

Front your Function with Azure API Management (APIM) for more advance features

You can use APIM to turn your functions into an API without having to manage, within your application, the authentication, caching, mTLS, custom domains and more! Be sure to check out all there features here!