How can we add Application Insight in Service Fabric Actor Reliable service

667 views Asked by At

We have 5 reliable actor services which are being called from a stateless aspnet core web api. Now, the service fabric application is running in production but as a part of migration to azure we want all our custom events and trace to app insight.

How can we add the same to SF? Please note that I am looking specifically for reliable actor service. It's kind of simple adding that in reliable service but I am facing challenges with Actor services.

I referred to this https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-tutorial-monitoring-aspnet tutorial for reliable services but same doesn't work in case of reliable actor service written in .NET Framework.

1

There are 1 answers

0
Bhargavi Annadevara On

Quoting the example from this open GitHub issue: Add documentation for configure actor services

Setting Service Context

  1. Create your own actor service class and initialize the context there:
internal class MyActorService : ActorService
{
    public MyActorService(
        StatefulServiceContext context,
        ActorTypeInformation actorTypeInfo,
        Func<ActorService, ActorId, ActorBase> actorFactory = null,
        Func<ActorBase, IActorStateProvider, IActorStateManager> stateManagerFactory = null,
        IActorStateProvider stateProvider = null,
        ActorServiceSettings settings = null)
    : base(context, actorTypeInfo, actorFactory, stateManagerFactory, stateProvider, settings)
    {
        FabricTelemetryInitializerExtension.SetServiceCallContext(this.Context);
    }
}
  1. Register the actor service like below:
ActorRuntime.RegisterActorAsync<MyActor>(
    (context, actorType) => new MyActorService(context, actorType)).GetAwaiter().GetResult();

Enabling Correlation for Service Remoting

Firstly, make sure Service Remoting is set up correctly. You can find more info here.

Remoting V2 (recommended)

Initialize the Service Remoting dependency/request tracking modules like below.

Note: You can also set the service context through the CreateFabricTelemetryInitializer method. In this case, you don't need to call SetServiceCallContext

public MyActorServiceNetCore(
            StatefulServiceContext context,
            ActorTypeInformation actorTypeInfo,
            Func<ActorService, ActorId, ActorBase> actorFactory = null,
            Func<ActorBase, IActorStateProvider, IActorStateManager> stateManagerFactory = null,
            IActorStateProvider stateProvider = null,
            ActorServiceSettings settings = null)
        : base(context, actorTypeInfo, actorFactory, stateManagerFactory, stateProvider, settings)
        {
            var config = TelemetryConfiguration.Active;
            config.InstrumentationKey = "<your ikey>";
            config.TelemetryInitializers.Add(FabricTelemetryInitializerExtension.CreateFabricTelemetryInitializer(this.Context));

            var requestTrackingModule = new ServiceRemotingRequestTrackingTelemetryModule();
            var dependencyTrackingModule = new ServiceRemotingDependencyTrackingTelemetryModule();
            requestTrackingModule.Initialize(config);
            dependencyTrackingModule.Initialize(config);
        }

Remoting V1

If you still want to use Service Remoting V1 and also track correlation, you can follow the instructions below, but it's strongly recommended that you upgrade to Remoting V2.

  1. Create the proxy like below on sender side
//IActorService actorServiceProxy = ActorServiceProxy.Create(new Uri(serviceUri), partitionKey);
CorrelatingActorProxyFactory actorProxyFactory = new CorrelatingActorProxyFactory(serviceContext, callbackClient => new FabricTransportActorRemotingClientFactory(callbackClient));
IActorService actorServiceProxy = actorProxyFactory.CreateActorServiceProxy<IActorService>(new Uri(serviceUri), partitionKey);
  1. Initialize the listener like below:
    internal class MyActorService : ActorService
    {
        public MyActorService(
            StatefulServiceContext context,
            ActorTypeInformation actorTypeInfo,
            Func<ActorService, ActorId, ActorBase> actorFactory = null,
            Func<ActorBase, IActorStateProvider, IActorStateManager> stateManagerFactory = null,
            IActorStateProvider stateProvider = null,
            ActorServiceSettings settings = null)
        : base(context, actorTypeInfo, actorFactory, stateManagerFactory, stateProvider, settings)
        {
        }

        protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
        {
            return new[]
            {
                new ServiceReplicaListener(
                    context => new FabricTransportActorServiceRemotingListener(
                        context,
                        new CorrelatingRemotingMessageHandler(this),
                        new FabricTransportRemotingListenerSettings()))
            };
        }
    }
  1. Register your own actor service:
// ActorRuntime.RegisterActorAsync<MyActor>(
//     (context, actorType) => new ActorService(context, actorType)).GetAwaiter().GetResult();
ActorRuntime.RegisterActorAsync<MyActor>(
    (context, actorType) => new MyActorService(context, actorType)).GetAwaiter().GetResult();

Originally posted by @yantang-msft in https://github.com/microsoft/ApplicationInsights-ServiceFabric/issue_comments/434430800

Other resources: service-fabric-application-insights-example