Ejemplo n.º 1
0
 public override XmlDocument Load(XmlDocument xDoc, params string[] filenames)
 {
     if (filenames.Length == 0)
     {
         using (ServerManager serverManager = String.IsNullOrWhiteSpace(ServerName) ? new ServerManager() : ServerManager.OpenRemote(ServerName))
         {
             List <string> logFiles = new List <string>();
             foreach (string siteName in SiteNames)
             {
                 Site site = serverManager.Sites[siteName];
                 if (site != null)
                 {
                     SiteLogFile siteLogFile = site.LogFile;
                     foreach (string logFileName in Directory.EnumerateFiles(siteLogFile.Directory, "*.log", SearchOption.TopDirectoryOnly))
                     {
                         if ((StartDate.HasValue) && (StartDate.Value <= File.GetCreationTime(logFileName)) &&
                             (EndDate.HasValue) && (EndDate.Value >= File.GetLastWriteTime(logFileName)))
                         {
                             logFiles.Add(logFileName);
                         }
                     }
                 }
             }
         }
     }
     return((filenames.Length > 0) ? base.Load(xDoc, filenames) : xDoc);
 }
Ejemplo n.º 2
0
        internal void SelectFields()
        {
            var         service = (IConfigurationService)GetService(typeof(IConfigurationService));
            SiteLogFile element;

            if (service.Server != null)
            {
                var section2 = service.GetSection("system.applicationHost/sites");
                var parent   = section2.ChildElements["siteDefaults"];
                element = new SiteLogFile(parent.ChildElements["logFile"], parent);
            }
            else
            {
                element = service.Application.GetSite().LogFile;
            }

            var dialog = new FieldsDialog(Module, element);

            if (dialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            service.ServerManager.CommitChanges();
        }
Ejemplo n.º 3
0
        public Fields(SiteLogFile file)
        {
            Element         = file;
            CustomLogFields = new List <CustomLogField>();
            foreach (CustomLogField item in file.CustomLogFields)
            {
                CustomLogFields.Add(item);
            }

            LogExtFileFlags = file.LogExtFileFlags;
        }
        private static void TrySetLoggingEnabled(bool value, HttpLoggingSection httpLoggingSection, LogSection logSection, SiteLogFile siteLogFile, Site site, string configScope = null)
        {
            //
            // Logging is configurable only at server and site level

            if (site == null)
            {
                httpLoggingSection.DontLog = !value;

                logSection.CentralW3CLogFile.Enabled    = value;
                logSection.CentralBinaryLogFile.Enabled = value;
            }
            else
            {
                if (httpLoggingSection.IsLocked && (configScope == null || configScope != ManagementUnit.APP_HOST_CONFIG_SCOPE))
                {
                    if (value && httpLoggingSection.DontLog)
                    {
                        throw new LockedException("enabled");
                    }
                }
                else
                {
                    httpLoggingSection.DontLog = !value;
                }

                siteLogFile.Enabled = value;
            }
        }
        private static bool IsLoggingEnabled(HttpLoggingSection httpLoggingSection, LogSection logSection, SiteLogFile siteLogFile)
        {
            CentralLogFileMode mode = logSection.CentralLogFileMode;

            bool modeEnabled = false;

            switch (mode)
            {
            case CentralLogFileMode.CentralBinary:
                modeEnabled = logSection.CentralBinaryLogFile.Enabled;
                break;

            case CentralLogFileMode.CentralW3C:
                modeEnabled = logSection.CentralW3CLogFile.Enabled;
                break;

            case CentralLogFileMode.Site:
                modeEnabled = siteLogFile.Enabled;
                break;

            default:
                break;
            }

            return(modeEnabled && !httpLoggingSection.DontLog);
        }
        internal static object ToJsonModel(Site site, string path)
        {
            LogSection         logSection     = GetLogSection(site, path);
            HttpLoggingSection httpLogSection = GetHttpLoggingSection(site, path);

            SiteLogFile logFile = null;

            if (site == null)
            {
                logFile = ManagementUnit.Current.ServerManager.SiteDefaults.LogFile;
            }
            else
            {
                logFile = site.LogFile;
            }

            LoggingId id = new LoggingId(site?.Id, path, httpLogSection.IsLocallyStored);

            Dictionary <string, bool> logTargetW3C = new Dictionary <string, bool>();

            if (logFile.Schema.HasAttribute(LogTargetW3CAttribute))
            {
                LogTargetW3C target = logFile.LogTargetW3C;

                logTargetW3C.Add("etw", target.HasFlag(LogTargetW3C.ETW));
                logTargetW3C.Add("file", target.HasFlag(LogTargetW3C.File));
            }

            FileLogFormat logFormat;

            if (logSection.CentralLogFileMode == CentralLogFileMode.Site)
            {
                logFormat = FromLogFormat(logFile.LogFormat);
            }
            else
            {
                logFormat = logSection.CentralLogFileMode == CentralLogFileMode.CentralBinary ? FileLogFormat.Binary : FileLogFormat.W3c;
            }


            bool logFilePerSite = logSection.CentralLogFileMode == CentralLogFileMode.Site;

            string directory    = default(string);
            string period       = default(string);
            long   truncateSize = default(long);
            bool   useLocalTime = default(bool);
            Dictionary <string, bool> logTargetW3c    = default(Dictionary <string, bool>);
            Dictionary <string, bool> logFields       = default(Dictionary <string, bool>);
            IEnumerable <object>      customLogFields = default(IEnumerable <object>);

            switch (logSection.CentralLogFileMode)
            {
            case CentralLogFileMode.CentralBinary:

                directory       = logSection.CentralBinaryLogFile.Directory;
                period          = PeriodRepresentation(logSection.CentralBinaryLogFile.Period);
                truncateSize    = logSection.CentralBinaryLogFile.TruncateSize;
                useLocalTime    = logSection.CentralBinaryLogFile.LocalTimeRollover;
                logTargetW3c    = null;
                logFields       = null;
                customLogFields = null;
                break;

            case CentralLogFileMode.CentralW3C:

                directory       = logSection.CentralW3CLogFile.Directory;
                period          = PeriodRepresentation(logSection.CentralW3CLogFile.Period);
                truncateSize    = logSection.CentralW3CLogFile.TruncateSize;
                useLocalTime    = logSection.CentralW3CLogFile.LocalTimeRollover;
                logTargetW3c    = null;
                logFields       = LogExtFileFlagsRepresentation(logSection.CentralW3CLogFile.LogExtFileFlags);
                customLogFields = null;

                break;

            case CentralLogFileMode.Site:

                directory    = logFile.Directory;
                period       = PeriodRepresentation(logFile.Period);
                truncateSize = logFile.TruncateSize;
                useLocalTime = logFile.LocalTimeRollover;
                logTargetW3c = logTargetW3C;
                logFields    = LogExtFileFlagsRepresentation(logFile.LogExtFileFlags);

                if (logFile.Schema.HasChildElement(CustomFieldsElement))
                {
                    customLogFields = logFile.CustomLogFields.Select(custField => {
                        return(new
                        {
                            field_name = custField.LogFieldName,
                            source_name = custField.SourceName,
                            source_type = SourceTypeRepresentation(custField.SourceType)
                        });
                    });
                }

                break;
            }

            dynamic o = new ExpandoObject();

            o.id    = id.Uuid;
            o.scope = site == null ? string.Empty : site.Name + path;

            // The metadata is obtained solely from <httpLogSection> because the <log> section is in applicationHost/* path which means it can't be accessed in web configs
            o.metadata = ConfigurationUtility.MetadataToJson(httpLogSection.IsLocallyStored, httpLogSection.IsLocked, httpLogSection.OverrideMode, httpLogSection.OverrideModeEffective);

            o.enabled      = IsLoggingEnabled(httpLogSection, logSection, logFile);
            o.log_per_site = logFilePerSite;

            o.directory         = directory;
            o.log_file_encoding = logSection.LogInUTF8 ? "utf-8" : "ansi";
            o.log_file_format   = Enum.GetName(typeof(FileLogFormat), logFormat).ToLower();

            if (logFile.Schema.HasAttribute(LogTargetW3CAttribute))
            {
                o.log_target = logTargetW3c;
            }

            o.log_fields = logFields;

            if (logFile.Schema.HasChildElement(CustomFieldsElement))
            {
                o.custom_log_fields = customLogFields;
            }

            o.rollover = new
            {
                period         = period,
                truncate_size  = truncateSize,
                use_local_time = useLocalTime,
            };

            o.website = SiteHelper.ToJsonModelRef(site);

            return(Core.Environment.Hal.Apply(Defines.Resource.Guid, o));
        }
        public static void Update(dynamic model, Site site, string path, string configScope = null)
        {
            if (model == null)
            {
                throw new ApiArgumentException("model");
            }

            // Cannot configure at any path below site
            if (site != null && path != "/")
            {
                throw new InvalidScopeTypeException(string.Format("{0}{1}", (site == null ? "" : site.Name), path ?? ""));
            }

            LogSection         logSection         = GetLogSection(site, path, configScope);
            HttpLoggingSection httpLoggingSection = GetHttpLoggingSection(site, path, configScope);

            // Site log settings are set in the site defaults if Configuration target is server
            // If target is a site then the site's logfile element is used
            SiteLogFile siteLogFile = site == null ? ManagementUnit.Current.ServerManager.SiteDefaults.LogFile : site.LogFile;

            try {
                bool?enabled = DynamicHelper.To <bool>(model.enabled);
                if (enabled != null)
                {
                    TrySetLoggingEnabled(enabled.Value, httpLoggingSection, logSection, siteLogFile, site, configScope);
                }

                // Extract rollover from model
                dynamic rollover = model.rollover;
                if (rollover != null && !(rollover is JObject))
                {
                    throw new ApiArgumentException("rollover", ApiArgumentException.EXPECTED_OBJECT);
                }

                // Only accessible at server level
                if (site == null)
                {
                    DynamicHelper.If <bool>((object)model.log_per_site, v => logSection.CentralLogFileMode = v ? CentralLogFileMode.Site : CentralLogFileMode.CentralW3C);
                    DynamicHelper.If <FileLogFormat>((object)model.log_file_format, v => {
                        // Site log mode exposes 4 possible log formats
                        if (logSection.CentralLogFileMode == CentralLogFileMode.Site)
                        {
                            switch (v)
                            {
                            case FileLogFormat.Custom:
                                siteLogFile.LogFormat = LogFormat.Custom;
                                break;

                            case FileLogFormat.Iis:
                                siteLogFile.LogFormat = LogFormat.Iis;
                                break;

                            case FileLogFormat.W3c:
                                siteLogFile.LogFormat = LogFormat.W3c;
                                break;

                            case FileLogFormat.Ncsa:
                                siteLogFile.LogFormat = LogFormat.Ncsa;
                                break;

                            default:
                                throw new ApiArgumentException("log_file_format");
                            }
                        }
                        // Server log mode exposes 2 possible log formats
                        else
                        {
                            switch (v)
                            {
                            case FileLogFormat.W3c:
                                logSection.CentralLogFileMode = CentralLogFileMode.CentralW3C;
                                break;

                            case FileLogFormat.Binary:
                                logSection.CentralLogFileMode = CentralLogFileMode.CentralBinary;
                                break;

                            default:
                                throw new ApiArgumentException("log_file_format");
                            }
                        }
                    });
                    DynamicHelper.If((object)model.log_file_encoding, v => {
                        switch (v.ToLower())
                        {
                        case "utf-8":
                            logSection.LogInUTF8 = true;
                            break;

                        case "ansi":
                            logSection.LogInUTF8 = false;
                            break;

                        default:
                            throw new ApiArgumentException("log_file_encoding");
                        }
                    });

                    // Binary log mode settings
                    if (logSection.CentralLogFileMode == CentralLogFileMode.CentralBinary)
                    {
                        dynamic bSettings = model;


                        CentralBinaryLogFile bFile = logSection.CentralBinaryLogFile;

                        DynamicHelper.If((object)bSettings.directory, v => bFile.Directory = v);

                        if (rollover != null)
                        {
                            DynamicHelper.If <LoggingRolloverPeriod>((object)PeriodFromRepresentation(rollover.period), v => bFile.Period = v);
                            DynamicHelper.If((object)rollover.truncate_size, 1048576, 4294967295, v => bFile.TruncateSize = v);
                            DynamicHelper.If <bool>((object)rollover.use_local_time, v => bFile.LocalTimeRollover         = v);
                        }
                    }

                    // W3C log mode settings
                    if (logSection.CentralLogFileMode == CentralLogFileMode.CentralW3C)
                    {
                        dynamic wSettings = model;

                        CentralW3CLogFile wFile = logSection.CentralW3CLogFile;

                        DynamicHelper.If((object)wSettings.directory, v => wFile.Directory = v);

                        if (rollover != null)
                        {
                            DynamicHelper.If <LoggingRolloverPeriod>((object)PeriodFromRepresentation(rollover.period), v => wFile.Period = v);
                            DynamicHelper.If((object)rollover.truncate_size, 1048576, 4294967295, v => wFile.TruncateSize = v);
                            DynamicHelper.If <bool>((object)rollover.use_local_time, v => wFile.LocalTimeRollover         = v);
                        }

                        if (wSettings.log_fields != null)
                        {
                            try {
                                wFile.LogExtFileFlags = SetLogFieldFlags(wFile.LogExtFileFlags, wSettings.log_fields);
                            }
                            catch (ApiArgumentException e) {
                                throw new ApiArgumentException("w3c_settings.log_fields", e);
                            }
                            catch (JsonSerializationException e) {
                                throw new ApiArgumentException("w3c_settings.log_fields", e);
                            }
                        }
                    }
                }

                //
                // Per site mode format
                DynamicHelper.If <FileLogFormat>((object)model.log_file_format, v => {
                    if (logSection.CentralLogFileMode == CentralLogFileMode.Site)
                    {
                        switch (v)
                        {
                        case FileLogFormat.Custom:
                            siteLogFile.LogFormat = LogFormat.Custom;
                            break;

                        case FileLogFormat.Iis:
                            siteLogFile.LogFormat = LogFormat.Iis;
                            break;

                        case FileLogFormat.W3c:
                            siteLogFile.LogFormat = LogFormat.W3c;
                            break;

                        case FileLogFormat.Ncsa:
                            siteLogFile.LogFormat = LogFormat.Ncsa;
                            break;

                        default:
                            throw new ApiArgumentException("log_file_format");
                        }
                    }
                });

                // Site settings
                if (logSection.CentralLogFileMode == CentralLogFileMode.Site)
                {
                    dynamic siteSettings = model;

                    DynamicHelper.If((object)siteSettings.directory, v => siteLogFile.Directory = v);

                    if (rollover != null)
                    {
                        DynamicHelper.If <LoggingRolloverPeriod>((object)PeriodFromRepresentation(rollover.period), v => siteLogFile.Period = v);
                        DynamicHelper.If((object)rollover.truncate_size, 1048576, 4294967295, v => siteLogFile.TruncateSize = v);
                        DynamicHelper.If <bool>((object)rollover.use_local_time, v => siteLogFile.LocalTimeRollover         = v);
                    }

                    if (siteSettings.log_fields != null)
                    {
                        try {
                            siteLogFile.LogExtFileFlags = SetLogFieldFlags(siteLogFile.LogExtFileFlags, siteSettings.log_fields);
                        }
                        catch (ApiArgumentException e) {
                            throw new ApiArgumentException("site_settings.log_fields", e);
                        }
                        catch (JsonSerializationException e) {
                            throw new ApiArgumentException("site_settings.log_fields", e);
                        }
                    }

                    if (siteSettings.log_target != null && siteLogFile.Schema.HasAttribute(LogTargetW3CAttribute))
                    {
                        try {
                            Dictionary <string, bool> logTargets = JsonConvert.DeserializeObject <Dictionary <string, bool> >(siteSettings.log_target.ToString());

                            if (logTargets == null)
                            {
                                throw new ApiArgumentException("site_settings.log_target_w3c");
                            }

                            LogTargetW3C logTargetW3C = siteLogFile.LogTargetW3C;

                            if (logTargets.ContainsKey("etw"))
                            {
                                if (logTargets["etw"])
                                {
                                    logTargetW3C |= LogTargetW3C.ETW;
                                }
                                else
                                {
                                    logTargetW3C &= ~LogTargetW3C.ETW;
                                }
                            }
                            if (logTargets.ContainsKey("file"))
                            {
                                if (logTargets["file"])
                                {
                                    logTargetW3C |= LogTargetW3C.File;
                                }
                                else
                                {
                                    logTargetW3C &= ~LogTargetW3C.File;
                                }
                            }

                            siteLogFile.LogTargetW3C = logTargetW3C;
                        }
                        catch (JsonSerializationException e) {
                            throw new ApiArgumentException("site_settings.log_fields", e);
                        }
                    }

                    if (siteSettings.custom_log_fields != null && siteLogFile.Schema.HasChildElement(CustomFieldsElement))
                    {
                        IEnumerable <dynamic> customFields = siteSettings.custom_log_fields;

                        List <CustomField> tempCustFields = new List <CustomField>();

                        foreach (dynamic field in customFields)
                        {
                            string fieldName  = DynamicHelper.Value(field.field_name);
                            string sourceName = DynamicHelper.Value(field.source_name);
                            CustomLogFieldSourceType?sourceType = SourceTypeFromRepresentation(field.source_type);

                            if (string.IsNullOrEmpty(fieldName))
                            {
                                throw new ApiArgumentException("custom_log_field.field_name");
                            }
                            if (string.IsNullOrEmpty(sourceName))
                            {
                                throw new ApiArgumentException("custom_log_field.source_name");
                            }
                            if (sourceType == null)
                            {
                                throw new ApiArgumentException("custom_log_field.source_type");
                            }

                            tempCustFields.Add(new CustomField()
                            {
                                FieldName  = fieldName,
                                SourceName = sourceName,
                                SourceType = sourceType.Value
                            });
                        }

                        siteLogFile.CustomLogFields.Clear();
                        tempCustFields.ForEach(f => siteLogFile.CustomLogFields.Add(f.FieldName, f.SourceName, f.SourceType));
                    }
                }


                if (model.metadata != null)
                {
                    DynamicHelper.If <OverrideMode>((object)model.metadata.override_mode, v => httpLoggingSection.OverrideMode = v);
                }
            }
            catch (FileLoadException e) {
                throw new LockedException(logSection.SectionPath + "|" + httpLoggingSection.SectionPath, e);
            }
            catch (DirectoryNotFoundException e) {
                throw new ConfigScopeNotFoundException(e);
            }
        }
Ejemplo n.º 8
0
        public AddFieldDialog(IServiceProvider serviceProvider, CustomLogField custom, SiteLogFile logFile)
            : base(serviceProvider)
        {
            Custom = custom;
            InitializeComponent();
            if (custom != null)
            {
                txtName.Text         = custom.LogFieldName;
                cbType.SelectedIndex = (int)custom.SourceType;
                cbSource.Text        = custom.SourceName;
            }
            else
            {
                cbType.SelectedIndex = 0;
            }

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(txtName, "TextChanged")
                .Merge(Observable.FromEventPattern <EventArgs>(cbSource, "TextChanged"))
                .Sample(TimeSpan.FromSeconds(1))
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                btnOK.Enabled = !string.IsNullOrWhiteSpace(txtName.Text) && !string.IsNullOrWhiteSpace(cbSource.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(cbType, "SelectedIndexChanged")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                cbSource.Items.Clear();
                if (cbType.SelectedIndex == 0)
                {
                    cbSource.Items.AddRange(new object[]
                    {
                        "Accept",
                        "Accept_Charset",
                        "Accept_Encoding",
                        "Authorization",
                        "Cache-Control",
                        "Connection",
                        "Content-Length",
                        "Content-MD5",
                        "Content-Type",
                        "Date",
                        "Expect",
                        "From",
                        "Host",
                        "If-Match",
                        "If-Modified-Since",
                        "If-None-Match",
                        "If-Range",
                        "If-Unmodified-Since",
                        "Max-Forwards",
                        "Pragma",
                        "Proxy-Authorization",
                        "Range",
                        "Referer",
                        "TE",
                        "Upgrade",
                        "User-Agent",
                        "Via",
                        "Warning"
                    });
                }
                else if (cbType.SelectedIndex == 1)
                {
                    cbSource.Items.AddRange(new object[]
                    {
                        "Accept-Range",
                        "Content-Type",
                        "ETag",
                        "Last-Modified",
                        "Server"
                    });
                }
                else if (cbType.SelectedIndex == 2)
                {
                    cbSource.Items.AddRange(new object[]
                    {
                        "ALL_HTTP",
                        "ALL_RAW",
                        "APPL_MD_PATH",
                        "APPL_PHYSICAL_PATH",
                        "AUTH_PASSWORD",
                        "AUTH_TYPE",
                        "AUTH_USER",
                        "CERT_COOKIE",
                        "CERT_FLAGS",
                        "CERT_ISSUER",
                        "CERT_KEYSIZE",
                        "CERT_SECRETKEYSIZE",
                        "CERT_SERIALNUMBER",
                        "CERT_SERVER_ISSUER",
                        "CERT_SERVER_SUBJECT",
                        "CERT_SUBJECT",
                        "CONTENT_LENGTH",
                        "CONTENT_TYPE",
                        "GATEWAY_INTERFACE",
                        "HTTP_ACCEPT",
                        "HTTP_ACCEPT_ENCODING",
                        "HTTP_ACCEPT_LANGUAGE",
                        "HTTP_CONNECTION",
                        "HTTP_COOKIE",
                        "HTTP_HOST",
                        "HTTP_METHOD",
                        "HTTP_REFERER",
                        "HTTP_URL",
                        "HTTP_USER_AGENT",
                        "HTTP_VERSION",
                        "HTTPS",
                        "HTTPS_KEYSIZE",
                        "HTTPS_SECRETKEYSIZE",
                        "HTTPS_SERVER_ISSUER",
                        "HTTPS_SERVER_SUBJECT",
                        "INSTANCE_ID",
                        "INSTANCE_META_PATH",
                        "LOCAL_ADDR",
                        "LOGON_USER",
                        "PATH_INFO",
                        "PATH_TRANSLATED",
                        "QUERY_STRING",
                        "REMOTE_ADDR",
                        "REMOTE_HOST",
                        "REMOTE_PORT",
                        "REMOTE_USER",
                        "REQUEST_METHOD",
                        "SCRIPT_NAME",
                        "SERVER_NAME",
                        "SERVER_PORT",
                        "SERVER_PORT_SECURE",
                        "SERVER_PROTOCOL",
                        "SERVER_SOFTWARE",
                        "UNMAPPED_REMOTE_USER",
                        "URL"
                    });
                }
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                if (Custom == null)
                {
                    Custom = logFile.CustomLogFields.CreateElement();
                    logFile.CustomLogFields.Add(Custom);
                }

                Custom.LogFieldName = txtName.Text;
                Custom.SourceType   = (CustomLogFieldSourceType)Enum.ToObject(typeof(CustomLogFieldSourceType), cbType.SelectedIndex);
                Custom.SourceName   = cbSource.Text;
                DialogResult        = DialogResult.OK;
            }));
        }
Ejemplo n.º 9
0
        public FieldsDialog(IServiceProvider serviceProvider, SiteLogFile logFile)
            : base(serviceProvider)
        {
            InitializeComponent();
            if (logFile.CustomLogFields != null)
            {
                foreach (CustomLogField custom in logFile.CustomLogFields)
                {
                    lvCustom.Items.Add(new CustomListViewItem(custom));
                }
            }

            foreach (LogExtFileFlags flag in Enum.GetValues(typeof(LogExtFileFlags)))
            {
                lvStandard.Items.Add(new StandardListViewItem(flag)
                {
                    Checked = (logFile.LogExtFileFlags & flag) == flag
                });
            }

            btnAdd.Enabled = logFile.CustomLogFields != null;

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(lvCustom, "SelectedIndexChanged")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                btnRemove.Enabled = lvCustom.SelectedItems.Count > 0;
                btnEdit.Enabled   = lvCustom.SelectedItems.Count == 1;
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(lvStandard, "ItemChecked")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                btnOK.Enabled = true;
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnAdd, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                var dialog = new AddFieldDialog(ServiceProvider, null, logFile);
                if (dialog.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                lvCustom.Items.Add(new CustomListViewItem(dialog.Custom));
                btnOK.Enabled = true;
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnEdit, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                var selected = (CustomListViewItem)lvCustom.SelectedItems[0];
                var dialog   = new AddFieldDialog(ServiceProvider, selected.Custom, logFile);
                if (dialog.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                selected.Update();
                btnOK.Enabled = true;
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnRemove, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                foreach (CustomListViewItem item in lvCustom.SelectedItems)
                {
                    item.Remove();
                    item.Custom.Delete();
                }

                btnOK.Enabled = true;
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                logFile.LogExtFileFlags = 0;
                foreach (StandardListViewItem item in lvStandard.Items)
                {
                    if (item.Checked)
                    {
                        logFile.LogExtFileFlags |= item.Flag;
                    }
                }

                DialogResult = DialogResult.OK;
            }));
        }