Track non-HTTP requests with Application Insights - azure

As mentioned in this link, on .net core2.1 web.api application implemented the below code to track non-HTTP requests(i.e, redis calls) using Application Insights
private ReviewModel<T> GetCachedData<T>(string id)
{
try
{
var obj = default(RedisValue);
_retryPolicy.Execute(() =>
{
using (var getReviewsOperation = _telemetryClient.StartOperation<DependencyTelemetry>("RedisCall"))
{
obj = _database.StringGet(id); // external call to redis server
}
});
var review = string.IsNullOrEmpty(obj) || !obj.HasValue ?
default(ReviewModel<T>) : _serializer.Deserialize<ReviewModel<T>>(obj );
return review;
}
catch (Exception ex)
when (ex is RedisException)
{
//how to log the exception cases in dependency table of application insights log?
_log.LogError($"Redis exception occurred : ", {ex.Message});
return null;
}
}
The above code successfully log the redis call details on "dependency" table of application insights log. But how to log redis call details on "dependency" table of application insights log on exception scenarios with success property value as "false"?

You can use TrackDependency for this. TrackDependency is used to track the response times and success rates of calls to an external piece of code. The results appear in the dependency charts in the portal. The code snippet below needs to be added wherever a dependency call is made:
var success = false;
var startTime = DateTime.UtcNow;
var timer = System.Diagnostics.Stopwatch.StartNew();
try
{
success = dependency.Call();
}
catch(Exception ex)
{
success = false;
telemetry.TrackException(ex);
throw new Exception("Operation went wrong", ex);
}
finally
{
timer.Stop();
telemetry.TrackDependency("DependencyType", "myDependency", "myCall", startTime, timer.Elapsed, success);
}

Related

Distributed Tracing with Service Bus Triggered Function

According to the docs around distributed tracing for Servicebus, the Diagnostic-Id property should be used to store the WC3 traceparent.
When an Azure Function is triggered via a service bus message, I would expect this value to be used to initialize the tracecontext (so AppInsight logs would get tagged with the appropriate operation_Id).
I've even tried to copy it over to the tracecontext and it doesn't seem to work.
Is it not possible to maintain distributed tracing with Service Bus in Azure functions?
Update
You can kinda of get this to work by implementing the wrapped app insights context, however, calls to context.log will still have the original traceparent reference :(
export default async function contextPropagatingHttpTrigger(context, req) {
// overwrite with the proper traceparent from the incoming SB message.
const sbTraceParent = context.bindingData.applicationProperties['diagnostic-Id'];
if (sbTraceParent) {
context.traceContext.traceparent = sbTraceParent;
}
const correlationContext = appInsights.startOperation(context, req) as CorrelationContext;
// Wrap the Function runtime with correlationContext
return appInsights.wrapWithCorrelationContext(async () => {
const startTime = Date.now(); // Start trackRequest timer
try {
// operation_Id matches SB 'diagnostic-Id'
appInsights.defaultClient.trackTrace({
message: 'Correct Trace Context',
});
// operation_Id is the original function traceparent
context.log('Incorrect Trace Context');
return await trigger(context, req);
} catch (e) {
context.log.error(e);
throw e;
} finally {
// Track Request on completion
appInsights.defaultClient.flush();
}
}, correlationContext)();
}

Could not find method due to a type load error

I am building an app with Xamarin and Breez# use VS2017 for Mac, all goes fine till VS2017 notified me there are updates yesterday, then I updated it, also the package of Xamarin.forms from nugget.
then my app cannot work. and throw an exception when trying to call a method to get data.
{System.TypeLoadException: Could not find method due to a type load error
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder
`1[TResult].Start[TStateMachine] (TStateMachine& stateMachine) [0x0002c] in
/Library/Frameworks/Xamarin.iOS.framework/Versions/11.2.0.11
/src/mono/mcs/class/referencesource/mscorlib/system/runtime
/compilerservices/AsyncMethodBuilder.cs:471
the method:
public async Task<IEnumerable<Tenant>> GetAllItems()
{
try
{
// ignore the flurry of events when query results arrive
_ignoreEntityChanged = true;
var query = new EntityQuery<Tenant>().From(_resourceName);
var qr = await _em.ExecuteQuery(query);
_ignoreEntityChanged = false;
var result = qr.ToList();
return result;
}
catch (Exception e)
{
_ignoreEntityChanged = false;
return new List<Tenant>(); // return empty result instead
}
}
every time when I try to step into this method, the error come out. and then I tried comment all the lines but only return an empty list, I can step into the method and it works. the next step, I uncomment the line:
var query = new EntityQuery<Tenant>().From(_resourceName);
then I cannot step into the method, and the error throws.
I suppose the EntityQuery has something wrong with the newest vs2017 and Xamarin.Form, but no sure of that.

Waterline Error implementation in sails.js Services

As most of you know sails.js framework throws error as WLError object, I would like to make this consistent across my application. Any I error I would like to raise in my services should be a WLError object with my own error,status & summary. Has anyone done this?
var error = new Error(errorMsg);
return error;
I want something like below...
var error = new WLError({"status":"Fail", "error": "somethig", "summary": "OOPS!!"});
return error;
Thanks!
In one of my adapters I use waterline errors
// Adjust the relative path as needed
var WLError = require('../../sails/node_modules/waterline/lib/waterline/error/WLError');
processError: function(error) {
var formattedErr = new WLError();
formattedErr.code = 'E_MY_ERROR';
formattedErr.status = 400;
formattedErr.reason = error;
formattedErr.details = error;
return formattedErr;
},
Also I did just the opposite, converting waterline errors to look like other sails errors
in api/responses/badRequest.js I added:
// If the user-agent wants JSON, always respond with JSON
if (req.wantsJSON) {
try {
// This formats waterline errors like other sails errors
// See WLError.prototype.toJSON in waterline/error/WLError.js
var WLResponse = data.toJSON();
if(WLResponse.hasOwnProperty('error') && WLResponse.hasOwnProperty('summary')) {
return res.jsonx({
code: WLResponse.error,
message: WLResponse.summary
});
} else {
// Not a waterline error
throw 'NonWLError';
}
} catch (e) {
return res.jsonx(data);
}
}
I did this...
I added below in bootstrap.js
sails.WLError = require('../node_modules/sails/node_modules/waterline/lib/waterline/error/WLError.js');
Then in my code need not do a "require". Just below lines works.
error = new sails.WLError();
error.code = "404";
error.status = "Failure";
error.summary = "Invalid Request";
error.details = errorMsg;

How to do a basic remote procedure call (RPC) in Telegram?

I'm attempting to create a small program that can demonstrate some features of the Telegram API. I wish to be able to register and authenticate users via SMS. According to the user authorization guide, I need to invoke the auth.sendCode RPC. However, the codebase is inadequately documented and is proving hard to get into.
How do I send the auth.sendCode remote procedure call in Telegram? Please provide a code snippet which shows everything starting from set up and initialization.
Try Like this...
TLSentCode sentCode;
try {
sentCode = api.doRpcCallNonAuth(new TLRequestAuthSendCode(phone, 0, 5, "your app id", "en"));
} catch (RpcException e) {
if (e.getErrorCode() == 303) {
int destDC;
if (e.getErrorTag().startsWith("NETWORK_MIGRATE_")) {
destDC = Integer.parseInt(e.getErrorTag().substring("NETWORK_MIGRATE_".length()));
} else if (e.getErrorTag().startsWith("PHONE_MIGRATE_")) {
destDC = Integer.parseInt(e.getErrorTag().substring("PHONE_MIGRATE_".length()));
} else if (e.getErrorTag().startsWith("USER_MIGRATE_")) {
destDC = Integer.parseInt(e.getErrorTag().substring("USER_MIGRATE_".length()));
} else {
throw e;
}
api.switchToDc(destDC);
sentCode = api.doRpcCallNonAuth(new TLRequestAuthSendCode(phone, 0, 5, "youa app id", "en"));
} else {
throw e;
}
}

WCF client goes to faulted immediately

I have the following code for recreating a WCf client in a non opened state
if (client.State != CommunicationState.Opened)
{
client.Abort();
client = null;
Trace.WriteLine("Client object in non opened state. Recreating object");
client = new <WCFClient>("NetTcpBindingEndpoint", ConfigurationManager.AppSettings["ServiceEndPointAddress"]);
client.Open();
}
For some reason though, as soon as this routine returns and I try to call client.Somemethod(), I get an exception and when I catch it, I see the client in a faulted state. I don't understand how this happened so quickly.
Thanks for any help in advance.
Subbu
Can you show us when you're trying to call client.SomeMethod() ?
I don't see what you're trying to achieve with the client.Open() here..... that really doesn't make any sense at all - just call the method you want to call!
try
{
var client = new <WCFClient>("NetTcpBindingEndpoint", ConfigurationManager.AppSettings["ServiceEndPointAddress"]);
client.SomeMethod();
client.Close();
}
catch(FaultException<T> exc)
{
// handle it
client.Abort();
}
catch(CommunicationException exc)
{
// handle it
client.Abort();
}
catch(EndpointNotFoundException exc)
{
// handle it
client.Abort();
}
catch(TimeoutException exc)
{
// handle it
client.Abort();
}
and maybe add some try.....catch magic around it to make it safer.... but that's really all you need - no need to first .Open() the client.....

Resources