Reputation: 364
I have created a Blob Trigger Azure Function, and I wanted to be able to create mail alerts when I have an exception, and among the information sent in the mail alert, there should be the name of the file the exception occurred on.
I noticed that exceptions are automatically logged in Azure, but I found no way of customizing the message or the information sent along the exception. So I decided to inject a telemetry service in my Function App, and add the file name as a custom property, as you can see in the code below :
public class Function1
{
private readonly IGremlinService _gremlinService;
private readonly TelemetryClient _telemetryClient;
public Function1(IGremlinService gremlinService, TelemetryConfiguration telemetryConfiguration)
{
this._gremlinService = gremlinService;
this._telemetryClient = new TelemetryClient(telemetryConfiguration);
}
[FunctionName(nameof(Function1))]
public async Task Run([BlobTrigger("files/{directory}/{name}.00.pdf", Connection = "AzureWebJobsStorage")] Stream myBlob, string name, ILogger logger)
{
try
{
//some code not related to the issue
}
catch (Exception e)
{
var properties = new Dictionary<string, string>
{{"Filename", name}};
_telemetryClient.TrackException(e, properties);
if (e is ResponseException)
{
ResponseException re = (ResponseException) e;
var statusCode = (long) re.StatusAttributes["x-ms-status-code"];
_telemetryClient.TrackTrace("Error on file " + name + ". Status code: " + statusCode + " " + re.StackTrace, SeverityLevel.Error, properties);
}
else
{
_telemetryClient.TrackTrace("Error on file " + name, SeverityLevel.Error, properties);
}
throw;
}
}
}
}
But I still cannot customize the message to provide the user with additional information. I know I can send alerts on trace messages instead, and send customized messages this way, and this is currently what I'm doing, but I would find it cleaner to send alert on exceptions.
My second issue is that my exceptions are still logged automatically on top of being logged by the telemetry service, and for some reason I can't understand, they are logged twice, as you can see in the screenshot below from Application Insights :
Is there a way I can turn off the automatic logging of exceptions ? Or is there a way to customize these exceptions messages that I'm not aware of, instead of using the telemetry service ?
Upvotes: 0
Views: 1720
Reputation: 10839
I believe, the 3 exceptions are being logged due to following reasons:
IGremlinService
throwing exception which is being logged._telemetryClient.TrackException(e, properties);
throw
is invoked.Now coming to your question
I found no way of customizing the message or the information sent along the exception
I would suggest you to use ILogger
for LogException and use BeginScope
(read here) to define the scope properties which will be logged as Custom Properties in application insights for all the logs which are invoked during the lifetime of created scope.
Using the ILogger
object, your code will be simplified as follows and all traces and exceptions inside scope will have FileName
as custom property in application insights.
[FunctionName(nameof(Function1))]
public async Task Run([BlobTrigger("files/{directory}/{name}.00.pdf", Connection = "AzureWebJobsStorage")] Stream myBlob, string name, ILogger logger)
{
using (logger.BeginScope(new Dictionary<string, object>()
{
["FileName"] = name,
}))
{
try
{
//some code not related to the issue
}
catch (Exception e)
{
logger.LogError(e, "Error occurred with {StatusCode}", (long) re.StatusAttributes["x-ms-status-code"]);
throw;
}
}
}
Following summarizes the definition of statement logger.LogException(e, "Error occurred with {StatusCode}", (long) re.StatusAttributes["x-ms-status-code"]);
e
represents the actual exception which occurred.{StatusCode}
will be logged the StatusCode as Custom Property in application insights for the logged exception so you don't need to create any dictionary.FileName
will be logged as Custom property as defined by Scope.You can view a sample implementation at here.
Upvotes: 1