Plinth.AzureFunction 1.7.0

Prefix Reserved
dotnet add package Plinth.AzureFunction --version 1.7.0                
NuGet\Install-Package Plinth.AzureFunction -Version 1.7.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Plinth.AzureFunction" Version="1.7.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Plinth.AzureFunction --version 1.7.0                
#r "nuget: Plinth.AzureFunction, 1.7.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Plinth.AzureFunction as a Cake Addin
#addin nuget:?package=Plinth.AzureFunction&version=1.7.0

// Install Plinth.AzureFunction as a Cake Tool
#tool nuget:?package=Plinth.AzureFunction&version=1.7.0                

README

Plinth.AzureFunction

Utility framework and enhancements for Azure Function projects

Adds enhancements and facilities for Azure Function projects with HTTP triggers including logging using the Plinth framework and Application Insights integration. This parallels the Plinth.AspNetCore package.

Function Setup

1. Logging Settings

  • In host.json or a custom loaded funcsettings.json, this configuration must be supplied.
    👉 It is important to set the default level for both the LogLevel and the ApplicationInsights blocks. 👉 Log levels set for application insights are the most important. The top level LogLevel block only controls local console logging
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug"
    },
    "ApplicationInsights": {
      "LogLevel": {
        "Default": "Debug",
        "Microsoft": "Warning",
        "System": "Warning"
      }
    }
  }
}

2. Loading custom config

In Program.cs, if you choose to load a custom funcsettings.json, here is an example of doing that. This should be done first before any other host configuration.

var host = new HostBuilder()
    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        var context = hostingContext.HostingEnvironment;
        config
            .AddJsonFile(Path.Combine(context.ContentRootPath, "funcsettings.json"), optional: false, reloadOnChange: false)
            .AddJsonFile(Path.Combine(context.ContentRootPath, $"funcsettings.{context.EnvironmentName}.json"), optional: true, reloadOnChange: false)
            .AddEnvironmentVariables();
    })

3. Enable Plinth service logging

Next, this enables middleware to provide service logging and exception handling for http triggered functions

    .ConfigureFunctionsWorkerDefaults((config, builder) =>
    {
        builder.UsePlinthServiceLogging();
    })

You may pass an Action to this call to configure some logging parameters

  • MaxRequestBody - maximum amount of the request body to be logged (default 25000)
  • MaxResponseBody - maximum amount of the response body to be logged (default 25000)
  • RequestProcessors - a mapping of api prefixes to callbacks for processing the request body to be logged before it is logged, for sanitation or filtering.
  • ResponseProcessors - a mapping of api prefixes to callbacks for processing the response body to be logged before it is logged, for sanitation or filtering.

4. Enabling Application Insights

Next, this enables application insights integration with the function runtime and configures ILogger to send traces

    .ConfigureServices((hostingContext, services) =>
    {
        services.AddPlinthAppInsightsTelemetry(hostingContext.Configuration);
    })

👉 The connection string for Application Insights will be retrieved from the configuration variable "APPLICATIONINSIGHTS_CONNECTION_STRING"

👉 The Cloud Role Name for Application Insights will be retrieved from the configuration variable "WEBSITE_CLOUD_ROLENAME"

When running locally, these can be set in local.settings.json. They should be supplied in the Azure Portal when running on Azure.

5. ILogger configuration

Next, this ensures that your settings from host.json or a custom loaded funcsettings.json are applied to ILogger

    .ConfigureLogging((hostingContext, logging) =>
    {
        logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
    })

6. Attaching Plinth static loggers to Application Insights

Once your IHost is built, in order to include all logging done by Plinth components (such as Plinth.HttpApiClient), you must add Plinth logging to the host. This can be done by calling .AddPlinthLogging() before running the host.

    await host
        .AddPlinthLogging()
        .RunAsync();

7. Generate OpenAPI Spec (Optional)

Microsoft provides a nuget package Microsoft.Azure.Functions.Worker.Extensions.OpenApi for generating OpenAPI and Swagger documentation based on your Http Trigger functions. If you include this package in your project, you'll need to document your functions like below

[Function("Function1")]
[OpenApiOperation(operationId: "function1", tags: new[] { "Functions" }, Summary = "Function 1", Description = "This is the first Function")]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(ResponseModel), Summary = "The response", Description = "This returns the response")]
public async Task<ActionResult> RunFunction1([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)

👉 NOTE: Do not name your functions any of these names, as they conflict with the functions generated by the Microsoft package, and the logging in Plinth will not log them.

  • RenderSwaggerDocument
  • RenderSwaggerUI
  • RenderOpenApiDocument
  • RenderOAuth2Redirect

To configure, follow this pattern. Note that if using the dotnet-isolated model, you will have to add your endpoint manually as shown below.

s.AddSingleton<IOpenApiConfigurationOptions>(_ =>
{
    var options = new OpenApiConfigurationOptions()
    {
        Info = new OpenApiInfo()
        {
            Version = "1.0.0",
            Title = "Swagger Test",
            Description = "This is a test",
        },
        // these two lines are needed if using dotnet-isolated
        Servers = [ new OpenApiServer() { Url = "http://localhost:7296/api", Description = "Local Dev" } ],
        ExcludeRequestingHost = true,
        OpenApiVersion = OpenApiVersionType.V3,
    };

    return options;
});

Complete Setup Example

    var host = new HostBuilder()
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            var context = hostingContext.HostingEnvironment;
            config
                .AddJsonFile(Path.Combine(context.ContentRootPath, "funcsettings.json"), optional: false, reloadOnChange: false)
                .AddJsonFile(Path.Combine(context.ContentRootPath, $"funcsettings.{context.EnvironmentName}.json"), optional: true, reloadOnChange: false)
                .AddEnvironmentVariables();
        })
        .ConfigureFunctionsWorkerDefaults((config, builder) =>
        {
            builder.UsePlinthServiceLogging();
        })
        .ConfigureServices((hostingContext, services) =>
        {
            services.AddPlinthAppInsightsTelemetry(hostingContext.Configuration);
            // OpenAPI package config here if desired 
        })
        .ConfigureLogging((hostingContext, logging) =>
        {
            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
        })
        .Build();

    await host
        .AddPlinthLogging()
        .RunAsync();

Function Example

[Function("MyFunction")]
public async Task<ActionResult> MyFunction([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req)
{
    var data = await SomeDataThing.GetDataAsync();
    return new OkObjectResult(data);
}
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.7.0 71 11/12/2024
1.6.6 75 11/8/2024
1.6.5 98 8/31/2024
1.6.4 72 8/2/2024
1.6.3 118 5/15/2024
1.6.2 143 2/16/2024
1.6.1 196 1/5/2024
1.6.0 177 11/30/2023
1.5.10-b186.aca976b4 80 11/30/2023
1.5.9 135 11/29/2023
1.5.9-b174.64153841 157 11/23/2023
1.5.9-b172.dfc6e7bd 78 11/17/2023
1.5.9-b171.4e2b92e2 125 11/4/2023

net9.0 support