【问题标题】:Correlation Token for Service Fabric Actors and ServicesService Fabric 参与者和服务的相关令牌
【发布时间】:2016-11-06 07:36:52
【问题描述】:

我们开始使用 Service Fabric 作为微服务平台,在成功实现了我们的第一个关于 Actor 模式、无状态/有状态服务、Web api(等等)的“hello world”示例之后,我们开始寻找其他核心的解决方案auth/autz 和应用程序日志记录等方面。

我对 Logging 有疑问;到目前为止,在我们设计的所有 SOA 中,我们总是为所有涉及的服务添加一个“关联令牌”(通常在架构级别,作为标头自动添加到 WCF 上,对开发人员隐藏)所以,现在我们正在尝试做同样的事情使用 Service Fabric。

寻找让“相关令牌”流经所有参与者/服务调用的最佳解决方案,因为我们还没有发现任何现成可用的东西,我们想知道我们是否正在寻找一些东西理论上是错误的。

有什么建议吗?

【问题讨论】:

    标签: logging token actor microservices azure-service-fabric


    【解决方案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) });
    }
    

    【讨论】:

    • @nick-radell 我的问题不在于 Log 基础设施建模,为此我的选择与您的不同(我依赖 common.loggin + log4net)但它完全无关紧要。我的问题是如何让令牌在 ServiceFabric 参与者/服务中从客户端流向服务器。更好的是,如果我选择使用 WCF 建立通信,这非常简单,通过行为添加标头就足够了,但问题是使用远程处理做同样的事情(这是默认设置,我想坚持使用它)
    猜你喜欢
    • 2017-12-17
    • 2016-04-07
    • 2016-07-26
    • 2016-02-28
    • 2017-01-31
    • 2017-12-27
    • 1970-01-01
    • 2015-12-28
    • 2018-09-01
    相关资源
    最近更新 更多