Why does application insight log 400 bad request as successful request and not log exception - azure

i am encountering a problem i'm not familiar with.
So i'm trying to log exceptions from a test Azure Function but when i throw an exception and return a 400 bad request, application insight registers the log as a successful request.
As i understand it it is probably register the function's successful run but what i don't understand is how i then should log the exception.
So what i have done so far is this.
(I Will be referring to Application Insights as AI from here on out)
I started by created an AI-Resource.
Then i took the instrument key and applied it to the app settings of my function.
After that i installed the AI NUGET to my function bu creating a Projet.json file and then pasting something like this which installed the necessary assemblies and such.
{
"frameworks": {
"net46":{
"dependencies": {
"Microsoft.ApplicationInsights": "2.4.0"
}
}
}
}
after this i initialize the TelemetryClient in the function and try to log and exception in a catch:
Initiation:
string key = TelemetryConfiguration.Active.InstrumentationKey = System.Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", EnvironmentVariableTarget.Process);
TelemetryClient telemetry = new TelemetryClient() {
InstrumentationKey = key
};
Catch:
catch (Exception e)
{
Dictionary<string,string> properties = new Dictionary<string,string>();
properties.Add("Function Payload", data.ToString());
properties.Add("Function Exception", e.ToString());
telemetry.TrackException(e, properties);
return req.CreateResponse(HttpStatusCode.BadRequest, e);
}
Test running the function i get:
2018-03-07T14:24:36.171 [Info] Function started (Id=0292b455-314d-4c4c-872a-2b8137a72305)
2018-03-07T14:24:37.092 [Info] Function completed (Success, Id=0292b455-314d-4c4c-872a-2b8137a72305, Duration=931ms)
In Application insights i can can only see bad requests for StatusCode: 500
but 400 Bad requests gets logged as Successful requests.
And also the TrackException functionality doesn't log any of the custom properties...
So what am i missing?
MORE DETAILS ABOUT EXCEPTION LOGGING:

#Mikhail is right that we treat this as a success because the function is a success. We didn't want to use status codes to guess whether there was a successful operation or not, so we look for whether the function threw an exception.
Your exception isn't appearing in that screen because it hasn't been property correlated with this function execution. If you go to App Insights Analytics and query for that ExceptionTelemetry, you should see it.
In order to correlate it with a specific function, you'd need to set the OperationId, which is the same as the function's InvocationId. There is a sample that shows how to do this with Events, Metrics, and Dependencies, but doing it for Exceptions is the same (you can ignore the User.Id assignment): https://learn.microsoft.com/en-us/azure/azure-functions/functions-monitoring#custom-telemetry-in-c-functions
Update: From what you've shown of your function above, you may be able to get away with doing something like:
catch (Exception e)
{
log.Error("Function Payload " + data.ToString());
throw;
}
That would return a 500 (rather than a 400), and Functions would log the trace to Application Insights, and then log the exception as well as the Request failure. If you're not using your TelemetryClient anywhere else, you could remove that from your code.

The server (Azure Function) processed the request without errors, you returned a result from it, so from the point of view of Function App runtime the request was processed successfully. You can see that from the log too:
... Function completed (Success, ...
So, it makes sense that the Function App registers the call as success in Application Insights too. At least, that's how they chose to implement it.

the "for this operation" not showing exceptions implies that the exception that you sent does not have the same operationId as the azure function. operation
id is how application insights "links" related telemetry together.
your "exeption logging" screenshot is not an exception, but a request, so the custom properties logged on your exception won't be there.
if you want your azure function to fail, and show as a failed request, and log an exception, why are you catching the exception and logging it yourself? doesn't catching the exception then cause the azure function to succeed? why not just let the exception trickle out and let the function runtime do that part for you? (doesn't it?)

Related

Error reporting in Azure Functions vs App Insights

We call REST based APIs hosted by Azure Functions and fail to implement a consistent error handling supporting App Insights and wonder what can be done about it:
If we don't handle exceptions of the function, then App Insights
reports a 'failure', but the service returns only the the error code to the caller, but no error content:
Hence, the client receives a 500 and thats it.
If we handle the exception and log it (to AppInsights) then App Insights stops reporting a 'failure' hence monitoring on function level is broken. We can query for the exception, but they are out-of-context (i.e. we can see the exception by a custom query only) and we don't know which function is impacted actually.
How to marry up the two needs:
Let the function fail so that AppInsights reports the failure (and monitor can alert)
Return a bit more meaningful error message to the caller than 500.
Example on how it looks in AppInsights:
Exception is visible on the Exceptions tab, but the underlying operation has not failed
UPDATE:
According to Microsoft, App Insight Failures are exclusive to unhandled exceptions. Still, open whether there is a way to at least pass-through an error message.
If don't handle exceptions of the function, then App Insights reports a 'failure', returns the error code, but no error content. Hence, the client receives a 500 and thats it.
App Insights doesn't return anything, so what do you mean with returns the error code?
If we handle the exception, LOG it (to AppInsights), return simple error message in code 500, then App Insights doesn't log this as 'failure' hence monitoring is not possible.
Can you show how you do the logging? Because as soon as you log an exception using App Insights you should see it under failures.
This should work:
try
{
...
}
catch(Exception e)
{
logger.LogError(e, e.Message);
return httpRequest.CreateResponse(HttpStatusCode.InternalServerError, e.Message);
}

Firebase Cloud Functions fail with no logs, just "Error: function terminated. Recommended action: inspect logs for termination reason"

I infrequently see this error in my Firebase Cloud Functions logs:
"Error: function terminated. Recommended action: inspect logs for termination reason. Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging Request rejected.".
I looked through the logs around the time this error occurred and don't see any other information, just a few other successful executions of the same cloud function. The same function is executing successfully thousands of times a day, but then once every day or few hours this is shown. My entire cloud function body is wrapped in a try/catch and I've seen logical errors reported properly from the error log in the catch code so I don't know how this uncaught error is happening or how to get any more information about it. Does anyone know how this error could be happening? This is a sanitized version of the function throwing this weird error:
exports.onUserDocUpdate = functions.firestore
.document('user/{userId}/{collectionId}/{docId}')
.onWrite(handleDocumentWrite);
async function handleDocumentWrite(change, context) {
try {
// Function logic here
} catch (error) {
functions.logger.error(`firestoreTriggers.handleDocumentWrite failed with error:`, error);
}
}

How to define a request timeout on asp.net core MVC on linux

Given:
ASP.Net Core MVC application, deployed in docker containers on linux.
Nginx reverse proxy + load balancer
When the ASP.Net core container gets stuck (after a timeout on nginx), it calls a different instance of the application. At that point, the application should cancel the processing in order to not perform data manipulation operations twice. This works great with a global:
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
using (context.HttpContext.RequestAborted.Register(() => context.HttpContext.RequestAborted.ThrowIfCancellationRequested()))
{
await base.OnActionExecutionAsync(context, next);
}
}
The problem here is, that nginx might cancel the request, right after the transaction in the controller and underlying services completed. Which means, the request was successful, but just slightly too long, and nginx will try a second time anyway. In order to solve this, we wanted to set a second timeout which would be few seconds shorter than nginx timeout. The only solution I've found is this:
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var timeout = new CancellationTokenSource();
timeout.CancelAfter(ActionTimeout);
using (timeout.Token.Register(() => timeout.Token.ThrowIfCancellationRequested()))
using (context.HttpContext.RequestAborted.Register(() => context.HttpContext.RequestAborted.ThrowIfCancellationRequested()))
{
await base.OnActionExecutionAsync(context, next);
}
}
But this is throwing the following exception:
System.AggregateException was unhandled
Message: An unhandled exception of type 'System.AggregateException' occurred in System.Private.CoreLib.ni.dll
Additional information: One or more errors occurred.
And afterwards the application is crashing. Putting try/catch anywhere around of course also doesn't help and adding a global exception filter to the middleware doesn't help either.
What is the best way to cancel Requests on linux after a custom timout, without depending on a reverse proxy to do it?
Update - details on exceptions:
At first I see the following exception:
System.OperationCanceledException was unhandled by user code
HResult=-2146233029
Message=The operation was canceled.
Source=System.Private.CoreLib
StackTrace:
at System.Threading.CancellationToken.ThrowOperationCanceledException()
at ...BaseController.<>c__DisplayClass4_0.<OnActionExecutionAsync>b__0() in ...\Controllers\BaseController.cs:line 28
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
InnerException:
Which is fine, that's the cancellation token throwing the exception. But the second one, the one which I can't catch, not sure how I could see the details there, I just see the following screen:
And regardless of what I tried, the process always stopped afterwards (even if I press continue execution)

Azure IoTHub throwing exceptions I cannot catch

I have a Xamarin app using the Microsoft.Azure.Devices.Client.DeviceClient to listen for messages from the Azure IoT hub. Occasionally I get errors thrown that I cannot catch, and deal with. One such exception is:
Microsoft.Azure.Devices.Client.Exceptions.UnauthorizedException
This exception is just an example of an exception I am getting, and one that I can reliably recreate by changing system time. Other IoTHubExceptions are sporadic and difficult to recreate and hence the need to try and catch the exception.
Can anyone tell me how I can catch these IoT hub based errors? The code is:
try
{
await _deviceClientInbound.OpenAsync();
// execution never gets passed this line and the exception is eventually thrown, having reached this point
Message receivedMessage = await _deviceClientInbound.ReceiveAsync();
if (receivedMessage == null) continue;
await _deviceClientInbound.CompleteAsync(receivedMessage);
}
catch (Exception e)
{
// Exception is never caught in here ...
// How can I catch the IoTHubException based exceptions
}
If you are getting unauthorized exception . Then please check your iot hub connection string used in device client to confirm that the shared access polity used with connection string have all the privileges or not, that is needed at your end.
I believe this has to do with the various refactorings done for the supported platforms and you will likely have to catch all exceptions, process the ones you want, and rethrow ones you don't. Depending on platform you might be able to include:
using Microsoft.Azure.Devices.Client.Exceptions;
The sources are here if you feel like spelunking:
https://github.com/Azure/azure-iot-sdk-csharp/search?utf8=%E2%9C%93&q=using+Microsoft.Azure.Devices.Client.Exceptions

NodeJS Azure Functions used as a Messenger Bot return an mscorlib error

I'm trying to use Azure Functions as a Messenger bot server using a Generic Webhook. The problem I'm running into is that even running this simple code (most of it is commented out to try & figure out the issue) results in an error (below the code):
module.exports = function (context, data) {
context.log('Webhook was triggered!');
context.res = {
status: 403,
body: ''
}
context.done();
}
Function completed (Failure,
Id=fb0f2178-8b98-4163-a5ae-7ab68eff47cd)
Exception while executing function: Functions.StriverMessenger.
mscorlib: The given key was not present in the dictionary.
Why is this error occurring and how do I get this to work? If I fake out the querystring entries in the run mode inside Azure, the function appears to work as coded. The error occurs when trying to send a Verify request to the Azure Function from Facebook Developer, specifically in Messenger's Webhook setup.
This happens when an empty (or non-json) body is sent to a Function with type WebHook. The handling is poor, and we are improving it per https://github.com/Azure/azure-webjobs-sdk-script/issues/849. This should be deployed within a week and you can then verify.

Resources