Azure Function silently fails to start if dependency is misconfigured - azure

When developing locally on my machine, if I do not start the Azure Cosmos Emulator, my Function fails to start correctly. There are no errors in the console output, however if I try to call a HttpTrigger function the TCP connection is refused. No exceptions are trapped by the Visual Studio debugger, and no errors are shown in the console.
How can I get an error to be logged to console?
The only difference I've seen is in the console output is the following output not showing when Cosmos is switched off:
[2020-10-19T19:20:29.487] Host started (2444ms)
[2020-10-19T19:20:29.490] Job host started
Hosting environment: Production
Content root path: C:\Code\MyApp.Functions\bin\Debug\netcoreapp3.1
Now listening on: http://0.0.0.0:7071
Application started. Press Ctrl+C to shut down.
[2020-10-19T19:20:34.554] Host lock lease acquired by instance ID '000000000000000000000000C51E9459'.
I'm not seeing much when using enhanced logging either, as configured below:
{
"version": "2.0",
"logging": {
"logLevel": {
"Host.Triggers.Warmup": "Trace",
"Host.General": "Trace",
"Host": "Trace",
"Function": "Trace",
"MyApp": "Trace",
"default": "Trace"
}
}
}
Below is a diff of the logs after normalizing meaningless differences, including timestamps, guids and execution-times.

Related

Cannot get rid of logs in Azure Function for Web Storage

I have tried so many things to do this and nothing works, but when I run my Azure function I get all these logs its far too much noise
What is the correct way to get rid of them once and for all?
I have this in my host.json
"logging": {
"logLevel": {
"default": "Information",
"Microsoft": "Warning",
"System": "Warning",
"Host": "Error",
"Function": "Error",
"Host.Aggregator": "Information"
},
"Serilog": {
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:HH:mm:ss} {Level} | {RequestId} - {Message}{NewLine}{Exception}"
}
}
]
}
},
and this is in my localsettings.json
"logging": {
"logLevel": {
"Microsoft.Azure.WebJobs.Script.WebHost.Middleware.SystemTraceMiddleware": "Error",
"Worker.rpcWorkerProcess": "Error"
}
},
You have to modify the host.json for configuring minimum level of logs either locally or in Azure Cloud.
I can see you have defined the log values as Information, Warning to the Log Level attributes where information gives the general flow of the Application Execution from Start to End like Host level flow, Application-Level Flow logs.
Host.Aggregator generates more than the trace level metrics if assigned with the value of Information.
You have to remove/disable the unnecessary modules which are not required for logs or keep that modules log level to None if not required for the current situation and change the log level to minimum which also reduces your Logs Consumption if deployed to Azure Cloud.
I found a similar SO Issue 70690850 that shows the minimum log levels should be modified in the host.json which reduces the number of logs both locally and given the techniques of Application Insights and this MS Doc for more information on Log Levels Configuration.

Azure Function App Cosmos DB trigger connection drop

I am using a Function app with cosmos DB trigger, when running locally, the behavior is very strange as I stop receiving events randomly, like if the connection to the Lease collection drops. I am getting an error message that says a read operation fails to Blob storage, but not sure if this is related. Here's the error:
There was an error performing a read operation on the Blob Storage Secret Repository.
Please ensure the 'AzureWebJobsStorage' connection string is valid
I am running the function app with this code: func host start --cors * --verbose
And here's the CosmosDBOptions object I can see in the console:
[2021-02-09T16:17:58.305Z] CosmosDBOptions
[2021-02-09T16:17:58.307Z] {
[2021-02-09T16:17:58.307Z] "ConnectionMode": null,
[2021-02-09T16:17:58.308Z] "Protocol": null,
[2021-02-09T16:17:58.309Z] "LeaseOptions": {
[2021-02-09T16:17:58.310Z] "CheckpointFrequency": {
[2021-02-09T16:17:58.310Z] "ExplicitCheckpoint": false,
[2021-02-09T16:17:58.311Z] "ProcessedDocumentCount": null,
[2021-02-09T16:17:58.311Z] "TimeInterval": null
[2021-02-09T16:17:58.312Z] },
[2021-02-09T16:17:58.313Z] "FeedPollDelay": "00:00:05",
[2021-02-09T16:17:58.313Z] "IsAutoCheckpointEnabled": true,
[2021-02-09T16:17:58.314Z] "LeaseAcquireInterval": "00:00:13",
[2021-02-09T16:17:58.314Z] "LeaseExpirationInterval": "00:01:00",
[2021-02-09T16:17:58.315Z] "LeasePrefix": null,
[2021-02-09T16:17:58.316Z] "LeaseRenewInterval": "00:00:17"
[2021-02-09T16:17:58.316Z] }
[2021-02-09T16:17:58.323Z] }
and my host.json file:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}
Finally, that issue started since I added a shared folder, not sure if it's related but it's really annoying, deleting leases collection solves temporary the problem but It costs a lot of time and all the other running functions break because I clean all the collection.
TLDR; Using the CosmosDB emulator for local development solves this issue, as you won't have two functions pointing to the same lease collection.
There are two important points:
If you have one Azure Function deployed on Azure and one running locally in your machine with the same lease configuration listening for changes in the same monitored collection then these will behave as multiple instances of the same deployment and changes will be delivered to one or the other and you might experience "event loss" on the one running in Azure. This is documented in https://learn.microsoft.com/en-us/azure/cosmos-db/troubleshoot-changefeed-functions#some-changes-are-missing-in-my-trigger. If you want to have 2 independent Functions listening for changes in the same monitored collection, sharing the same lease collection, you need to use the LeaseCollectionPrefix configuration https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-create-multiple-cosmos-db-triggers
The error you are seeing locally is potentially related to either not having the Azure Storage emulator running or not configuring the AzureWebJobsStorage configuration locally to use it. Azure Functions runtime (regardless of the Cosmos DB Trigger) requires a storage account. You can use UseDevelopmentStorage=true for the local storage emulator.

docker-compose to run Azure Functions locally

We are building a system that some customers will run in Azure and some will run in Docker on their own hardware via docker-compose. We are basing our Microservices on Azure Functions.
I have written a docker-compose file to setup the various images (web site, Azure Functions and RabbitMQ)
The docker-compose looks like this (Simplified):
version: "3"
services:
abmicroservice:
build:
context: ./AbMicroservice
depends_on:
- rabbitmq
When the docker-compose starts up, I get this error when the Azure Function project is started:
abmicroservice_1 | 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.).
But when I run the same Azure Function using the func.exe tool or Visual Studio Debug, it runs fine.
I am guessing that the issue is my various host.json and the like and settings in docker-compose.yml.
My Function is just a hello-world test that runs great when Visual Studio 2019 runs it:
public static class TriggerFunction
{
[FunctionName("TriggerFunction")]
public static void Run(
[RabbitMQTrigger("hello")] string message,
ILogger log)
{
log.LogInformation($"************* Message received from RabbitMQ trigger: {message}");
}
}
Few thing that could could solve it:
Check the connection strings
Make sure the connection strings are given as env variables to your docker (look into function.json and the value of "connection" should be the name of env variable with connection string)
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "msg",
"type": "serviceBusTrigger",
"direction": "in",
"queueName": "nameOfTheQue",
"connection": "connectionVariable"
}
]
}
This means your docker should have a env variable "connectionVariable" with the connection string (to service bus in this example)

Starting Azure Service Bus Trigger Function throws InvalidOperationException for "Host not yet started"

I have a v.2 Service Bus Trigger function which, when I attempt to start, throws the following exception:
System.InvalidOperationException
HResult=0x80131509
Message=The host has not yet started.
Source=Microsoft.Azure.WebJobs.Host
StackTrace:
at Microsoft.Azure.WebJobs.JobHost.StopAsync() in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\JobHost.cs:line 121
at Microsoft.Azure.WebJobs.Hosting.JobHostService.StopAsync(CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\JobHostService.cs:line 32
at Microsoft.Extensions.Hosting.Internal.Host.<StopAsync>d__10.MoveNext()
I've searched around but cannot find anyone with a similar issue (and fix). I'm running VS 15.8.7 with all extensions and packages updated.
Here's what my function looks like:
[FunctionName("ServiceBusListenerFunction")]
public static void Run([ServiceBusTrigger("myTopic", "MySubscription", Connection = "MyConnection")]string mySbMsg, ILogger log)
{
log.LogInformation($"C# ServiceBus topic trigger function processed message: {mySbMsg}");
}
And here's my local.settings.json:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"MyConnection": "UseDevelopmentStorage=true",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"AzureWebJobsDashboard": "UseDevelopmentStorage=true"
},
"Host": {
"LocalHttpPort": 7077
}
}
I also tried doing the following in launchSettings.json, but it didn't help:
{
"profiles": {
"MyProject": {
"commandName": "Project",
"executablePath": "C:\\Users\\[myUserName\\AppData\\Roaming\\npm\\node_modules\\azure-functions-core-tools\\bin\\func.dll",
"commandLineArgs": "host start --port 7077"
}
}
}
I have Service Bus Explorer running and have created the above-named topic and subscription on it. The project in which the functions are located is built against .NET Standard 2.0.
Please let me know if you have any suggestions or need additional information.
EDIT: I grabbed the red exception text that appears briefly in the console window before it closes (which happens right before I get the above exception), and it reads:
Host initialized
A host error has occurred
System.Private.Uri: Value cannot be null
Parameter name: uriString
Stopping job host
Searching on this, I found this, but it doesn't seem as though I should have to change the attribute to get this working.
Thanks in advance for any help.
Problem is caused by this setting
"MyConnection": "UseDevelopmentStorage=true"
UseDevelopmentStorage=true represents Storage emulator connection string, for a Service Bus trigger, use Service Bus connection string(same one used in Service Bus Explorer or find it in Azure portal).
Some improvements:
In local.settings.json, LocalHttpPort somehow doesn't work in VS, you can remove it as commandLineArgs in launchSettings.json works as expected.
AzureWebJobsDashboard is not required now, so it can be deleted without special purpose.
In launchSettings.json, remove executablePath which is invalid as well. Usually we don't need this setting as VS use latest CLI by default.
One of the ways, I sorted the issue by removing the connection string from the [ServiceBusTrigger] and inserting it through local.settings.json.
in the function file.
[ServiceBusTrigger("Your-Topics-Name", "SubscriptionName",Connection = "MyServiceBus")]
Inside the local.settings.json.
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"AzureWebJobsMyServiceBus": "your connection string",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}
note: connection string name start with the "AzureWebJobs" so you can put the remaining as the name.
In my case, it was just to update the version of Microsoft.Azure.WebJobs.Extensions.ServiceBus from 4.7.x to 5.x.x, and that's it :-)
I had to install Azure Functions Core Tools. It includes a version of the same runtime that powers Azure Functions runtime that you can run on your local development computer. It also provides commands to create functions, connect to Azure, and deploy function projects.
In my case the problem was the Platform target, change it to Any CPU instead of x86
I solve the issue by updating all the packages. I had sold packages that were incompatible with a recent package I installed.

Docker exit status 1 for Node app on AWS

I'm hosting a beta app on AWS using Express.js, Node, mongoose and docker. Daily active users < 10, mainly friends of mine for testing. The app is down almost everyday for some reason. Initially I thought it was AWS's issue, so I stopped my app, changed it from free tier to t2.medium and started it again.
It didn't resolve the issue, I checked docker log for the container. It was not caused by OOMKilled.
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 1,
"Error": "",
"StartedAt": "2017-03-22T00:51:59.234643501Z",
"FinishedAt": "2017-03-22T07:21:41.351927073Z"
},
"Config": {
...
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
...
}
I could set docker to always restart, but I want to figure out what's the root cause of it. Any suggestions?
That happens to everyone. Lots of things can kill Express applications, like weird HTTP requests. The Docker log should show the exception. Add an uncaughtException handler to log the issue.
process.on('uncaughtException', (e) => {
console.error(e); // try console.log if that doesn't work
process.exit(10);
});
If you can't find an error in the Docker log, then instead of logging to the console, maybe you can log to a file (make sure it is in a volume that stays between Docker runs though).
People don't like admitting this but many applications actually just log the exception and eat it and keep going in the uncaughtException handler without exiting. Because things like broken requests or other stuff that doesn't matter often kill the server you can usually get away with this. But then once in a while you will get burned by something strange happening to the server state that it can't recover from and you will have no idea because you just ate the exception.
You may be able to have it autorestart the app https://docs.docker.com/docker-cloud/apps/autorestart/ which might be a good solution.
Otherwise look into an example of using pm2 along with Docker if possible, pm2 will handle restarting for you.

Resources