azure-functions-host
azure-functions-host copied to clipboard
Explicitly handle and log startup errors
For example, if an invalid storage connection string is set in an App Setting, we will throw an exception very early in the startup pipeline (specifically in BlobStorageSecretsRepository). This will go unhandled and cause the process to exit, leaving us with no trace of the error.
We need to catch and log this properly.
Flagging this as a supportability issue.
Need to flush out the details and perhaps break this up before moving forward with implementation.
This needs clarification and better design. Moving back to triaged
One scenario we need to handle better: Exceptions being thrown from Startup.cs. Today App Insights isn't initialized so these logs can just disappear and customers can't tell that they have an exception.
Possible solution:
If we catch an exception in a startup, we:
- Make sure the exception is returned as part of the Errors that the portal sees when pinging for host status. I'm fairly certain this is true today but we need to double-check.
- Explicitly check the environment for App Insights keys. If they exist, create a one-off TelemetryClient so we can log this error to the customer. This would go outside of our normal App Insights configuration (since startup was canceled by the exception), but it would give better insight to customers when they hit this. Today they get nothing.
One example: https://github.com/Azure/azure-functions-host/issues/6278#issuecomment-653049243
Is there currently a way to surface exception information in the startup of a v3 app? For example, when my startup consists of:
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
throw new NotImplementedException("Does this end up anywhere?");
}
}
And I have an APPINSIGHTS_INSTRUMENTATIONKEY
defined in Application Settings with a host.json
containing:
"logging": {
"fileLoggingMode": "always",
"logLevel": {
"default": "Trace"
},
"console": {
"isEnabled": "true"
}
}
I cannot find the exception message anywhere. Should I expect to? Is it possible to?
One thing you can always do if you're using App Insights is try/catch around your Startup and then log the exception directly to App Insights yourself. This is effectively what I'm going to propose we do in the host. The current issue is that when we're calling your Startup class, we have not yet constructed the App Insights services (since we're still in DI initialization) so the exception isn't logged automatically.
I'm thinking something like:
try
{
// do all your DI stuff
}
catch (Exception ex)
{
var config = new TelemetryConfiguration(Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY"));
var client = new TelemetryClient(config);
client.TrackException(ex);
client.Flush();
throw;
}
Ofc we can write all the "wiring" ourselfves, the question is - should we?
Azure functions states the serverless aproach - and logging to attached AppInsights exceptions thrown in Startup
class should be somthing that host does.
Hi All,
Anything wrong with this approach:
define a private member in startup class:
private ILogger Logger()
{
var loggerFactory = LoggerFactory.Create(startupLogbuilder =>
{
startupLogbuilder.AddConsole();
startupLogbuilder.AddDebug();
});
return loggerFactory.CreateLogger<Startup>();
}
then I can reference it within Configure and ConfigureAppConfiguration and any other override like so:
this.Logger().LogError(errorMessage);
Does anyone see any issues with this? I've tested it and works consistently.
I am running a Python function app and have the same issue. No access to start-up logs. Sometimes, for example, due to a missing environment variable, the function won't properly start and all I get is...
"No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.)."
...while the error is actually totally unrelated to public classes or methods or binding extensions.
Any plans to make this happen anytime soon?