Exemple #1
0
        private static ApplicationInsightsConfiguration InitializeApplicationInsights(RefreshableConfiguration configuration)
        {
            var instrumentationKey       = configuration.Root.GetValue <string>("ApplicationInsights_InstrumentationKey");
            var heartbeatIntervalSeconds = configuration.Root.GetValue("ApplicationInsights_HeartbeatIntervalSeconds", 60);

            var applicationInsightsConfiguration = ApplicationInsights.Initialize(
                instrumentationKey,
                TimeSpan.FromSeconds(heartbeatIntervalSeconds));

            applicationInsightsConfiguration.TelemetryConfiguration.TelemetryInitializers.Add(new AzureWebAppTelemetryInitializer());
            applicationInsightsConfiguration.TelemetryConfiguration.TelemetryInitializers.Add(new KnownOperationNameEnricher(new[]
            {
                GetOperationName <SearchController>(HttpMethod.Get, nameof(SearchController.AutocompleteAsync)),
                GetOperationName <SearchController>(HttpMethod.Get, nameof(SearchController.IndexAsync)),
                GetOperationName <SearchController>(HttpMethod.Get, nameof(SearchController.GetStatusAsync)),
                GetOperationName <SearchController>(HttpMethod.Get, nameof(SearchController.V2SearchAsync)),
                GetOperationName <SearchController>(HttpMethod.Get, nameof(SearchController.V3SearchAsync)),
            }));

            applicationInsightsConfiguration.TelemetryConfiguration.TelemetryProcessorChainBuilder.Use(next =>
            {
                var processor = new RequestTelemetryProcessor(next);

                processor.SuccessfulResponseCodes.Add(400);
                processor.SuccessfulResponseCodes.Add(403);
                processor.SuccessfulResponseCodes.Add(404);
                processor.SuccessfulResponseCodes.Add(405);

                return(processor);
            });

            RegisterApplicationInsightsTelemetryModules(applicationInsightsConfiguration.TelemetryConfiguration);

            return(applicationInsightsConfiguration);
        }
Exemple #2
0
 public SearchRequestTelemetryProcessor(ITelemetryProcessor nextProcessor)
 {
     _next = new RequestTelemetryProcessor(nextProcessor);
     _next.SuccessfulResponseCodes.Add(400);
     _next.SuccessfulResponseCodes.Add(403);
     _next.SuccessfulResponseCodes.Add(404);
     _next.SuccessfulResponseCodes.Add(405);
 }
Exemple #3
0
        // This method is auto-detected by the OWIN pipeline. DO NOT RENAME IT!
        public static void Configuration(IAppBuilder app)
        {
            // Tune ServicePointManager
            // (based on http://social.technet.microsoft.com/Forums/en-US/windowsazuredata/thread/d84ba34b-b0e0-4961-a167-bbe7618beb83 and https://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.aspx)
            ServicePointManager.DefaultConnectionLimit = 500;
            ServicePointManager.UseNagleAlgorithm      = false;
            ServicePointManager.Expect100Continue      = false;

            // Ensure that SSLv3 is disabled and that Tls v1.2 is enabled.
            ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
            ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

            // Setting time out for all RegEx objects. Noted in remarks at https://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.matchtimeout%28v=vs.110%29.aspx
            AppDomain.CurrentDomain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT", TimeSpan.FromSeconds(10));

            // Register IoC
            app.UseAutofacInjection(GlobalConfiguration.Configuration);
            var dependencyResolver = DependencyResolver.Current;

            // Register Elmah
            var elmahServiceCenter = new DependencyResolverServiceProviderAdapter(dependencyResolver);

            ServiceCenter.Current = _ => elmahServiceCenter;

            // Get config
            var config = dependencyResolver.GetService <IGalleryConfigurationService>();
            var auth   = dependencyResolver.GetService <AuthenticationService>();

            // Configure machine key for session persistence across slots
            SessionPersistence.Setup(config);
            // Refresh the content for the ContentObjectService to guarantee it has loaded the latest configuration on startup.
            var contentObjectService = dependencyResolver.GetService <IContentObjectService>();

            HostingEnvironment.QueueBackgroundWorkItem(async token =>
            {
                while (!token.IsCancellationRequested)
                {
                    await contentObjectService.Refresh();
                    await Task.Delay(ContentObjectService.RefreshInterval, token);
                }
            });

            // Setup telemetry
            var instrumentationKey = config.Current.AppInsightsInstrumentationKey;

            if (!string.IsNullOrEmpty(instrumentationKey))
            {
                TelemetryConfiguration.Active.InstrumentationKey = instrumentationKey;

                // Add enrichers
                TelemetryConfiguration.Active.TelemetryInitializers.Add(new ClientInformationTelemetryEnricher());

                var telemetryProcessorChainBuilder = TelemetryConfiguration.Active.TelemetryProcessorChainBuilder;

                // Add processors
                telemetryProcessorChainBuilder.Use(next =>
                {
                    var processor = new RequestTelemetryProcessor(next);

                    processor.SuccessfulResponseCodes.Add(400);
                    processor.SuccessfulResponseCodes.Add(404);

                    return(processor);
                });

                telemetryProcessorChainBuilder.Use(next => new ClientTelemetryPIIProcessor(next));

                var telemetry = dependencyResolver.GetService <TelemetryClientWrapper>();
                telemetryProcessorChainBuilder.Use(
                    next => new ExceptionTelemetryProcessor(next, telemetry.UnderlyingClient));

                // Note: sampling rate must be a factor 100/N where N is a whole number
                // e.g.: 50 (= 100/2), 33.33 (= 100/3), 25 (= 100/4), ...
                // https://azure.microsoft.com/en-us/documentation/articles/app-insights-sampling/
                var instrumentationSamplingPercentage = config.Current.AppInsightsSamplingPercentage;
                if (instrumentationSamplingPercentage > 0 && instrumentationSamplingPercentage < 100)
                {
                    telemetryProcessorChainBuilder.UseSampling(instrumentationSamplingPercentage);
                }

                telemetryProcessorChainBuilder.Build();
            }

            // Configure logging
            app.SetLoggerFactory(new DiagnosticsLoggerFactory());

            // Remove X-AspNetMvc-Version header
            MvcHandler.DisableMvcResponseHeader = true;

            if (config.Current.RequireSSL)
            {
                // Put a middleware at the top of the stack to force the user over to SSL
                if (config.Current.ForceSslExclusion == null)
                {
                    app.UseForceSsl(config.Current.SSLPort);
                }
                else
                {
                    app.UseForceSsl(config.Current.SSLPort, config.Current.ForceSslExclusion);
                }
            }

            // Get the local user auth provider, if present and attach it first
            Authenticator localUserAuthenticator;

            if (auth.Authenticators.TryGetValue(Authenticator.GetName(typeof(LocalUserAuthenticator)), out localUserAuthenticator))
            {
                // Configure cookie auth now
                localUserAuthenticator.Startup(config, app).Wait();
            }

            // Attach external sign-in cookie middleware
            app.SetDefaultSignInAsAuthenticationType(AuthenticationTypes.External);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = AuthenticationTypes.External,
                AuthenticationMode = AuthenticationMode.Passive,
                CookieName         = ".AspNet." + AuthenticationTypes.External,
                ExpireTimeSpan     = TimeSpan.FromMinutes(5)
            });

            // Attach non-cookie auth providers
            var nonCookieAuthers = auth
                                   .Authenticators
                                   .Where(p => !String.Equals(
                                              p.Key,
                                              Authenticator.GetName(typeof(LocalUserAuthenticator)),
                                              StringComparison.OrdinalIgnoreCase))
                                   .Select(p => p.Value);

            foreach (var auther in nonCookieAuthers)
            {
                auther.Startup(config, app).Wait();
            }

            // Catch unobserved exceptions from threads before they cause IIS to crash:
            TaskScheduler.UnobservedTaskException += (sender, exArgs) =>
            {
                // Send to AppInsights
                try
                {
                    var telemetryClient = new TelemetryClient();
                    telemetryClient.TrackException(exArgs.Exception, new Dictionary <string, string>()
                    {
                        { "ExceptionOrigin", "UnobservedTaskException" }
                    });
                }
                catch (Exception)
                {
                    // this is a tragic moment... swallow Exception to prevent crashing IIS
                }

                // Send to ELMAH
                try
                {
                    HttpContext current = HttpContext.Current;
                    if (current != null)
                    {
                        var errorSignal = ErrorSignal.FromContext(current);
                        if (errorSignal != null)
                        {
                            errorSignal.Raise(exArgs.Exception, current);
                        }
                    }
                }
                catch (Exception)
                {
                    // more tragedy... swallow Exception to prevent crashing IIS
                }

                exArgs.SetObserved();
            };

            HasRun = true;
        }
Exemple #4
0
        public void Configuration(IAppBuilder app, IConfigurationFactory configFactory, Directory directory,
                                  ILoader loader)
        {
            _configFactory = configFactory;
            var config = _configFactory.Get <BasicSearchConfiguration>().Result;

            // Configure
            if (!string.IsNullOrEmpty(config.ApplicationInsightsInstrumentationKey))
            {
                TelemetryConfiguration.Active.InstrumentationKey = config.ApplicationInsightsInstrumentationKey;
            }

            // Add telemetry initializers
            TelemetryConfiguration.Active.TelemetryInitializers.Add(new MachineNameTelemetryInitializer());
            TelemetryConfiguration.Active.TelemetryInitializers.Add(new DeploymentIdTelemetryInitializer());

            // Create telemetry sink
            _searchTelemetryClient = new SearchTelemetryClient();

            // Add telemetry processors
            var processorChain = TelemetryConfiguration.Active.TelemetryProcessorChainBuilder;

            processorChain.Use(next =>
            {
                var processor = new RequestTelemetryProcessor(next);

                processor.SuccessfulResponseCodes.Add(400);
                processor.SuccessfulResponseCodes.Add(404);

                return(processor);
            });

            processorChain.Use(next => new ExceptionTelemetryProcessor(next, _searchTelemetryClient.TelemetryClient));

            processorChain.Build();

            // Create an ILoggerFactory
            var loggerConfiguration = LoggingSetup.CreateDefaultLoggerConfiguration(withConsoleLogger: false)
                                      .Enrich.With <HttpRequestIdEnricher>()
                                      .Enrich.With <HttpRequestTraceIdEnricher>()
                                      .Enrich.With <HttpRequestTypeEnricher>()
                                      .Enrich.With <HttpRequestUrlReferrerEnricher>()
                                      .Enrich.With <HttpRequestUserAgentEnricher>()
                                      .Enrich.With <HttpRequestRawUrlEnricher>();

            var loggerFactory = LoggingSetup.CreateLoggerFactory(loggerConfiguration);

            // Create a logger that is scoped to this class (only)
            _logger = loggerFactory.CreateLogger <Startup>();

            _logger.LogInformation(LogMessages.AppStartup);

            // Overwrite the index's Azure Directory cache path if configured ot use an Azure Local Storage resource.
            if (!string.IsNullOrEmpty(config.AzureDirectoryCacheLocalResourceName))
            {
                if (SafeRoleEnvironment.TryGetLocalResourceRootPath(config.AzureDirectoryCacheLocalResourceName, out var path))
                {
                    config.AzureDirectoryCachePath = path;

                    _logger.LogInformation(
                        "Set Azure Directory cache path to Azure Local Resource = {LocalResourceName}, Path = {LocalResourcePath}",
                        config.AzureDirectoryCacheLocalResourceName,
                        config.AzureDirectoryCachePath);
                }
                else
                {
                    _logger.LogWarning(
                        "Cannot use Azure Local Resource {LocalResourceName} for caching when the RoleEnvironment is not available",
                        config.AzureDirectoryCacheLocalResourceName);
                }
            }

            // redirect all HTTP requests to HTTPS
            if (config.RequireSsl)
            {
                if (string.IsNullOrWhiteSpace(config.ForceSslExclusion))
                {
                    app.UseForceSsl(config.SslPort);
                }
                else
                {
                    app.UseForceSsl(config.SslPort, new[] { config.ForceSslExclusion });
                }
            }

            // Correlate requests
            app.Use(typeof(CorrelationIdMiddleware));

            // Add Application Insights
            app.Use(typeof(RequestTrackingMiddleware));

            // Set up exception logging
            app.Use(typeof(ExceptionTrackingMiddleware));

            // Enable HSTS
            app.Use(async(context, next) =>
            {
                context.Response.Headers.Add("Strict-Transport-Security", new string[] { "max-age=31536000; includeSubDomains" });
                await next.Invoke();
            });

            // Disable content type sniffing
            app.Use(async(context, next) =>
            {
                context.Response.Headers.Add("X-Content-Type-Options", new[] { "nosniff" });
                await next.Invoke();
            });

            // Enable CORS
            var corsPolicy = new CorsPolicy
            {
                Methods         = { "GET", "HEAD", "OPTIONS" },
                Headers         = { "Content-Type", "If-Match", "If-Modified-Since", "If-None-Match", "If-Unmodified-Since", "Accept-Encoding" },
                ExposedHeaders  = { "Content-Type", "Content-Length", "Last-Modified", "Transfer-Encoding", "ETag", "Date", "Vary", "Server", "X-Hit", "X-CorrelationId" },
                AllowAnyOrigin  = true,
                PreflightMaxAge = 3600
            };

            app.UseCors(new CorsOptions
            {
                PolicyProvider = new CorsPolicyProvider
                {
                    PolicyResolver = context => Task.FromResult(corsPolicy)
                }
            });

            // Search test console
            app.Use(typeof(SearchConsoleMiddleware));
            app.UseStaticFiles(new StaticFileOptions(new SharedOptions
            {
                RequestPath = new PathString("/console"),
                FileSystem  = new EmbeddedResourceFileSystem(typeof(Startup).Assembly, "NuGet.Services.BasicSearch.Console")
            }));

            // Start the service running - the Lucene index needs to be reopened regularly on a background thread
            var intervalSec = config.IndexRefreshSec;

            _logger.LogInformation(LogMessages.SearchIndexRefreshConfiguration, intervalSec);

            if (InitializeSearcherManager(config, directory, loader, loggerFactory))
            {
                var intervalMs = intervalSec * 1000;

                _gate             = 0;
                _indexReloadTimer = new Timer(ReopenCallback, 0, intervalMs, intervalMs);
            }

            _responseWriter = new ResponseWriter();

            app.Run(InvokeAsync);
        }
        // This method is auto-detected by the OWIN pipeline. DO NOT RENAME IT!
        public static void Configuration(IAppBuilder app)
        {
            // Tune ServicePointManager
            // (based on http://social.technet.microsoft.com/Forums/en-US/windowsazuredata/thread/d84ba34b-b0e0-4961-a167-bbe7618beb83 and https://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.aspx)
            ServicePointManager.DefaultConnectionLimit = 500;
            ServicePointManager.UseNagleAlgorithm      = false;
            ServicePointManager.Expect100Continue      = false;

            // Register IoC
            app.UseAutofacInjection(GlobalConfiguration.Configuration);
            var dependencyResolver = DependencyResolver.Current;

            // Register Elmah
            var elmahServiceCenter = new DependencyResolverServiceProviderAdapter(dependencyResolver);

            ServiceCenter.Current = _ => elmahServiceCenter;

            // Get config
            var config = dependencyResolver.GetService <IGalleryConfigurationService>();
            var auth   = dependencyResolver.GetService <AuthenticationService>();

            // Setup telemetry
            var instrumentationKey = config.Current.AppInsightsInstrumentationKey;

            if (!string.IsNullOrEmpty(instrumentationKey))
            {
                TelemetryConfiguration.Active.InstrumentationKey = instrumentationKey;

                // Add enrichers
                TelemetryConfiguration.Active.TelemetryInitializers.Add(new ClientInformationTelemetryEnricher());

                var telemetryProcessorChainBuilder = TelemetryConfiguration.Active.TelemetryProcessorChainBuilder;

                // Add processors
                telemetryProcessorChainBuilder.Use(next =>
                {
                    var processor = new RequestTelemetryProcessor(next);

                    processor.SuccessfulResponseCodes.Add(400);
                    processor.SuccessfulResponseCodes.Add(404);

                    return(processor);
                });

                telemetryProcessorChainBuilder.Use(
                    next => new ExceptionTelemetryProcessor(next, Telemetry.TelemetryClient));

                // Note: sampling rate must be a factor 100/N where N is a whole number
                // e.g.: 50 (= 100/2), 33.33 (= 100/3), 25 (= 100/4), ...
                // https://azure.microsoft.com/en-us/documentation/articles/app-insights-sampling/
                var instrumentationSamplingPercentage = config.Current.AppInsightsSamplingPercentage;
                if (instrumentationSamplingPercentage > 0 && instrumentationSamplingPercentage < 100)
                {
                    telemetryProcessorChainBuilder.UseSampling(instrumentationSamplingPercentage);
                }

                telemetryProcessorChainBuilder.Build();
            }

            // Configure logging
            app.SetLoggerFactory(new DiagnosticsLoggerFactory());

            // Remove X-AspNetMvc-Version header
            MvcHandler.DisableMvcResponseHeader = true;

            if (config.Current.RequireSSL)
            {
                // Put a middleware at the top of the stack to force the user over to SSL
                // if authenticated.
                app.UseForceSslWhenAuthenticated(config.Current.SSLPort);
            }

            // Get the local user auth provider, if present and attach it first
            Authenticator localUserAuthenticator;

            if (auth.Authenticators.TryGetValue(Authenticator.GetName(typeof(LocalUserAuthenticator)), out localUserAuthenticator))
            {
                // Configure cookie auth now
                localUserAuthenticator.Startup(config, app).Wait();
            }

            // Attach external sign-in cookie middleware
            app.SetDefaultSignInAsAuthenticationType(AuthenticationTypes.External);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = AuthenticationTypes.External,
                AuthenticationMode = AuthenticationMode.Passive,
                CookieName         = ".AspNet." + AuthenticationTypes.External,
                ExpireTimeSpan     = TimeSpan.FromMinutes(5)
            });

            // Attach non-cookie auth providers
            var nonCookieAuthers = auth
                                   .Authenticators
                                   .Where(p => !String.Equals(
                                              p.Key,
                                              Authenticator.GetName(typeof(LocalUserAuthenticator)),
                                              StringComparison.OrdinalIgnoreCase))
                                   .Select(p => p.Value);

            foreach (var auther in nonCookieAuthers)
            {
                auther.Startup(config, app).Wait();
            }

            // Catch unobserved exceptions from threads before they cause IIS to crash:
            TaskScheduler.UnobservedTaskException += (sender, exArgs) =>
            {
                // Send to AppInsights
                try
                {
                    var telemetryClient = new TelemetryClient();
                    telemetryClient.TrackException(exArgs.Exception, new Dictionary <string, string>()
                    {
                        { "ExceptionOrigin", "UnobservedTaskException" }
                    });
                }
                catch (Exception)
                {
                    // this is a tragic moment... swallow Exception to prevent crashing IIS
                }

                // Send to ELMAH
                try
                {
                    HttpContext current = HttpContext.Current;
                    if (current != null)
                    {
                        var errorSignal = ErrorSignal.FromContext(current);
                        if (errorSignal != null)
                        {
                            errorSignal.Raise(exArgs.Exception, current);
                        }
                    }
                }
                catch (Exception)
                {
                    // more tragedy... swallow Exception to prevent crashing IIS
                }

                exArgs.SetObserved();
            };

            HasRun = true;
        }