2016-07-04 3 views
4

마이크로 서비스 플랫폼으로 서비스 패브릭을 사용하기 시작했으며 액터 패턴, 상태 비 저장/상태 저장 서비스, 웹 API (기타 등등)에 대한 첫 번째 "안녕하십니까"샘플을 성공적으로 구현 한 후 auth/autz 및 응용 프로그램 로깅과 같은 다른 핵심 측면에 대한 솔루션을 찾고 있습니다.서비스 패브릭 액터 및 서비스에 대한 상관 관계 토큰

로깅에 대한 의문점이 있습니다. 우리가 지금까지 설계 한 모든 SOA에서 관련된 모든 서비스에 "상관 관계 토큰"을 추가했습니다 (종종 아키텍처 수준에서, WCF에 헤더로 자동 추가되고 개발자에게는 숨겨 짐). 이제 우리는 동일한 서비스를 시도하고 있습니다 서비스 패브릭.

모든 액터/서비스 콜을 통해 "상관 관계 토큰 (Correlation Token)"을 처리 할 수있는 최상의 솔루션을 찾고 있습니다. 우리는 즉시 사용 가능한 것을 발견하지 못했기 때문에 우리가 찾고 있는지 궁금해하고 있습니다. 이론적으로 잘못된 것.

어떤 제안이 있습니까?

답변

1

serilogseq을 사용하여 많은 성공을 거두었으며 로그 메시지에 속성을 추가하기 위해 강화제를 사용했습니다.

내 서비스에서는 ServiceLogger.CreateLogger (this)를 호출하여 서비스에 대한 모든 상태가 풍부한 로그를 얻습니다. 상관 토큰을 원하면 비교적 쉽게 추가 할 수 있어야하지만, 아직 완료하지 않은 것입니다.

아래 관련 코드를 복사 한 것 같습니다. @

public class ServiceFabricEnricher<T> : ILogEventEnricher where T : ServiceContext 
{ 
    protected T Context { get; } 
    private LogEventProperty _nodeName; 

    public ServiceFabricEnricher(T context) 
    { 
     Context = context; 
    } 

    public virtual void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) 
    { 
     if (_nodeName == null) _nodeName = propertyFactory.CreateProperty("NodeName", Context.NodeContext.NodeName); 
     logEvent.AddPropertyIfAbsent(_nodeName); 
    } 
} 


public class ServiceEnricher<T> : ServiceFabricEnricher<T> where T : ServiceContext 
{ 
    private LogEventProperty _serviceName; 
    private LogEventProperty _partitionId; 
    private LogEventProperty _applicationName; 

    public ServiceEnricher(T context) : base(context) 
    { 
    } 

    public override void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) 
    { 
     base.Enrich(logEvent, propertyFactory); 

     if (_serviceName == null) _serviceName = propertyFactory.CreateProperty("ServiceName", Context.ServiceName); 
     if (_partitionId == null) _partitionId = propertyFactory.CreateProperty("PartitionId", Context.PartitionId); 
     if (_applicationName == null) _applicationName = propertyFactory.CreateProperty("ApplicationName", Context.CodePackageActivationContext.ApplicationName); 

     logEvent.AddPropertyIfAbsent(_serviceName); 
     logEvent.AddPropertyIfAbsent(_partitionId); 
     logEvent.AddPropertyIfAbsent(_applicationName); 
    } 
} 

public static class ServiceFabricLogger 
{ 
    private static ILogger CreaterDefaultLogger() 
    { 
     var configurationProvider = new FabricConfigurationProvider("SeqConfig"); 

     var loggerConfiguration = new LoggerConfiguration(); 
     if (configurationProvider.HasConfiguration) 
     { 
      var seqServer = configurationProvider.GetValue("SeqServer"); 
      loggerConfiguration = 
       loggerConfiguration 
       .WriteTo.Seq(seqServer, period: TimeSpan.FromMilliseconds(500)) 
       ; 

      var level = configurationProvider.GetValue("MinimumLevel"); 
      LogEventLevel minimumLevel; 
      if (!string.IsNullOrWhiteSpace(level) && Enum.TryParse<LogEventLevel>(level, true, out minimumLevel)) 
      { 
       loggerConfiguration = loggerConfiguration.MinimumLevel.Is(minimumLevel); 
      } 
     } 
     else 
     { 
      loggerConfiguration = 
       loggerConfiguration 
       .MinimumLevel.Error() 
       ; 
     } 

     Log.Logger = loggerConfiguration.CreateLogger(); 
     return Log.Logger; 
    } 

    public static ILogger Logger { get; } = CreaterDefaultLogger(); 
} 

public static class ServiceLogger 
{ 
    public static ILogger CreateLogger(this StatefulServiceBase service) => 
     ServiceFabricLogger.Logger.ForContext(new[] { new StatefulServiceEnricher(service.Context) }); 

    public static ILogger CreateLogger(this StatelessService service) => 
     ServiceFabricLogger.Logger.ForContext(new[] { new StatelessServiceEnricher(service.Context) }); 
} 
+0

닉 - radell 내 문제는 내 선택은 당신 (나는 common.loggin + log4net에 의존)하지만 그것은 아주 관계가 다릅니다 그 목적을 위해, 로그 기반 모델링에 대해 아닙니다. 내 문제는 ** 토큰을 클라이언트에서 ServiceFabric 액터/서비스 ** 내의 서버로 이동시키는 방법입니다. 더 좋은 방법은 WCF를 사용하여 통신을 설정하는 것이 간단하고 행동을 통해 헤더를 추가하는 것만으로도 충분하지만 문제는 리모팅을 사용하여 동일하게 수행하는 것입니다 (기본 설정이고이를 사용하고 싶습니다) – MonDeveloper