Exemple #1
0
 private static void ConfigureMetricsReporting(IWebHostBuilder builder, MetricOptions options)
 {
     if (String.Equals(options.Provider, "prometheus"))
     {
         var metrics = AppMetrics.CreateDefaultBuilder()
                       .OutputMetrics.AsPrometheusPlainText()
                       .OutputMetrics.AsPrometheusProtobuf()
                       .Build();
         builder.ConfigureMetrics(metrics).UseMetrics(o => {
             o.EndpointOptions = endpointsOptions => {
                 endpointsOptions.MetricsTextEndpointOutputFormatter = metrics.OutputMetricsFormatters.GetType <MetricsPrometheusTextOutputFormatter>();
                 endpointsOptions.MetricsEndpointOutputFormatter     = metrics.OutputMetricsFormatters.GetType <MetricsPrometheusProtobufOutputFormatter>();
             };
         });
     }
     else if (!String.Equals(options.Provider, "statsd"))
     {
         builder.UseMetrics();
     }
 }
Exemple #2
0
        /// <summary>
        /// 注册AppMetrics
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        public static void RegisterAppMetrics(this IServiceCollection services, IConfiguration configuration)
        {
            var metrics = AppMetrics.CreateDefaultBuilder()
                          .Configuration.Configure(
                options =>
            {
                options.AddAppTag(configuration.GetValue <string>("AppMetrics:App"));
                options.AddEnvTag(configuration.GetValue <string>("AppMetrics:Env"));
                options.Enabled          = true;
                options.ReportingEnabled = true;
            })
                          .Report.ToInfluxDb(
                options =>
            {
                // 配置InfluxDb
                options.InfluxDb.BaseUri                 = new Uri(configuration.GetValue <string>("InfluxDb:ConnectionString"));
                options.InfluxDb.Database                = configuration.GetValue <string>("AppMetrics:App");
                options.InfluxDb.UserName                = configuration.GetValue <string>("InfluxDb:UserName");
                options.InfluxDb.Password                = configuration.GetValue <string>("InfluxDb:Password");
                options.HttpPolicy.BackoffPeriod         = TimeSpan.FromSeconds(30);
                options.HttpPolicy.FailuresBeforeBackoff = 5;
                options.HttpPolicy.Timeout               = TimeSpan.FromSeconds(10);
                options.FlushInterval = TimeSpan.FromSeconds(5);
            })
                          .Build();

            services.AddMetrics(metrics);
            services.AddMetricsEndpoints(options =>
            {
                // 允许启用/禁用/metrics端点
                options.MetricsEndpointEnabled = true;

                //允许启用 / 禁用 / metrics - text端点
                options.MetricsTextEndpointEnabled = true;

                // 允许启用/禁用/env端点
                options.EnvironmentInfoEndpointEnabled = true;
            });
            services.AddMetricsReportingHostedService();
            services.AddMetricsTrackingMiddleware();
        }
        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            Metrics = AppMetrics.CreateDefaultBuilder()
                      .OutputMetrics.AsPrometheusPlainText()
                      .OutputMetrics.AsPrometheusProtobuf()
                      .Build();

            return(Host.CreateDefaultBuilder(args)
                   .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder
                .UseMetrics()
                .UseMetricsEndpoints(options =>
                {
                    options.MetricsTextEndpointOutputFormatter = Metrics.OutputMetricsFormatters.OfType <MetricsPrometheusTextOutputFormatter>().First();
                    options.MetricsEndpointOutputFormatter = Metrics.OutputMetricsFormatters.OfType <MetricsPrometheusProtobufOutputFormatter>().First();
                })
                .UseMetricsWebTracking()
                .UseStartup <Startup>();
            }));
        }
 public static IMetricsRoot CreateMetrics(string graphiteUri, TimeSpan flushInterval, params string[] pathNodes)
 {
     return(AppMetrics.CreateDefaultBuilder()
            .Report.ToGraphite(g =>
     {
         g.FlushInterval = flushInterval;
         g.Graphite.BaseUri = new Uri(graphiteUri);
         var metricFields = new MetricFields();
         metricFields.Histogram.OnlyInclude(HistogramFields.Count, HistogramFields.Max, HistogramFields.Min,
                                            HistogramFields.P999, HistogramFields.Sum, HistogramFields.Mean);
         metricFields.Meter.OnlyInclude(MeterFields.Count, MeterFields.Rate5M, MeterFields.Rate1M, MeterFields.SetItem);
         metricFields.DefaultGraphiteMetricFieldNames();
         g.MetricsOutputFormatter
             = new MetricsGraphitePlainTextProtocolOutputFormatter(
                   new MetricsGraphitePlainTextProtocolOptions
         {
             MetricPointTextWriter = new CustomGraphitePointTextWriter(pathNodes)
         }, metricFields);
     })
            .Build());
 }
Exemple #5
0
        public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
            Metrics = AppMetrics.CreateDefaultBuilder()
                      .OutputMetrics.AsPrometheusPlainText()
                      .Build();

            return(WebHost.CreateDefaultBuilder(args)
                   .UseConfiguration(Configuration)
                   .UseSerilog()
                   .UseHealth()
                   .ConfigureMetrics(Metrics)
                   .UseMetrics(options =>
            {
                options.EndpointOptions = endpointsOptions =>
                {
                    endpointsOptions.MetricsEndpointOutputFormatter = Metrics.OutputMetricsFormatters.GetType <MetricsPrometheusTextOutputFormatter>();
                };
            })
                   .UseMetricsWebTracking()
                   .UseStartup <Startup>());
        }
Exemple #6
0
        public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
            var metrics = AppMetrics.CreateDefaultBuilder()
                          .OutputMetrics.AsPrometheusPlainText()
                          .OutputMetrics.AsPrometheusProtobuf()
                          .Build();

            return(WebHost.CreateDefaultBuilder(args)
                   .ConfigureMetrics(metrics)
                   .UseMetrics(options =>
            {
                options.EndpointOptions = endpointsOptions =>
                {
                    endpointsOptions.MetricsTextEndpointOutputFormatter
                        = metrics.OutputMetricsFormatters.GetType <MetricsPrometheusTextOutputFormatter>();
                    endpointsOptions.MetricsEndpointOutputFormatter
                        = metrics.OutputMetricsFormatters.GetType <MetricsPrometheusProtobufOutputFormatter>();
                };
            })
                   .UseStartup <Startup>());
        }
Exemple #7
0
        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            IMetricsRoot metrics = AppMetrics.CreateDefaultBuilder()
                                   .OutputMetrics.AsPrometheusPlainText()
                                   .Build();

            return(Host.CreateDefaultBuilder(args)
                   .UseSerilog()
                   .ConfigureMetrics(metrics)
                   .ConfigureAppMetricsHostingConfiguration(options => { options.MetricsEndpoint = "/metrics"; })
                   .UseMetrics(
                       options =>
            {
                options.EndpointOptions = endpointOptions =>
                {
                    endpointOptions.MetricsEndpointOutputFormatter = metrics.OutputMetricsFormatters.GetType <MetricsPrometheusTextOutputFormatter>();
                };
            })
                   .ConfigureWebHostDefaults(webBuilder =>
                                             webBuilder.UseStartup <Startup>()));
        }
Exemple #8
0
        static void Main(string[] args)
        {
            // 将会自动将 app(程序集名)、server(机器名)和env(运行环境)作为标签
            var metrics = AppMetrics.CreateDefaultBuilder()
                          .Report.ToConsole()
                          .Build();

            //metrics.Measure.Gauge.SetValue(MyMetrics.ProcessMetrics.SystemNonPagedMemoryGauge, 2);

            //metrics.Measure.Gauge.SetValue(MyMetrics.ProcessMetrics.ProcessVirtualMemorySizeGauge, 20);

            //using (metrics.Measure.Timer.Time(MyMetrics.DatabaseMetrics.SearchUsersSqlTimer))
            //{
            //    Thread.Sleep(100);
            //}

            var process = Process.GetCurrentProcess();

            var derivedGauge = new GaugeOptions
            {
                Name            = "Derived Gauge",
                MeasurementUnit = Unit.MegaBytes
            };

            var processPhysicalMemoryGauge = new GaugeOptions
            {
                Name            = "Process Physical Memory",
                MeasurementUnit = Unit.Bytes
            };

            var physicalMemoryGauge = new FunctionGauge(() => process.WorkingSet64);

            metrics.Measure.Gauge.SetValue(derivedGauge, () => new DerivedGauge(physicalMemoryGauge, g => g / 1024 / 1024));

            metrics.Measure.Gauge.SetValue(processPhysicalMemoryGauge, () => physicalMemoryGauge);

            Task.WhenAll(metrics.ReportRunner.RunAllAsync()).Wait();

            Console.ReadKey();
        }
Exemple #9
0
        public static IHost BuildWebHost(string[] args)
        {
            ConfigureLogging();

            var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).
                                AddJsonFile(path: "appsettings.json", optional: false, reloadOnChange: true).Build();

            var statsDOptions = new MetricsReportingStatsDOptions();

            configuration.GetSection(nameof(MetricsReportingStatsDOptions)).Bind(statsDOptions);

            // Samples with weight of less than 10% of average should be discarded when rescaling
            const double minimumSampleWeight = 0.001;

            var metrics = AppMetrics.CreateDefaultBuilder().Configuration.ReadFrom(configuration).SampleWith.ForwardDecaying(
                AppMetricsReservoirSamplingConstants.DefaultSampleSize,
                AppMetricsReservoirSamplingConstants.DefaultExponentialDecayFactor,
                minimumSampleWeight: minimumSampleWeight).Report.ToStatsDUdp(statsDOptions).Build();

            return(Host.CreateDefaultBuilder(args).ConfigureMetrics(metrics).UseMetrics().UseSerilog().ConfigureWebHostDefaults(
                       webBuilder => { webBuilder.UseStartup <Startup>(); }).Build());
        }
        private IServiceProvider SetupServicesAndConfiguration(
            Action <MetricsWebTrackingOptions> trackingSetupAction = null,
            Action <MetricEndpointsOptions> setupEndpointAction    = null)
        {
            var services = new ServiceCollection();

            services.AddOptions();

            var builder = new ConfigurationBuilder()
                          .SetBasePath(AppContext.BaseDirectory)
                          .AddJsonFile("DependencyInjection/TestConfiguration/appsettings.json", optional: true, reloadOnChange: true);

            var configuration = builder.Build();

            var metricsBuilder = AppMetrics.CreateDefaultBuilder()
                                 .Configuration.ReadFrom(configuration);

            services.AddMetrics(metricsBuilder);

            if (setupEndpointAction == null)
            {
                services.AddMetricsEndpoints(configuration.GetSection(nameof(MetricEndpointsOptions)));
            }
            else
            {
                services.AddMetricsEndpoints(configuration.GetSection(nameof(MetricEndpointsOptions)), setupEndpointAction);
            }

            if (trackingSetupAction == null)
            {
                services.AddMetricsTrackingMiddleware(configuration.GetSection(nameof(MetricsWebTrackingOptions)));
            }
            else
            {
                services.AddMetricsTrackingMiddleware(configuration.GetSection(nameof(MetricsWebTrackingOptions)), trackingSetupAction);
            }

            return(services.BuildServiceProvider());
        }
Exemple #11
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpc();

            services.AddSingleton(sp =>
            {
                var lifetimeEvents = sp.GetService <IHostApplicationLifetime>();
                var ekati          = new Ekati.GrpcFileStore(new Config(
                                                                 Convert.ToInt32(1), //Environment.ProcessorCount * .75),
                                                                 FSharpFunc <string, Unit> .FromConverter(
                                                                     input => { return(null); }),
                                                                 false,
                                                                 AppMetrics
                                                                 .CreateDefaultBuilder()
                                                                 .Build())) as IStorage;

                lifetimeEvents.ApplicationStopping.Register(() =>
                {
                    Console.WriteLine("Ekati got shutdown event. Calling Stop");
                    ekati.Stop();
                    Console.WriteLine("Ekati got shutdown event. Stop Finished");
                });

                return(ekati);
            });
            services.AddGrpc();
            //services.AddGrpcWeb(o => o.GrpcWebEnabled = true);

            // services.AddCors(o =>
            // {
            //     o.AddPolicy("MyPolicy", builder =>
            //     {
            //         builder.WithOrigins("localhost:5001","localhost:5000");
            //         builder.WithMethods("POST,OPTIONS");
            //         builder.AllowAnyHeader();
            //         builder.WithExposedHeaders("Grpc-Status", "Grpc-Message");
            //     });
            // });
        }
        public void ConfigureServices(IServiceCollection services)
        {
            services
            .AddMvc(options => { options.Filters.Add(typeof(GlobalExceptionFilter)); })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddApiVersioning()
            .AddHttpClient();

            var metrics = AppMetrics.CreateDefaultBuilder().Report.ToConsole(options =>
            {
                options.FlushInterval          = TimeSpan.FromSeconds(5);
                options.Filter                 = new MetricsFilter().WhereType(MetricType.Timer);
                options.MetricsOutputFormatter = new MetricsJsonOutputFormatter();
            }).Build();

            services.AddMetrics(metrics)
            .AddMetricsTrackingMiddleware()
            .AddMetricsEndpoints()
            .AddHealth()
            .AddHealthEndpoints();

            var scheduler = new AppMetricsTaskScheduler(TimeSpan.FromSeconds(5),
                                                        async() => await Task.WhenAll(metrics.ReportRunner.RunAllAsync()));

            scheduler.Start();

            services.AddRssFeedsConfigurations(_env, options =>
            {
                options.AddDefault()
                .AddDataProtection()
                .AddDbContext()
                .AddCors()
                .AddSwagger()
                .AddTraceId()
                .AddRegistComponents()
                .AddRegistDomainEventHandlers();
            });
        }
        /// <summary>
        /// Build Web Host
        /// </summary>
        /// <param name="args"></param>
        /// <returns>Webhost</returns>
        public static IWebHost BuildWebHost(string[] args)
        {
            var Metrics = AppMetrics.CreateDefaultBuilder()
                          .OutputMetrics.AsPrometheusPlainText()
                          .OutputMetrics.AsPrometheusProtobuf()
                          .Build();

            System.Diagnostics.Debug.WriteLine(Metrics.DefaultOutputMetricsFormatter.MediaType.GetType());

            return(WebHost.CreateDefaultBuilder(args)
                   .ConfigureMetrics(Metrics)
                   .UseMetrics(
                       options =>
            {
                options.EndpointOptions = endpointsOptions =>
                {
                    endpointsOptions.MetricsTextEndpointOutputFormatter = Metrics.OutputMetricsFormatters.ElementAt(2);
                };
            })
                   .UseStartup <Startup>()
                   .UseUrls("http://0.0.0.0:5080/")
                   .Build());
        }
Exemple #14
0
        private static IWebHost BuildWebHost(string[] args)
        {
            var metrics = AppMetrics.CreateDefaultBuilder()
                          .OutputMetrics.AsPrometheusPlainText()
                          .Build();

            return(WebHost.CreateDefaultBuilder(args)
                   .UseIISIntegration()
                   .UseStartup <Startup>()
                   .UseSerilog()
                   .UseHealth()
                   .UseMetricsWebTracking()
                   .UseMetrics(
                       options =>
            {
                options.EndpointOptions = endpointsOptions =>
                {
                    endpointsOptions.MetricsTextEndpointOutputFormatter = metrics.OutputMetricsFormatters
                                                                          .GetType <MetricsPrometheusTextOutputFormatter>();
                };
            })
                   .Build());
        }
Exemple #15
0
        private static void Init()
        {
            var configurationBuilder = new ConfigurationBuilder()
                                       .SetBasePath(Directory.GetCurrentDirectory())
                                       .AddJsonFile("appsettings.json");

            Configuration = configurationBuilder.Build();

            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.Verbose()
                         .WriteTo.LiterateConsole(LogEventLevel.Information)
                         .WriteTo.Seq("http://localhost:5341", LogEventLevel.Verbose)
                         .CreateLogger();

            var metricsConfigSection = Configuration.GetSection(nameof(MetricsOptions));

            Metrics = AppMetrics.CreateDefaultBuilder()
                      .Configuration.Configure(metricsConfigSection.AsEnumerable())
                      .Report.Using <SimpleConsoleMetricsReporter>(TimeSpan.FromSeconds(2))
                      .Build();

            Reporter = Metrics.ReportRunner;
        }
Exemple #16
0
        public static IWebHost BuildWebHost(string[] args)
        {
            ConfigureLogging();

            var configuration = new ConfigurationBuilder()
                                .SetBasePath(Directory.GetCurrentDirectory())
                                .AddJsonFile(path: "appsettings.json", optional: false, reloadOnChange: true)
                                .Build();

            var influxOptions = new MetricsReportingInfluxDbOptions();

            configuration.GetSection(nameof(MetricsReportingInfluxDbOptions)).Bind(influxOptions);
            influxOptions.MetricsOutputFormatter = new MetricsInfluxDbLineProtocolOutputFormatter();

            var metrics = AppMetrics.CreateDefaultBuilder()
                          .Configuration.ReadFrom(configuration)
                          .Report.ToInfluxDb(influxOptions)
                          .Build();

            return(WebHost.CreateDefaultBuilder(args)
                   .ConfigureMetrics(metrics)
                   .ConfigureHealthWithDefaults(
                       (context, builder) =>
            {
                builder.OutputHealth.AsPlainText()
                .OutputHealth.AsJson()
                .HealthChecks.AddCheck("check 1", () => new ValueTask <HealthCheckResult>(HealthCheckResult.Healthy()))
                .HealthChecks.AddCheck("check 2", () => new ValueTask <HealthCheckResult>(HealthCheckResult.Degraded()))
                .HealthChecks.AddCheck("check 3", () => new ValueTask <HealthCheckResult>(HealthCheckResult.Unhealthy()))
                .Report.ToMetrics(metrics);
            })
                   .UseHealth()
                   .UseMetrics()
                   .UseSerilog()
                   .UseStartup <Startup>()
                   .Build());
        }
Exemple #17
0
        public void ConfigureServices(IServiceCollection services)
        {
            #region 注放Metrics
            var metrics = AppMetrics.CreateDefaultBuilder()
                          .Configuration.Configure(
                options =>
            {
                options.AddAppTag("RepairApp");
                options.AddEnvTag("stage");
            })
                          .Report.ToInfluxDb(
                options =>
            {
                options.InfluxDb.BaseUri                 = new Uri("http://127.0.0.1:8086");
                options.InfluxDb.Database                = "MetricsDB";
                options.InfluxDb.UserName                = "******";
                options.InfluxDb.Password                = "******";
                options.HttpPolicy.BackoffPeriod         = TimeSpan.FromSeconds(30);
                options.HttpPolicy.FailuresBeforeBackoff = 5;
                options.HttpPolicy.Timeout               = TimeSpan.FromSeconds(10);
                options.FlushInterval = TimeSpan.FromSeconds(5);
            })
                          .Build();
            services.AddMetrics(metrics);
            services.AddMetricsReportScheduler();
            services.AddMetricsTrackingMiddleware();
            services.AddMetricsEndpoints();
            #endregion

            #region 注放JWT
            var audienceConfig = Configuration.GetSection("Audience");
            //注入OcelotJwtBearer
            services.AddOcelotJwtBearer(audienceConfig["Issuer"], audienceConfig["Issuer"], audienceConfig["Secret"], "GSWBearer");
            #endregion
            //注入配置文件,AddOcelot要求参数是IConfigurationRoot类型,所以要作个转换
            services.AddOcelot(Configuration as ConfigurationRoot);
        }
Exemple #18
0
        private static void Initialize(CLI root)
        {
            if (root == null)
            {
                throw new InvalidOperationException("root should not be null.");
            }

            string context = root.RunTag ?? nameof(EGBench);

            IMetricsBuilder builder = AppMetrics.CreateDefaultBuilder()
                                      .Filter.With(new MetricsFilter().WhereContext(context))
                                      .Configuration.Configure(options =>
            {
                options.DefaultContextLabel = context;
                options.GlobalTags.Clear();
                options.Enabled          = true;
                options.ReportingEnabled = true;
            });

            if (root.AppInsightsKey.HasValue)
            {
                EGBenchLogger.WriteLine($"Reporting metrics to application insights with instrumentation key={root.AppInsightsKey.Value}");
                builder.Report.ToApplicationInsights(root.AppInsightsKey.Value);
            }
            else
            {
                isConsole = true;
                EGBenchLogger.WriteLine("Reporting metrics to console since --app-insights-key was not specified.");
                builder.Report.ToConsole(options =>
                {
                    options.MetricsOutputFormatter = new MetricsInfluxDbLineProtocolOutputFormatter();
                });
            }

            metricsRoot = builder.Build();

            _ = Task.Run(() => ReportingLoop(metricsRoot, root.MetricsIntervalSeconds));
Exemple #19
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            string mackerelApiKey = Configuration.GetValue <string>("Mackerel:ApiKey");
            string mackerelHostId = Configuration.GetValue <string>("Mackerel:HostId");
            var    filter         = new MetricsFilter();
            var    metrics        = AppMetrics.CreateDefaultBuilder()
                                    .Report.ToMackerel(
                options =>
            {
                options.ApiKey = mackerelApiKey;
                options.HostId = mackerelHostId;

                options.HttpOptions.HttpPolicy.BackoffPeriod         = TimeSpan.FromSeconds(30);
                options.HttpOptions.HttpPolicy.FailuresBeforeBackoff = 3;
                options.HttpOptions.HttpPolicy.Timeout = TimeSpan.FromSeconds(10);
                options.HttpOptions.Filter             = filter;
                options.HttpOptions.FlushInterval      = TimeSpan.FromSeconds(60);
            })
                                    .Build();

            SampleMetricsRunner.ScheduleSomeSampleMetrics(metrics);
            services.AddMetrics(metrics);
            services.AddMetricsTrackingMiddleware();
            services.AddMetricsReportingHostedService();
            services.AddMetricsEndpoints();

            services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddMetrics();
        }
Exemple #20
0
        public void RegisterAppMetrics(IServiceCollection services)
        {
            bool isOpenMetrics = Convert.ToBoolean(Configuration["AppMetrics:IsOpen"]);

            if (isOpenMetrics)
            {
                string database = Configuration["AppMetrics:DatabaseName"];
                string connStr  = Configuration["AppMetrics:ConnectionString"];
                string app      = Configuration["AppMetrics:App"];
                string env      = Configuration["AppMetrics:Env"];
                string username = Configuration["AppMetrics:UserName"];
                string password = Configuration["AppMetrics:Password"];

                var uri     = new Uri(connStr);
                var metrics = AppMetrics.CreateDefaultBuilder().Configuration.Configure(options =>
                {
                    options.AddAppTag(app);
                    options.AddEnvTag(env);
                }).Report.ToInfluxDb(options =>
                {
                    options.InfluxDb.BaseUri                 = uri;
                    options.InfluxDb.Database                = database;
                    options.InfluxDb.UserName                = username;
                    options.InfluxDb.Password                = password;
                    options.HttpPolicy.BackoffPeriod         = TimeSpan.FromSeconds(30);
                    options.HttpPolicy.FailuresBeforeBackoff = 5;
                    options.HttpPolicy.Timeout               = TimeSpan.FromSeconds(10);
                    options.FlushInterval = TimeSpan.FromSeconds(5);
                }).Build();

                services.AddMetrics(metrics);
                services.AddMetricsReportScheduler();
                services.AddMetricsTrackingMiddleware();
                services.AddMetricsEndpoints();
            }
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            var metrics = AppMetrics.CreateDefaultBuilder()
                          .Report.ToInfluxDb(options => {
                options.InfluxDb.BaseUri  = new Uri("http://127.0.0.1:8086");
                options.InfluxDb.Database = "my-metrics";
                options.InfluxDb.CreateDataBaseIfNotExists = true;
            })
                          .Build();

            services.AddMetrics(metrics);
            services.AddMetricsTrackingMiddleware();
            services.AddMetricsReportingHostedService();
            services.AddHoneycomb(Configuration);

            services.AddMvc().AddMetrics();
        }
Exemple #22
0
        public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
            var metrics = AppMetrics.CreateDefaultBuilder()
                          .OutputMetrics.AsPrometheusPlainText()
                          .OutputMetrics.AsPrometheusProtobuf()
                          .Build();

            return(WebHost.CreateDefaultBuilder(args)
                   .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
                               .ReadFrom.Configuration(hostingContext.Configuration)
                               .Enrich.FromLogContext())
                   .UseHealth()
                   .UseMetrics(options =>
            {
                options.EndpointOptions = endpointsOptions =>
                {
                    endpointsOptions.MetricsTextEndpointOutputFormatter =
                        metrics.OutputMetricsFormatters.GetType <MetricsPrometheusTextOutputFormatter>();
                    endpointsOptions.MetricsEndpointOutputFormatter =
                        metrics.OutputMetricsFormatters.GetType <MetricsPrometheusProtobufOutputFormatter>();
                };
            })
                   .UseStartup <Startup>());
        }
Exemple #23
0
        public static IWebHost BuildWebHost(string[] args)
        {
            Metrics = AppMetrics.CreateDefaultBuilder()
                      .OutputMetrics.AsPrometheusPlainText()
                      .OutputMetrics.AsPrometheusProtobuf()
                      .Build();

            return(WebHost.CreateDefaultBuilder(args)
                   .ConfigureAppConfiguration((hostingContext, config) => {
                config.SetBasePath(Directory.GetCurrentDirectory());
                config.AddJsonFile("config/appusers.json", optional: true, reloadOnChange: true);
            })
                   .ConfigureMetrics(Metrics)
                   .UseMetrics(
                       options =>
            {
                options.EndpointOptions = endpointsOptions =>
                {
                    endpointsOptions.MetricsEndpointOutputFormatter = Metrics.OutputMetricsFormatters.GetType <MetricsPrometheusTextOutputFormatter>();
                };
            })
                   .UseStartup <Startup>()
                   .Build());
        }
Exemple #24
0
        /// <summary>
        /// 配置服务
        /// </summary>
        public void ConfigureServices(IServiceCollection services)
        {
            // 添加授权认证
            var audienceConfig            = Configuration.GetSection("Audience");
            var defaultScheme             = audienceConfig["defaultScheme"];
            var keyByteArray              = Encoding.ASCII.GetBytes(audienceConfig["Secret"]);
            var signingKey                = new SymmetricSecurityKey(keyByteArray);
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey         = signingKey,
                ValidateIssuer           = true,
                ValidIssuer           = audienceConfig["Issuer"],   //发行人
                ValidateAudience      = true,
                ValidAudience         = audienceConfig["Audience"], //订阅人
                ValidateLifetime      = true,
                ClockSkew             = TimeSpan.Zero,
                RequireExpirationTime = true,
            };

            services.AddAuthentication()
            .AddJwtBearer(defaultScheme, opt =>
            {
                //不使用https
                opt.RequireHttpsMetadata      = false;
                opt.TokenValidationParameters = tokenValidationParameters;
            });
            // 添加跨域
            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy", builder => builder
                                  .AllowAnyOrigin()
                                  .AllowAnyMethod()
                                  .AllowAnyHeader()
                                  .AllowCredentials()
                                  );
            });
            // 添加网关
            Action <ConfigurationBuilderCachePart> settings = (x) =>
            {
                x.WithMicrosoftLogging(log =>
                {
                    log.AddConsole(LogLevel.Debug);
                })
                .WithDictionaryHandle();
            };

            services.AddOcelot(Configuration)
            .AddCacheManager(settings)
            //.AddStoreOcelotConfigurationInConsul()
            .AddAdministration("/administration", "axon@2018");
            // 添加首字母大写
            services.AddMvc().AddJsonOptions(options =>
            {
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();
            });
            // 添加事件驱动
            var eventConfig = Configuration.GetSection("EventBus").GetSection("RabbitMQ");

            services.AddEventBus(option =>
            {
                option.UseRabbitMQ(opt =>
                {
                    opt.HostName     = eventConfig["HostName"];
                    opt.Port         = Convert.ToInt32(eventConfig["Port"]);
                    opt.ExchangeName = eventConfig["ExchangeName"];
                    opt.QueueName    = eventConfig["QueueName"];
                });
            });
            // 添加统计
            var metrics = AppMetrics.CreateDefaultBuilder()
                          .Configuration.Configure(options => {
                options.AddAppTag("RepairApp");
                options.AddEnvTag("stage");
            })
                          .Report.ToInfluxDb(options => {
                options.InfluxDb.BaseUri                 = new Uri("http://192.168.1.199:8086");
                options.InfluxDb.Database                = "MetricsDB";
                options.InfluxDb.UserName                = "******";
                options.InfluxDb.Password                = "******";
                options.HttpPolicy.BackoffPeriod         = TimeSpan.FromSeconds(30);
                options.HttpPolicy.FailuresBeforeBackoff = 5;
                options.HttpPolicy.Timeout               = TimeSpan.FromSeconds(10);
                options.FlushInterval = TimeSpan.FromSeconds(5);
            })
                          .Build();

            services.AddMetrics(metrics);
            services.AddMetricsReportScheduler();
            services.AddMetricsTrackingMiddleware();
            services.AddMetricsEndpoints();
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            #region 注册Metrics 主要用作看板
            var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();
            var metrics = AppMetrics.CreateDefaultBuilder()
                          .Configuration.Configure(
                options =>
            {
                options.AddAppTag("RepairApp");
                options.AddEnvTag("stage");
            })
                          .Report.ToInfluxDb(
                options =>
            {
                options.InfluxDb.BaseUri                 = new Uri($"{builder["InfluxDb:BaseUri"]}");
                options.InfluxDb.Database                = builder["InfluxDb:Database"];
                options.InfluxDb.UserName                = builder["InfluxDb:UserName"];
                options.InfluxDb.Password                = builder["InfluxDb:Password"];
                options.HttpPolicy.BackoffPeriod         = TimeSpan.FromSeconds(30);
                options.HttpPolicy.FailuresBeforeBackoff = 5;
                options.HttpPolicy.Timeout               = TimeSpan.FromSeconds(10);
                options.FlushInterval = TimeSpan.FromSeconds(5);
            })
                          .Build();
            Console.WriteLine($"数据库名称:{ builder["InfluxDb:Database"] }");
            services.AddMetrics(metrics);
            services.AddMetricsReportingHostedService();
            services.AddMetricsTrackingMiddleware();
            services.AddMetricsEndpoints();
            #endregion
            #region 注册JWT
            var audienceConfig = Configuration.GetSection("Audience");
            //注入OcelotJwtBearer
            services.AddOcelotJwtBearer(audienceConfig["Issuer"], audienceConfig["Issuer"], audienceConfig["Secret"], "ChinaIrapBearer");
            #endregion

            //注入配置文件,AddOcelot要求参数是IConfigurationRoot类型,所以要作个转换//使用Polly做熔断策略
            // services.AddOcelot(Configuration as ConfigurationRoot).AddPolly();
            var ocelotConfig = new ConfigurationBuilder().AddJsonFile("ocelot.json", false, true).Build();
            services.AddMvc();
            //services.AddOcelot(ocelotConfig)
            //        .AddConsul().AddPolly()
            //        .AddConfigStoredInConsul();
            services.AddOcelot(Configuration as ConfigurationRoot).AddConsul().AddPolly().AddConfigStoredInConsul();

            services.Configure <SwaggerOptions>(Configuration.GetSection("Swagger"));
            var provider = services.BuildServiceProvider().GetRequiredService <IOptions <SwaggerOptions> >().Value;



            //if(  swaggerConfig["Swagger:UseSwagger"].Value)
            if (provider.UseSwagger)
            {
                services.AddSwaggerGen(options =>
                {
                    options.SwaggerDoc(provider.SwaggerConfig.DocName, new Info {
                        Title = provider.SwaggerConfig.TitleInfo, Version = provider.SwaggerConfig.VersionInfo
                    });
                });
            }
        }
Exemple #26
0
        public static IServiceCollection AddMetrics(this IServiceCollection services)
        {
            var builder = AppMetrics.CreateDefaultBuilder();

            return(services.AddMetrics(builder));
        }
        public void ConfigureServices(IServiceCollection services)
        {
            #region Metrics监控配置
            string IsOpen = Configuration.GetSection("InfluxDB:IsOpen").Value.ToLower();
            if (IsOpen == "true")
            {
                string database       = Configuration.GetSection("InfluxDB")["DataBaseName"];
                string InfluxDBConStr = Configuration.GetSection("InfluxDB")["ConnectionString"];
                string app            = Configuration.GetSection("InfluxDB")["app"];
                string env            = Configuration.GetSection("InfluxDB")["env"];
                string username       = Configuration.GetSection("InfluxDB")["username"];
                string password       = Configuration.GetSection("InfluxDB")["password"];
                var    uri            = new Uri(InfluxDBConStr);

                var metrics = AppMetrics.CreateDefaultBuilder()
                              .Configuration.Configure(
                    options =>
                {
                    options.AddAppTag(app);
                    options.AddEnvTag(env);
                })
                              .Report.ToInfluxDb(
                    options =>
                {
                    options.InfluxDb.BaseUri  = uri;
                    options.InfluxDb.Database = database;
                    options.InfluxDb.UserName = username;
                    options.InfluxDb.Password = password;
                    options.InfluxDb.CreateDataBaseIfNotExists = true;
                    options.HttpPolicy.BackoffPeriod           = TimeSpan.FromSeconds(30);
                    options.HttpPolicy.FailuresBeforeBackoff   = 5;
                    options.HttpPolicy.Timeout = TimeSpan.FromSeconds(10);
                    options.FlushInterval      = TimeSpan.FromSeconds(5);
                })
                              .Build();


                services.AddMetrics(metrics);
                services.AddMetricsReportingHostedService();
                services.AddMetricsTrackingMiddleware();
                services.AddMetricsEndpoints();

                var hmetrics = AppMetricsHealth.CreateDefaultBuilder().Report.ToMetrics(metrics)
                               //.HealthChecks.RegisterFromAssembly(services)    //自定义注册
                               .HealthChecks.AddCheck(new MyHealthCheck("自定义类现"))
                               .HealthChecks.AddCheck("委括实现", () =>
                {
                    if (DateTime.Now.Second % 3 != 0)
                    {
                        return(new ValueTask <HealthCheckResult>(HealthCheckResult.Healthy("Ok")));
                    }
                    else
                    {
                        return(new ValueTask <HealthCheckResult>(HealthCheckResult.Unhealthy("error")));
                    }
                })
                               .BuildAndAddTo(services);
                services.AddHealth(hmetrics);
                services.AddHealthReportingHostedService();
                services.AddHealthEndpoints();
            }

            #endregion

            services.AddMvc().AddMetrics().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }
Exemple #28
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddAutoMapper(typeof(Startup));

            services.AddMediatR(typeof(Startup));

            services.AddDbContext <DatabaseContext>(options => options.UseSqlServer(Configuration.GetConnectionString(ConnectionStringKeys.App)));

            services.AddHangfire(x => x.UseSqlServerStorage(Configuration.GetConnectionString(ConnectionStringKeys.Hangfire)));

            services.AddCorrelationId();

            services.AddOptions();

            var metricsConfigSection = Configuration.GetSection(nameof(MetricsOptions));
            var influxOptions        = new MetricsReportingInfluxDbOptions();

            Configuration.GetSection(nameof(MetricsReportingInfluxDbOptions)).Bind(influxOptions);

            var metrics = AppMetrics.CreateDefaultBuilder()
                          .Configuration.Configure(metricsConfigSection.AsEnumerable())
                          .Report.ToInfluxDb(influxOptions)
                          .Build();

            services.AddMetrics(metrics);
            services.AddMetricsReportScheduler();

            // Pipeline
            services.AddScoped(typeof(IPipelineBehavior <,>), typeof(MetricsProcessor <,>));
            services.AddScoped(typeof(IPipelineBehavior <,>), typeof(ValidationBehavior <,>));
            services.AddScoped(typeof(IPipelineBehavior <,>), typeof(RequestPreProcessorBehavior <,>));
            services.AddScoped(typeof(IPipelineBehavior <,>), typeof(RequestPostProcessorBehavior <,>));

            services.AddMvc(opt => { opt.Filters.Add(typeof(ExceptionFilter)); })
            .AddMetrics()
            .AddControllersAsServices()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddFluentValidation(cfg => { cfg.RegisterValidatorsFromAssemblyContaining <Startup>(); });

            // Identity
            var identityOptions = new Infrastructure.Identity.IdentityOptions();

            Configuration.GetSection(nameof(Infrastructure.Identity.IdentityOptions)).Bind(identityOptions);

            services.AddIdentity <User, Role>(options =>
            {
                options.Password.RequireDigit           = true;
                options.Password.RequireLowercase       = true;
                options.Password.RequireNonAlphanumeric = true;
                options.Password.RequireUppercase       = true;
                options.Password.RequiredLength         = 6;
                options.User.RequireUniqueEmail         = true;
            })
            .AddEntityFrameworkStores <DatabaseContext>()
            .AddDefaultTokenProviders();

            services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority            = identityOptions.Authority;
                options.ApiName              = identityOptions.ApiName;
                options.ApiSecret            = identityOptions.ApiSecret;
                options.RequireHttpsMetadata = _env.IsProduction();
                options.EnableCaching        = true;
                options.CacheDuration        = TimeSpan.FromMinutes(10);
            });

            IContainer container = new Container();

            container.Configure(config =>
            {
                config.Populate(services);
            });

            metrics.ReportRunner.RunAllAsync();


            // Check for missing dependencies
            var controllers = Assembly.GetExecutingAssembly().GetTypes()
                              .Where(type => typeof(ControllerBase).IsAssignableFrom(type))
                              .ToList();

            var sp = services.BuildServiceProvider();

            foreach (var controllerType in controllers)
            {
                _logger.LogInformation($"Found {controllerType.Name}");
                try
                {
                    sp.GetService(controllerType);
                }
                catch (Exception ex)
                {
                    _logger.LogCritical(ex, $"Cannot create instance of controller {controllerType.FullName}, it is missing some services");
                }
            }

            return(container.GetInstance <IServiceProvider>());
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddAutoMapper(typeof(Startup));

            services.AddMediatR(typeof(Startup));

            services.AddDbContext <DatabaseContext>(options =>
                                                    options.UseNpgsql(Configuration.GetConnectionString(ConnectionStringKeys.App)));

            services.AddHangfire(x =>
                                 x.UsePostgreSqlStorage(Configuration.GetConnectionString(ConnectionStringKeys.Hangfire)));

            services.AddCorrelationId();

            services.AddOptions();

            var metricsConfigSection = Configuration.GetSection(nameof(MetricsOptions));
            var influxOptions        = new MetricsReportingInfluxDbOptions();

            Configuration.GetSection(nameof(MetricsReportingInfluxDbOptions)).Bind(influxOptions);

            var metrics = AppMetrics.CreateDefaultBuilder()
                          .Configuration.Configure(metricsConfigSection.AsEnumerable())
                          .Report.ToInfluxDb(influxOptions)
                          .Build();

            services.AddMetrics(metrics);
            services.AddMetricsTrackingMiddleware();
            services.AddMetricsEndpoints();
            services.AddMetricsReportingHostedService();

            // Swagger
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info
                {
                    Version        = "v1",
                    Title          = "Knowledge API",
                    Description    = "Knowledge API v1",
                    TermsOfService = "None",
                    Contact        = new Contact
                    {
                        Name  = "Mads Engel Lundt",
                        Email = "*****@*****.**",
                        Url   = "https://elcc.dk"
                    }
                });
                c.CustomSchemaIds(x => x.FullName);
            });

            // Pipeline
            services.AddScoped(typeof(IPipelineBehavior <,>), typeof(MetricsProcessor <,>));
            services.AddScoped(typeof(IPipelineBehavior <,>), typeof(ValidationBehavior <,>));
            services.AddScoped(typeof(IPipelineBehavior <,>), typeof(RequestPreProcessorBehavior <,>));
            services.AddScoped(typeof(IPipelineBehavior <,>), typeof(RequestPostProcessorBehavior <,>));

            services.AddMvc(opt =>
            {
                opt.Filters.Add(typeof(ExceptionFilter));
                opt.Filters.Add(typeof(LocaleFilterAttribute));
            })
            .AddMetrics()
            .AddControllersAsServices()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddFluentValidation(cfg => { cfg.RegisterValidatorsFromAssemblyContaining <Startup>(); });

            // Identity
            var identityOptionsSection = Configuration.GetSection(nameof(Infrastructure.Identity.IdentityOptions));

            services.Configure <Infrastructure.Identity.IdentityOptions>(identityOptionsSection);

            // configure jwt authentication
            var identityOptions = identityOptionsSection.Get <Infrastructure.Identity.IdentityOptions>();
            var key             = Encoding.ASCII.GetBytes(identityOptions.ApiSecret);

            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            })
            //.AddIdentityServerAuthentication(options =>
            //{
            //    options.Authority = identityOptions.Authority;
            //    options.ApiName = identityOptions.ApiName;
            //    options.ApiSecret = identityOptions.ApiSecret;
            //    options.RequireHttpsMetadata = _env.IsProduction();
            //    options.EnableCaching = true;
            //    options.CacheDuration = TimeSpan.FromMinutes(10);
            //})
            .AddJwtBearer("Bearer", options =>
            {
                options.SaveToken = true;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = new SymmetricSecurityKey(key),
                    ValidateIssuer           = false,
                    ValidateAudience         = false
                };
                options.Audience = identityOptions.Audience;
            });

            IContainer container = new Container();

            container.Configure(config => config.Populate(services));

            var mediator = container.GetInstance <IMediator>();

            GlobalConfiguration.Configuration.UseMediator(mediator);

            metrics.ReportRunner.RunAllAsync();

            // Check for missing dependencies
            var controllers = Assembly.GetExecutingAssembly().GetTypes()
                              .Where(type => typeof(ControllerBase).IsAssignableFrom(type))
                              .ToList();

            var sp = services.BuildServiceProvider();

            foreach (var controllerType in controllers)
            {
                _logger.LogInformation($"Found {controllerType.Name}");
                try
                {
                    sp.GetService(controllerType);
                }
                catch (Exception ex)
                {
                    _logger.LogCritical(ex,
                                        $"Cannot create instance of controller {controllerType.FullName}, it is missing some services");
                }
            }

            services.AddLogging(builder => builder
                                .AddConfiguration(Configuration)
                                .AddConsole()
                                .AddDebug()
                                .AddEventSourceLogger()
                                .AddSentry());

            return(container.GetInstance <IServiceProvider>());
        }
Exemple #30
0
        /// <summary>
        /// Configure Services.
        /// </summary>
        /// <param name="services"></param>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();
            services.Configure <ApplicationOptions>(Configuration);
            services.Configure <Common.Configuration.ApplicationOptions>(Configuration);
            services.AddSingleton(Configuration);
            services.AddMemoryCache();
            services.AddSingleton <CronJobServiceHealthCheck>();

            var config = Configuration.Get <ApplicationOptions>();

            services.DisplayConfiguration(Configuration, HostingEnvironment);

            var commonConfig = Configuration.Get <MicroService.Common.Configuration.ApplicationOptions>();

            services.AddCustomApiVersioning();

            services.AddOpenTelemetryTracing(
                builder =>
            {
                _ = builder
                    .SetResourceBuilder(ResourceBuilder.CreateDefault()
                                        .AddService(HostingEnvironment.ApplicationName))
                    .AddSource(nameof(FeatureServiceController))
                    .AddAspNetCoreInstrumentation()
                    .AddHttpClientInstrumentation();

                if (commonConfig.JaegerConfiguration.Enabled)
                {
                    builder.AddJaegerExporter(o =>
                    {
                        o.AgentHost = commonConfig.JaegerConfiguration.Host;
                        o.AgentPort = commonConfig.JaegerConfiguration.Port;
                    });
                }

                if (HostingEnvironment.IsDevelopment())
                {
                    builder.AddConsoleExporter(options => options.Targets = ConsoleExporterOutputTargets.Console);
                }
            });

            var metrics = AppMetrics.CreateDefaultBuilder()
                          .OutputMetrics
                          .AsPrometheusPlainText()
                          .Build();

            MetricsHelpers.SetMetricsCustomTag(metrics, "OSDescription", System.Runtime.InteropServices.RuntimeInformation.OSDescription);
            MetricsHelpers.SetMetricsCustomTag(metrics, "instance", Dns.GetHostName());

            metrics.Options.ReportingEnabled = true;
            services.AddMetrics(metrics);
            services.AddAppMetricsHealthPublishing();
            services.AddAppMetricsCollectors();

            services.AddTransient <IConfigureOptions <SwaggerGenOptions>, ConfigureSwaggerOptions>();
            services.AddSwaggerConfiguration();
            services.AddCorsConfiguration();

            // Repositories
            services.AddScoped <ITestDataRepository>(x => new TestDataRepository(config.ConnectionStrings.PostgreSql));

            // Services
            services.AddScoped <ICalculationService, CalculationService>();

            services.AddScoped <ShapefileDataReaderResolver>(serviceProvider => key =>
            {
                ShapeAttributes shapeProperties = null;
                if (key == nameof(ShapeProperties.BoroughBoundaries))
                {
                    shapeProperties = ShapeProperties.BoroughBoundaries.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.CommunityDistricts))
                {
                    shapeProperties = ShapeProperties.CommunityDistricts.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.DSNYDistricts))
                {
                    shapeProperties = ShapeProperties.DSNYDistricts.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.HistoricDistricts))
                {
                    shapeProperties = ShapeProperties.HistoricDistricts.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.Neighborhoods))
                {
                    shapeProperties = ShapeProperties.Neighborhoods.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.NeighborhoodTabulationAreas))
                {
                    shapeProperties = ShapeProperties.NeighborhoodTabulationAreas.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.NypdPolicePrecincts))
                {
                    shapeProperties = ShapeProperties.NypdPolicePrecincts.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.NypdSectors))
                {
                    shapeProperties = ShapeProperties.NypdSectors.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.NychaDevelopments))
                {
                    shapeProperties = ShapeProperties.NychaDevelopments.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.Parks))
                {
                    shapeProperties = ShapeProperties.Parks.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.Subway))
                {
                    shapeProperties = ShapeProperties.Subway.GetAttribute <ShapeAttributes>();
                }
                else if (key == nameof(ShapeProperties.ZipCodes))
                {
                    shapeProperties = ShapeProperties.ZipCodes.GetAttribute <ShapeAttributes>();
                }
                else
                {
                    throw new KeyNotFoundException(key);
                }

                var options = serviceProvider.GetService <IOptions <ApplicationOptions> >();
                var cache   = serviceProvider.GetService <IMemoryCache>();

                var rootDirectory        = options?.Value?.ShapeConfiguration.ShapeSystemRootDirectory;
                string shapeFileNamePath = Path.Combine(rootDirectory, shapeProperties.Directory, shapeProperties.FileName);

                return(new CachedShapefileDataReader(cache, key, shapeFileNamePath));
            });

            // Feature Service Lookups
            services.AddScoped <BoroughBoundariesService>();
            services.AddScoped <CommunityDistrictsService>();
            services.AddScoped <DSNYDistrictsService>();
            services.AddScoped <HistoricDistrictService>();
            services.AddScoped <NeighborhoodsService <NeighborhoodShape> >();
            services.AddScoped <NeighborhoodTabulationAreasService>();
            services.AddScoped <NypdPolicePrecinctService>();
            services.AddScoped <NypdSectorsService <NypdSectorShape> >();
            services.AddScoped <NychaDevelopmentService <NychaDevelopmentShape> >();
            services.AddScoped <ParkService <ParkShape> >();
            services.AddScoped <SubwayService <SubwayShape> >();
            services.AddScoped <ZipCodeService <ZipCodeShape> >();

            services.AddScoped <ShapeServiceResolver>(serviceProvider => key =>
            {
                return(key switch
                {
                    nameof(ShapeProperties.BoroughBoundaries) => serviceProvider.GetService <BoroughBoundariesService>(),
                    nameof(ShapeProperties.CommunityDistricts) => serviceProvider.GetService <CommunityDistrictsService>(),
                    nameof(ShapeProperties.DSNYDistricts) => serviceProvider.GetService <DSNYDistrictsService>(),
                    nameof(ShapeProperties.HistoricDistricts) => serviceProvider.GetService <HistoricDistrictService>(),
                    nameof(ShapeProperties.Neighborhoods) => serviceProvider.GetService <NeighborhoodsService <NeighborhoodShape> >(),
                    nameof(ShapeProperties.NeighborhoodTabulationAreas) => serviceProvider.GetService <NeighborhoodTabulationAreasService>(),
                    nameof(ShapeProperties.NypdPolicePrecincts) => serviceProvider.GetService <NypdPolicePrecinctService>(),
                    nameof(ShapeProperties.NypdSectors) => serviceProvider.GetService <NypdSectorsService <NypdSectorShape> >(),
                    nameof(ShapeProperties.NychaDevelopments) => serviceProvider.GetService <NychaDevelopmentService <NychaDevelopmentShape> >(),
                    nameof(ShapeProperties.Parks) => serviceProvider.GetService <ParkService <ParkShape> >(),
                    nameof(ShapeProperties.Subway) => serviceProvider.GetService <SubwayService <SubwayShape> >(),
                    nameof(ShapeProperties.ZipCodes) => serviceProvider.GetService <ZipCodeService <ZipCodeShape> >(),
                    _ => throw new KeyNotFoundException(key)
                });
            });