public PerformanceLogOutput(PerformanceItemsList storage)
 {
     _storage = storage;
 }
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            BusinessEventsList   businessEventsList   = new BusinessEventsList();
            PerformanceItemsList performanceItemsList = new PerformanceItemsList();

            #region Logger Config

            // create and initialize logger for business events. We are using custom BusinessEvent class to store event's data
            var businessEventsLogger = LoggerFactory.Create <BusinessEvent>()
                                       .BindToWindsor(_container.Kernel)
                                       // logs will be written into businessEventsList collection
                                       .WriteTo(new BusinessEventLogOutput(businessEventsList));

            // Log event when user click "Enable cyclic api caller" button and controller's method would not throw exception
            // With event we want to store current time and user's name from current context
            // --- Plecase check .AsBusinessEvent extensions method implementation
            businessEventsLogger.LogInvocationOf <HomeController>(t => t.EnableCyclicApiCaller())
            .AsBusinessEvent("EnableCyclicApiCallerClickedEvent");

            // same as above but with "Disable cyclic api caller" button
            businessEventsLogger.LogInvocationOf <HomeController>(t => t.DisableCyclicApiCaller())
            .AsBusinessEvent("DisableCyclicApiCallerClickedEvent");

            // Log event when user send a form
            businessEventsLogger.LogInvocationOf <HomeController>(t => t.SendSomeForm(Input.Param <FormData>("model")))
            // Same as above but name of the event depends on selected radiobutton option
            .AsBusinessEvent((container, invocationData) =>
            {
                switch (invocationData.Arguments.Get <FormData>("model").FormType)
                {
                case FormType.SimpleForm:
                    return("SimpleFormSentEvent");

                case FormType.AdvancedForm:
                    return("AdvancedFormSendEvent");

                default:
                    return(null);
                }
            })
            // Also, we don't want log event if user select "FormABC" option
            .OnCondition((container, data) => data.Arguments.Get <FormData>("model").FormType != FormType.FormABC)
            // Except of standard event data (UserName and time of occurence) we want to log given formTitle
            .WithAdditionalData((container, data) => data.Arguments.Get <FormData>("model").Title, "FormTitle")
            // and url referrer
            .WithAdditionalData((container, data) => ((Controller)data.Raw.Target).Request.UrlReferrer, "UrlReferrer");

            // create and initialize logger for performance monitor. We are using DictionaryLogData supplied by MethodInvocationLogger.Extensions.
            var performanceLogger = LoggerFactory.Create <DictionaryLogData>()
                                    .BindToWindsor(_container.Kernel)
                                    .WriteTo(new PerformanceLogOutput(performanceItemsList)); // logs will be written into performanceItemsList collection

            // log every execution of PutSomeData method in SomeApiClient
            performanceLogger.LogInvocationOf <SomeApiClient>(t => t.PutSomeData(Input.Param <string>(), Input.Param <Data>()))
            .WithInvocationTime()                                                                // log time of the exection
            .WithExecutionDuration()                                                             // log duration of execution
            .WithAllArguments()                                                                  // log every argument of the method
            .WithMethodName()                                                                    // log method name
            .WithAdditionalData <int, IUserContext>((context, data) => context.UserId, "UserId") // log userId from current user context
            .WithExceptionIfThrown();                                                            // log full exception if method failed

            // here we are logging every execution of GetSomeData method with same additional values as above, but we use
            // one single configuration method "WithEverythingNecessaryForPerformanceMonitor" (please check its implementation)
            performanceLogger.LogInvocationOf <SomeApiClient>(t => t.GetSomeData())
            .WithEverythingNecessaryForPerformanceMonitor()
            .WithReturnedValue();                     // and method's returned value

            #endregion


            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container));
            _container.Register(Classes.FromThisAssembly().BasedOn <IController>().LifestyleTransient());

            _container.Register(
                Component.For <IUserContext>().ImplementedBy <UserContext>(),
                Component.For <BusinessEventsList>().Instance(businessEventsList),
                Component.For <PerformanceItemsList>().Instance(performanceItemsList),
                Component.For <IUserNameRetriever>().ImplementedBy <UserNameRetriever>().LifestyleSingleton(),
                Component.For <ISomeApiClient>().ImplementedBy <SomeApiClient>().LifestyleSingleton(),
                Component.For <CyclicApiCaller>().ImplementedBy <CyclicApiCaller>().LifestyleSingleton()
                );

            // Additional validation to check if everything is configured properly
            businessEventsLogger.Validate(_container.Kernel);
            performanceLogger.Validate(_container.Kernel);
        }