Sten Petrov
Sten Petrov

Reputation: 11040

Service Fabric QoS logging

I have a microservice application where I want to record Quality of Service (QoS) logs - one log line per service call, whatever the service call is. I also want to have detailed calls per call that have some ID that's the same in the QoS logs and the detailed logs.

I don't want to change the signature of service methods to take more parameters. Rather I'd like to change the remoting stack somehow, so all current and future service calls are covered.

I followed this answer and wrote an IServiceRemotingClient that uses AsyncLocal to store context info. This does not let me inspect the response type and log exception stack traces for example.

My question is - is there a way to wrap SF's call into my own method closer to my service method, where I can log exceptions and results, rather than at the remoting level, where everything is already packaged as a black box

public class LoggingServiceRemotingClient: IServiceRemotingClient
{
   IServiceRemotingClient standardClient;
   ...
   public async Task<IServiceRemotingResponseMessage> RequestResponseAsync(IServiceRemotingRequestMessage requestMessage)
   {
     var callId = Guid.NewGuid();
     try{
       SetCallIdInAsyncLocal(callId); // trimmed down pseudo code
       var response = await this.standardClient.RequestResponseAsync(requestMessage);
       Log.Ok(callId); // trimmed down pseudo code
     } catch (Exception x){
       // this will never be hit because the response body was already created with an exception serialized in it.
       // how do I catch such exceptions across all calls?
       // also some calls a due to client errors, others are internal - a single place to differentiate would be nice.
       Log.Fail(callId, x);
     }
   }
}

The service itself would also use callId to log its own process:

public class MyService: StatelessService, IMyService
{
  public async Task<string> GetMeAString(string prefix)
  {
      Debug.Assert(prefix!=null); // this exception is a caller fault
      Guid callId = GetFromAsyncLocal();
      Log(callId, "Got a call here")
      string result = prefix+": "+Guid.NewGuid().ToString();
      Log(callId, "returning "+result);
      return result;
  }
}

I don't understand why AsyncLocal works here, but apparently, it does.

Upvotes: 0

Views: 78

Answers (1)

Diego Mendes
Diego Mendes

Reputation: 11341

I think you are looking for Trace Correlation with Service Remoting from Microsoft Application Insights for Service Fabric package.

It will send all dependency tracking information to application insights, does not need much change in the code and can also be combined with the other application insights monitoring features.

The option mentioned by Peter Bons is also valid one if you want to do it from scratch or not use AppInsights.

Upvotes: 1

Related Questions