microsoft / ApplicationInsights-ServiceFabric

ApplicationInsights SDK for ServiceFabric projects
MIT License
63 stars 26 forks source link

Add documentation for configure actor services #88

Open yantang-msft opened 6 years ago

yantang-msft commented 6 years ago

https://github.com/MicrosoftDocs/azure-docs/issues/17510

yantang-msft commented 6 years ago

Some examples here as draft, need more time for verification and editing.

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);
        }
    }
  2. 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)

  1. Initialize the Service Remoting dependency/request tracking modules like below. Notice: 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);
  2. 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()))
            };
        }
    }
  3. 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();
brahmnes commented 6 years ago

Do we still need to use the FabricTransportServiceRemotingProvider attribute to use V2 remoting? If so, should that be mentioned?

yantang-msft commented 6 years ago

Good point. The user should have set the attribute correctly to use Service Remoting, but I'll add a link to SF doc just in case.

yantang-msft commented 6 years ago

Also add doc for how to configure non asp.net core application, e.g., https://github.com/yantang-msft/service-fabric-application-insights-example/blob/master/StatelessBackend/StatelessBackend.cs

ththiem commented 5 years ago

Any update on a formal doc/process for this? Is it really to circumvent the auto-generated actor project with manually constructed classes and hooks and reconfiguring remoting endpoints manually just to add appinsights?

Edit: It should be pointed out that you should not override the CreateServiceReplicaListeners function in your custom class when doing this for Actors for it to work as out-of-the-box as possible.

yantang-msft commented 5 years ago

@ththiem The "draft" doc will most likely work and be the formal process, but I don't have time to double check and publish the doc officially. Let me know if you can't make it work and I can definitely take a look.

richardlawidjaja commented 5 years ago

Hi, one question here I tried to configure app insight for a reliable actor. however, I am unable to do this,

config.TelemetryInitializers.Add(FabricTelemetryInitializerExtension.CreateFabricTelemetryInitializer(this.Context)); everytime I tried to add Nuget package for Microsoft.ApplicationInsights.ServiceFabric.Native it will collide with my own Service fabric configuration

here is my setup : reliable actor Service fabric with the console-based application, with messaging pattern after fiddling around I am able to Push something to App insight but all go to analytics

image

however, I am not sure that this is the correct way to configure since this is messaging pattern there will be no request however is it possible for me to get those detail like how long on average a message being processed?

Thanks

yantang-msft commented 5 years ago

@richardlawidjaja See if the StartOperation suffice what you need

LoloActemium commented 5 years ago

Hi, I tried to add Actor to AppInsights map, and works well. I see my Actor and calls to the Actor. But, I cannot see Actor callback in application map. How can I get those callbacks shown in Application map (Actor calling back services) ?

Thanks in advance, Laurent.

yantang-msft commented 5 years ago

@LoloActemium Do you mean your actor is calling downstream service and the downstream service is not showing up in the app map? In this case, please check if you have configured request tracking module in the downstream service.

LoloActemium commented 5 years ago

Hi, Both Actor and Downstream service are shown on the map. But the "Arrow" between Actor and Service is not shown: I am not able to see that the actor is calling the service.

yantang-msft commented 5 years ago

@LoloActemium Have you checked if you configured the dependency tracking module of the actor and request tracking module for the downstream service correctly? The example here configured both the request and dependency telemetry module for Service Remoting. If you are using other protocols like Http, WCF, then you need different modules. You should be able to see the dependency telemetry and request telemetry of the services if they are configured correctly.

LoloActemium commented 5 years ago

@yantang-msft : Hello, I use the following function in both actor and downstream service :

public static void ConfigureAppInsightTelemtry(ServiceContext serviceContext)
        {
            if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("AppInsightsInstrumentationKey")))
            {
                //Adding telemetry stuffs
                var configuration = TelemetryConfiguration.Active;
                configuration.InstrumentationKey = Environment.GetEnvironmentVariable("AppInsightsInstrumentationKey");
                configuration.TelemetryInitializers.Add(FabricTelemetryInitializerExtension.CreateFabricTelemetryInitializer(serviceContext));

                TelemetryConfiguration.Active.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());
                TelemetryConfiguration.Active.TelemetryInitializers.Add(new HttpDependenciesParsingTelemetryInitializer());
                TelemetryConfiguration.Active.TelemetryInitializers.Add(new CodePackageVersionTelemetryInitializer());

                new DependencyTrackingTelemetryModule().Initialize(configuration);
                new ServiceRemotingRequestTrackingTelemetryModule().Initialize(configuration);
                new ServiceRemotingDependencyTrackingTelemetryModule().Initialize(configuration);
            }
        }

Did I miss something ?

yantang-msft commented 5 years ago

@LoloActemium what's the protocol being used to talk between the Actor and downstream service? And what's type of the backend service? Asp.Net or Asp.Net core or console app?

LoloActemium commented 5 years ago

@yantang-msft : Hi, we use Service Fabric default protocol. Service is .Net 4.6.1 Console application hosted, Actor is .Net 4.6.1 Console application.

yantang-msft commented 5 years ago

@LoloActemium I suppose you mean they are communicating through Service Remoting. Make sure you are using Service Remoting V2, as the code you pasted only works for Service Remoting V2. Also, instead of looking at the App Map, please check if the dependency telemetry and request telemetry is collected at all. You can run some query like this, this will let you know if the telemetry module is initialized correctly. dependencies | where cloud_RoleName == <ActorName> requests | where cloud_RoleName == <DownStreamService>

LoloActemium commented 5 years ago

@yantang-msft I use V2 Remoting Stack. I see calls to the Actor in the telemetry. I see calls from the actor to our LogService. But I don't see the Event callback call: GetEvent<ICacheEvents>().CacheRefreshEvent(); In our own log, I can see that the actor is calling all subscribers, and that subscribers are doing the job.

yantang-msft commented 5 years ago

@LoloActemium Please checkout the example here: https://github.com/yantang-msft/service-fabric-application-insights-example/blob/yantang/ActorCallDownstream/ActorBackend/ActorBackend.cs#L61 Where the actor service calls the downstream service.

If it's configured correctly, you should see a pair of matching telemetry. To be more specific, a Request telemetry sent from the downstream service, and a RemoteDependency telemetry send from the actor service. image

Please verify that you see the matching telemetry, if not, then something is not configured correctly. Please refer the example to figure out what's missing.

LoloActemium commented 5 years ago

@yantang-msft: Actor calling a downstream service is working as expected. I see my Actor calling our LogService (another SF StatelessService in our application). But, for Actor subscribers, I do not see any entry when Actor is calling back the subscribers via the "Actor events" feature (https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-actors-events). Is there something special to configure in that case ?

yantang-msft commented 5 years ago

@LoloActemium Actor Events are not supported in this package, and we don't have plan to work it anytime soon.

mwonger commented 4 years ago

Side note on the above code, if integrating an actor service in with appinsights, make sure you are using singletons via statics for example instead of constructing a new FabricTelemetryInitializer and OperationCorrelationTelemetryInitializer. We ran into an issue where multiple initializers were getting created per actor thus causing performance issues as more and more actors were getting created. Thanks again Liudmila in https://github.com/microsoft/ApplicationInsights-dotnet/issues/1509, that helps in understanding usual depth of System.Diagnostics.Activity. Yanming, this was in regards to https://github.com/microsoft/ApplicationInsights-ServiceFabric/issues/107