2016-09-14 54 views
1

对于蔚蓝演员服务,Actor Method Start Stop登录诊断窗口,如下所示。演员方法开始/停止日志|添加附加信息

如何在每次调用方法时添加一些附加细节,如相关标识?

{ 
    "Timestamp": "2016-09-14T19:46:40.9955448+05:30", 
    "ProviderName": "Microsoft-ServiceFabric-Actors", 
    "Id": 7, 
    "Message": "Actor method is being invoked. Method name: IStore.GetStoreById, actor type: Backend.Actor.Store.Store, actor ID: STORE_6.", 
    "ProcessId": 30736, 
    "Level": "Verbose", 
    "Keywords": "0x0000F00000000002", 
    "EventName": "ActorMethod/Start", 
    "Payload": { 
    "methodName": "IStore.GetStoreById", 
    "methodSignature": "System.Threading.Tasks.Task`1[Backend.Models.Store.StoreView] GetStoreById(System.String)", 
    "actorType": "Backend.Actor.Store.Store", 
    "actorId": "STORE_6", 
    "actorIdKind": 2, 
    "replicaOrInstanceId": 131183360004211655, 
    "partitionId": "8af1c125-3666-40d0-b630-e3570c41833b", 
    "serviceName": "fabric:/MultiBannerBackend/StoreActorService", 
    "applicationName": "fabric:/MultiBannerBackend", 
    "serviceTypeName": "StoreActorServiceType", 
    "applicationTypeName": "MultiBannerBackendType", 
    "nodeName": "_Node_4" 
    } 
} 

回答

0

为了记录的数据给每个演员的操作,您可以使用这些方法:

protected override Task OnPreActorMethodAsync(ActorMethodContext c) 
protected override Task OnPostActorMethodAsync(ActorMethodContext c) 

为了得到通话情况下,我发现CallContext.LogicalGetData不在这种情况下工作。演员本身幸运地知道它的上下文。你可以用一些反思来获得它。

例如:

protected override Task OnPreActorMethodAsync(ActorMethodContext c) 
     { 
      var correlationID = this.GetActorContext() ?? Guid.Empty.ToString("N"); 
      string message = $"Actor method is being invoked. Method name: {c.MethodName}, actor type: {GetType().FullName}, actor ID: {Id}, CorrelationID:{correlationID}"; 
      ActorEventSource.Current.ActorMessage(this, message); 
      return Task.FromResult(true); 
     } 

     protected override Task OnPostActorMethodAsync(ActorMethodContext c) 
     { 
      var correlationID = this.GetActorContext() ?? Guid.Empty.ToString("N"); 
      string message = $"Actor method has completed. Method name: {c.MethodName}, actor type: {GetType().FullName}, actor ID: {Id}, CorrelationID:{correlationID}"; 
      ActorEventSource.Current.ActorMessage(this, message); 
      return Task.FromResult(true); 
     } 

结合:这

public static class ActorContextExtensions 
    { 
     public static string GetActorContext(this Actor actor) 
     { 
      var concurrencyLockProperty = GetPropertyInfo("ConcurrencyLock", typeof(ActorBase)); 
      var concurrencyLockPropertyValue = concurrencyLockProperty.GetValue(actor); 

      var currentContextProperty = GetPropertyInfo("Test_CurrentContext", concurrencyLockPropertyValue.GetType()); 
      string currentContextPropertyValue = (string)currentContextProperty.GetValue(concurrencyLockPropertyValue); 
      return currentContextPropertyValue; 
     } 

     private static PropertyInfo GetPropertyInfo(string propertyName, IReflect owner) 
     { 
      var property = owner.GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance); 
      if (property == null) throw new InvalidOperationException($"Failed to find property '{propertyName}' on '{owner}'."); 
      return property; 
     } 
    } 

很明显的不足,就是每当ActorBase变化的内部,则需要相应地改变你的反射代码。

+0

非常感谢,这正是我一直在寻找的。 – user1800524