/// <summary> /// Чтение листнеров из конфигурации и запись в указанный логгер /// </summary> /// <param name="logger">Целевой логгер</param> /// <param name="listeners">Коллекция элементов листенеров из конфигурации</param> private static void ReadListeners(ILogger logger, IEnumerable <ListenerElement> listeners) { var listenersFromConfg = new List <Listener>(); foreach (var listener in listeners) { var newListener = new Listener() { Name = listener.Name }; foreach (var filter in listener.Filters.Cast <FilterElementBase>()) { newListener.AddFilter(filter); } foreach (var adapterElement in listener.Adapters.OfType <LogAdapterElement>().Where(el => el != null)) { if (adapterElement.IsEnabled == false) //не создаем адаптер если он выключен { continue; } var newAdapter = CreateAdapter(adapterElement); if (newAdapter != null) { newListener.AddAdapter(newAdapter); } } listenersFromConfg.Add(newListener); logger.AddListener(newListener); } }
/// <summary> /// Метод выполняет мердж настроек из сервиса и локальных /// - Заменяет листенер в локальнх настройках при совпаденнни /// - Добавляет те листенеры которых нет в локальных настройках /// - Заменяет логальный список атрибутов для скрытия на список из сервиса /// </summary> /// <param name="sectionFromLoadedConfig">Секция настроек десериализованная из строки из бд</param> /// <param name="logger">Логгер</param> public static void ReconfigureLogging(LoggingInfrastructureSection sectionFromLoadedConfig, ILogger logger) { var localListeners = logger.Listeners.ToList(); //ToDo: Костыль, продумать как лучше подменять файлы для записи логов try { foreach (var localListener in localListeners) { foreach (var adapter in localListener.Adapters.Where(adapter => adapter is IFileLogAdapter)) { var localPath = ((IFileLogAdapter)adapter).FilePath; localPath = ((IFileLogAdapter)adapter).ReplaceEnvironmentVariable(localPath); //Преобразуем путь если указаны переменные if (File.Exists(localPath)) { var firstLogs = File.ReadAllText(localPath, Encoding.UTF8); //Поскольку имя файла в конфигурации из бд может быть таким же, то записываем все первоначальные логи во временные файлы var tempPath = localPath + ".tmp"; File.WriteAllText(tempPath, firstLogs, Encoding.UTF8); _tempLogFiles.Add(tempPath); //Копируем логи которые были уже записаны для адаптеров локально var listenerElements = sectionFromLoadedConfig.Listeners.OfType <ListenerElement>().EmptyIfNull().ToList(); foreach (var listenerElement in listenerElements) { //Берем те листенеры которые будут заменены на листенеры конфигурации из бд, //Закрываем адаптеры(для записи в файл), удаляем их, чтобы при пересоздании с такиж именем для листенеров из бд не создавался дополнительный файл //Для адаптеров из бд которые не будут перезаписаны, скопированы логи для вставки if (listenerElement.Name != localListener.Name) { continue; } ((IFileLogAdapter)adapter).CloseAppender(); for (var i = 0; i < TryCountDeleteFile; i++) { try { File.Delete(localPath); break; } catch (Exception) { Thread.Sleep(AttemptsWhaitingTime); } } } } } } } catch (Exception ex) { logger.ErrorDev(ex, new LoggingCategory("LoggingConfiguration"), "Error in reconfiguration method", null, null); } var loggerFromAdminConfiguration = ReadConfiguration(sectionFromLoadedConfig); if (loggerFromAdminConfiguration == null) { throw new Exception("Не удалось загрузить конфигурацию"); } foreach (var listener in loggerFromAdminConfiguration.Listeners) { if (localListeners.Any(x => String.Equals(x.Name, listener.Name, StringComparison.CurrentCultureIgnoreCase))) { var localListener = localListeners.FirstOrDefault( x => String.Equals(x.Name, listener.Name, StringComparison.CurrentCultureIgnoreCase)); localListeners.Remove(localListener); } localListeners.Add(listener); logger.AddListener(listener); } foreach (var adapter in logger.Listeners.SelectMany(x => x.Adapters.Where(adapter => adapter is IFileLogAdapter))) { ((IFileLogAdapter)adapter).IsFirstFlushDone += IsFirstFlushDone; } logger.AttributesToHide = loggerFromAdminConfiguration.AttributesToHide; }