Yes this is possible.
Option 1: Using a Telemetry Initializer with the help of AsyncLocal:
public class CustomTelemetryInitializer : ITelemetryInitializer
{
public static AsyncLocal<string> MyValue = new AsyncLocal<string>();
public void Initialize(ITelemetry telemetry)
{
if (telemetry is ISupportProperties propertyItem)
{
propertyItem.Properties["myProp"] = MyValue.Value;
}
}
}
You can set the value of the AsyncLocal in the function like this:
[FunctionName("Function")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
HttpRequest req,
ILogger log)
{
var name = req.Query["name"];
CustomTelemetryInitializer.MyValue.Value = name;
log.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult($"Hello, {name}");
}
When you run the function you can see the information in the portal:

You can find the whole code at this repo
Now, addressing your comments. Yes you need something extra. The ITelemetryInitializer instance needs to be registered using dependency injection. That is done in the Startup class as outlined in the documentation:
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(FunctionApp.Startup))]
namespace FunctionApp
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<ITelemetryInitializer, CustomTelemetryInitializer>();
builder.Services.AddLogging();
}
}
}
Once registered the Application Insights SDK will use the CustomTelemetryInitializer.
Option 2
The other option does not involve any TelemetryInitializer, but you can only add properties to the generated RequestTelemetry that is added by the Azure Function App Insights integration. This is done by making using of the fact that the current TelemetryRequest is stored in the HttpContext:
[FunctionName("Function")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
HttpRequest req,
ILogger log)
{
var name = req.Query["name"];
CustomTelemetryInitializer.MyValue.Value = name;
log.LogInformation("C# HTTP trigger function processed a request.");
var telemetryItem = req.HttpContext.Features.Get<RequestTelemetry>();
telemetryItem.Properties["SetInFunc"] = name;
return new OkObjectResult($"Hello, {name}");
}
This will show up in the portal as well:

Is it a problem that the context is added only to the Request? It might, but be aware you can query all related telemetry and know what context is involved, for example:
union (traces), (requests), (dependencies), (customEvents), (exceptions)
| extend itemType = iif(itemType == 'availabilityResult',itemType,iif(itemType == 'customEvent',itemType,iif(itemType == 'dependency',itemType,iif(itemType == 'pageView',itemType,iif(itemType == 'request',itemType,iif(itemType == 'trace',itemType,iif(itemType == 'exception',itemType,"")))))))
| extend prop = customDimensions.SetInFunc
| where ((itemType == 'trace' or (itemType == 'request' or (itemType == 'pageView' or (itemType == 'customEvent' or (itemType == 'exception' or (itemType == 'dependency' or itemType == 'availabilityResult')))))))
| top 101 by timestamp desc
will show:

All telemetry that comes from the same invocation will have the same operation_Id.