对于azure actor服务,Actor Method Start Stop在Diagnostics窗口中登录,如下所示。
如何在每次调用方法时添加一些其他详细信息,例如关联ID?
{
"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 :(得分:0)
为了记录每个Actor操作的自定义数据,您可以使用以下方法:
protected override Task OnPreActorMethodAsync(ActorMethodContext c)
protected override Task OnPostActorMethodAsync(ActorMethodContext c)
为了获得调用上下文,我发现CallContext.LogicalGetData在这种情况下不起作用。幸运的是,Actor确实知道它的上下文。你可以使用一些反思来获得它。
例如:
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的内部发生变化,您就需要相应地更改反射代码。