///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область СлужебныйПрограммныйИнтерфейс

// Получает регламентное задание по имени.
//
// Параметры:
//  ИмяРегламентногоЗадания - Строка - имя регламентного задания.
//    СоздатьНовое - Булево - в случае отсутствия создается новое.
//
Функция ПолучитьРегламентноеЗаданиеВнешнийВызов(ИмяРегламентногоЗадания, СоздатьНовое = Истина) Экспорт
	Возврат ПолучитьРегламентноеЗадание(ИмяРегламентногоЗадания, СоздатьНовое);
КонецФункции

// Устанавливает расписание регламентного задания по умолчанию.
//
// Параметры:
//  ИмяРегламентногоЗадания - РегламентноеЗадание.
//
Процедура УстановитьРасписаниеПоУмолчаниюВнешнийВызов(Задание) Экспорт
	УстановитьРасписаниеПоУмолчанию(Задание);
КонецПроцедуры

// Удаляет регламентное задание по имени.
//
// Параметры:
//  ИмяРегламентногоЗадания - Строка - имя регламентного задания.
//
Процедура УдалитьРегламентноеЗаданиеВнешнийВызов(ИмяРегламентногоЗадания) Экспорт
	УдалитьРегламентноеЗадание(ИмяРегламентногоЗадания);
КонецПроцедуры

// Устанавливает значение параметра центра мониторинга.
//
// Параметры:
//  Параметр - Строка - ключ параметра центра мониторинга, возможные значения ключа
//                      см. в процедуре ПолучитьПараметрыПоУмолчанию в модуле ЦентрМониторингаСлужебный.
//  Значение - Произвольный - значение параметра центра мониторинга.
//
Функция УстановитьПараметрЦентраМониторингаВнешнийВызов(Параметр, Значение) Экспорт
	УстановитьПараметрЦентраМониторинга(Параметр, Значение);
	Возврат "Успешно";
КонецФункции

// Получает параметры центра мониторинга по умолчанию.
//
// Возвращаемое значение:
//    Структура - значение константы ПараметрыЦентраМониторинга.
//
Функция ПолучитьПараметрыПоУмолчаниюВнешнийВызов() Экспорт
	Возврат ПолучитьПараметрыПоУмолчанию();
КонецФункции

// Получает параметры центра мониторинга.
//
// Параметры:
//    Параметры - Структура - где ключи необходимые параметры, значения которых необходимо получить.
//
// Возвращаемое значение:
//    Структура - значение константы ПараметрыЦентраМониторинга.
//
Функция ПолучитьПараметрыЦентраМониторингаВнешнийВызов(Параметры = Неопределено) Экспорт
	Возврат ПолучитьПараметрыЦентраМониторинга(Параметры);
КонецФункции

// Устанавливает параметры центра мониторинга.
// Параметры:
//    Параметры - Структура - необходимые параметры, значения которых необходимо получить.
//
Функция УстановитьПараметрыЦентраМониторингаВнешнийВызов(НовыеПараметры) Экспорт
	УстановитьПараметрыЦентраМониторинга(НовыеПараметры);
	Возврат "Успешно";
КонецФункции

Функция ЗапускОтправкиОзнакомительногоПакета() Экспорт
	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(Новый УникальныйИдентификатор);
	ПараметрыВыполнения.ОжидатьЗавершение = 0;
	ПараметрыПроцедуры = Новый Структура("Итератор, ОтправкаТестовогоПакета, ПолучениеИдентификатора", 0, Ложь, Истина);
	РезультатЗапуска = ДлительныеОперации.ВыполнитьВФоне("ЦентрМониторингаСлужебный.ОтправитьТестовыйПакет", ПараметрыПроцедуры, ПараметрыВыполнения);
	Возврат РезультатЗапуска;
КонецФункции

#Область ОбработчикиСобытийПодсистемКонфигурации

// См. РегламентныеЗаданияПереопределяемый.ПриОпределенииНастроекРегламентныхЗаданий
Процедура ПриОпределенииНастроекРегламентныхЗаданий(Настройки) Экспорт
	Зависимость = Настройки.Добавить();
	Зависимость.РегламентноеЗадание = Метаданные.РегламентныеЗадания.СборИОтправкаСтатистики;
	Зависимость.РаботаетСВнешнимиРесурсами = Истина;
	
	Зависимость = Настройки.Добавить();
	Зависимость.РегламентноеЗадание = Метаданные.РегламентныеЗадания.СборИОтправкаОтчетовОбОшибках;
	Зависимость.РаботаетСВнешнимиРесурсами = Истина;
КонецПроцедуры

// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления.
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
	
	Обработчик = Обработчики.Добавить();
	Обработчик.НачальноеЗаполнение = Истина;
	Обработчик.Процедура = "ЦентрМониторингаСлужебный.ПервоначальноеЗаполнение";
	
	Обработчик = Обработчики.Добавить();
	Обработчик.РежимВыполнения = "Оперативно";
	Обработчик.ОбщиеДанные = Истина;
	Обработчик.Версия = "2.4.1.7";
	Обработчик.Процедура = "ЦентрМониторингаСлужебный.ДобавитьИдентификаторИнформационнойБазыПостоянный";
	
	Если СтандартныеПодсистемыСервер.ЭтоБазоваяВерсияКонфигурации() И НЕ РазделениеПоОбластямДанныхВключено() Тогда
		Обработчик = Обработчики.Добавить();
		Обработчик.РежимВыполнения = "Отложенно";
		Обработчик.Версия          = "2.4.4.79";
		Обработчик.Комментарий     = НСтр("ru = 'Включает отправку сведений об использовании приложения в фирму ""1С"". Отключить отправку сведений можно в разделе Администрирование / Интернет-поддержка и сервисы / Центр мониторинга'");
		Обработчик.Идентификатор   = Новый УникальныйИдентификатор("68c8c60c-5b23-436a-9555-a6f24a6b1ffd");
		Обработчик.Процедура       = "ЦентрМониторингаСлужебный.ВключитьОтправкуСведений";
		Обработчик.ПроцедураЗаполненияДанныхОбновления = "ЦентрМониторингаСлужебный.ВключитьОтправкуСведенийЗаполнение";
		Обработчик.ЧитаемыеОбъекты                     = "Константа.ПараметрыЦентраМониторинга";
		Обработчик.ИзменяемыеОбъекты                   = "Константа.ПараметрыЦентраМониторинга, РегламентноеЗадание.СборИОтправкаСтатистики";
	КонецЕсли;

	Обработчик = Обработчики.Добавить();
	Обработчик.РежимВыполнения = "Оперативно";
	Обработчик.ОбщиеДанные = Истина;
	Обработчик.Версия = "3.1.9.43";
	Обработчик.Процедура = "ЦентрМониторингаСлужебный.ОтключитьРегистрациюСобытийПриОбновлении";
	
КонецПроцедуры

// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииПараметровРаботыКлиентаПриЗапуске.
Процедура ПриДобавленииПараметровРаботыКлиентаПриЗапуске(Параметры) Экспорт
	
	ПараметрыРаботыКлиента = Новый Структура("ЧасовойПоясСеанса, ХешПользователя, РегистрироватьБизнесСтатистику,
											|ВыводитьЗапросПолныхДампов, ЗапросПолныхДамповВыведен, ИнформацияОДампах,
											|ЗапросНаПолучениеДампов,ЗапросНаОтправку,ЗапросНаПолучениеКонтактов,
											|ЗапросНаПолучениеКонтактовВыведен");
	
	УникальныйИдентификаторПользователя = Строка(ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор);
	НомерСеанса = Формат(НомерСеансаИнформационнойБазы(), "ЧГ=0");
	ХешПользователя = ОбщегоНазначения.КонтрольнаяСуммаСтрокой(УникальныйИдентификаторПользователя + НомерСеанса);
	
	РегистрироватьБизнесСтатистику = ПолучитьПараметрыЦентраМониторинга("РегистрироватьБизнесСтатистику");
	ЗапросНаПолучениеКонтактов = ПолучитьПараметрыЦентраМониторинга("ЗапросКонтактнойИнформации") = 3;
	ПараметрыОповещенияОДампах = ПараметрыОповещенияОДампах();
	
	ЭтоПолноправныйПользователь = Пользователи.ЭтоПолноправныйПользователь(, Истина);
	
	НастройкиЦентраМониторинга = Новый Структура;
	// Всегда включаем оповещения, оповещения о дампах важны для Администратора.
	НастройкиЦентраМониторинга.Вставить("ВключитьОповещение", Истина);
	ЦентрМониторингаПереопределяемый.ПриОпределенииНастроек(НастройкиЦентраМониторинга);
	
	ПараметрыРаботыКлиента.ВыводитьЗапросПолныхДампов = ЭтоПолноправныйПользователь И НастройкиЦентраМониторинга.ВключитьОповещение;	
	ПараметрыРаботыКлиента.ЗапросПолныхДамповВыведен = Ложь;
	ПараметрыРаботыКлиента.ЗапросНаПолучениеДампов = ПараметрыОповещенияОДампах.ЗапросНаПолучениеДампов;
	ПараметрыРаботыКлиента.ЗапросНаОтправку = ПараметрыОповещенияОДампах.ЗапросНаОтправку;
	ПараметрыРаботыКлиента.ИнформацияОДампах = ПараметрыОповещенияОДампах.ИнформацияОДампах;
	ПараметрыРаботыКлиента.ЧасовойПоясСеанса = ЧасовойПоясСеанса();
	ПараметрыРаботыКлиента.ХешПользователя = ХешПользователя;
	ПараметрыРаботыКлиента.РегистрироватьБизнесСтатистику = РегистрироватьБизнесСтатистику;
	ПараметрыРаботыКлиента.ЗапросНаПолучениеКонтактов = ЗапросНаПолучениеКонтактов;
	ПараметрыРаботыКлиента.ЗапросНаПолучениеКонтактовВыведен = Ложь;
		
	Параметры.Вставить("ЦентрМониторинга", Новый ФиксированнаяСтруктура(ПараметрыРаботыКлиента));
	
	// Запишем активность пользователя в бизнес-статистику при запуске.
	Если РегистрироватьБизнесСтатистику Тогда
		ЗаписатьАктивностьПользователя(ХешПользователя);
	КонецЕсли;
	
КонецПроцедуры

// См. ОбщегоНазначенияПереопределяемый.ПриПериодическомПолученииДанныхКлиентаНаСервере
Процедура ПриПериодическомПолученииДанныхКлиентаНаСервере(Параметры, Результаты) Экспорт
	
	СобранныеПараметры = Параметры.Получить("СтандартныеПодсистемы.ЦентрМониторинга");
	Если СобранныеПараметры = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Результат = Новый Соответствие(СобранныеПараметры);
	Результаты.Вставить("СтандартныеПодсистемы.ЦентрМониторинга", Результат);
	
	Если СобранныеПараметры["ИнформацияКлиента"]["ПараметрыКлиента"]["РегистрироватьБизнесСтатистику"] Тогда
	
		РегистрироватьБизнесСтатистику = ПолучитьПараметрыЦентраМониторинга("РегистрироватьБизнесСтатистику");
		
		Результат.Вставить("РегистрироватьБизнесСтатистику", РегистрироватьБизнесСтатистику);
		
		КлючФоновогоЗадания = "ПриПериодическомПолученииДанныхКлиентаНаСервереВФоне"
			+ СобранныеПараметры["ИнформацияКлиента"]["ПараметрыКлиента"]["ХешПользователя"];
		
		Отбор = Новый Структура;
		Отбор.Вставить("Ключ", КлючФоновогоЗадания);
		Отбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
		АктивныеФоновыеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
		
		Если АктивныеФоновыеЗадания.Количество() = 0 Тогда
			
			ПараметрыФоновогоЗадания = Новый Массив;
			ПараметрыФоновогоЗадания.Добавить(СобранныеПараметры);
			ФоновыеЗадания.Выполнить("ЦентрМониторингаСлужебный.ПриПериодическомПолученииДанныхКлиентаНаСервереВФоне",
				ПараметрыФоновогоЗадания,
				КлючФоновогоЗадания,
				"ЦентрМониторингаСлужебный.ПриПериодическомПолученииДанныхКлиентаНаСервере");
		КонецЕсли;
		
	КонецЕсли;
	
	Если СобранныеПараметры["ИнформацияКлиента"]["ПараметрыКлиента"]["ВыводитьЗапросПолныхДампов"] Тогда
		
		ПараметрыОповещенияОДампах = ПараметрыОповещенияОДампах();
		
		ЗапросНаПолучениеДампов = ПараметрыОповещенияОДампах.ЗапросНаПолучениеДампов
								И НЕ СобранныеПараметры.Получить("ЗапросПолныхДамповВыведен") = Истина;
		ЗапросНаПолучениеКонтактов = ПолучитьПараметрыЦентраМониторинга("ЗапросКонтактнойИнформации") = 3
								И НЕ СобранныеПараметры.Получить("ЗапросНаПолучениеКонтактовВыведен") = Истина;
		
		Результат.Вставить("ЗапросНаПолучениеДампов", ЗапросНаПолучениеДампов);
		Результат.Вставить("ЗапросНаОтправкуДампов", ПараметрыОповещенияОДампах.ЗапросНаОтправку);
		Результат.Вставить("ИнформацияОДампах", ПараметрыОповещенияОДампах.ИнформацияОДампах);
		Результат.Вставить("ЗапросНаПолучениеКонтактов", ЗапросНаПолучениеКонтактов);
		
	КонецЕсли;
	
	ПараметрыЦентраМониторинга = Новый Структура("ТестовыйПакетОтправлен,ЦентрОбработкиИнформацииОПрограмме,ВключитьЦентрМониторинга");
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	
	Если НЕ ПараметрыЦентраМониторинга.ТестовыйПакетОтправлен И НЕ РазделениеПоОбластямДанныхВключено() Тогда
		// Тестовый пакет нет смысла отправлять - данные уже отправляются.
		Если ПараметрыЦентраМониторинга.ВключитьЦентрМониторинга ИЛИ ПараметрыЦентраМониторинга.ЦентрОбработкиИнформацииОПрограмме Тогда
			УстановитьПривилегированныйРежим(Истина);
			УстановитьПараметрЦентраМониторинга("ТестовыйПакетОтправлен", Истина);
			УстановитьПривилегированныйРежим(Ложь);
		Иначе
			КлючФоновогоЗадания = "ОтправкаТестовогоПакета";
			
			Отбор = Новый Структура;
			Отбор.Вставить("Ключ", КлючФоновогоЗадания);
			Отбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
			АктивныеФоновыеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
			Если АктивныеФоновыеЗадания.Количество() = 0 Тогда                                                                      
				ПараметрыПроцедуры = Новый Структура("Итератор, ОтправкаТестовогоПакета, ПолучениеИдентификатора", 0, Истина, Ложь);
				МассивПараметров = Новый Массив;
				МассивПараметров.Добавить(ПараметрыПроцедуры);
				МассивПараметров.Добавить(Неопределено);				
				ФоновыеЗадания.Выполнить("ЦентрМониторингаСлужебный.ОтправитьТестовыйПакет",
					МассивПараметров,
					КлючФоновогоЗадания,
					НСтр("ru = 'Центр мониторинга: отправка тестового пакета'"));
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Если ОбщегоНазначения.ИнформационнаяБазаФайловая() Тогда
		ПараметрыЦентраМониторинга = Новый Структура("ОтправлятьФайлыДампов,ВариантДампа,ОкончаниеСбораДампов,СборПолныхДамповВключен");
		ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
			
		НачатьСборИОтправкуОтчетовОбОшибках = Не ПараметрыЦентраМониторинга.ОтправлятьФайлыДампов = 0
												И Не ПустаяСтрока(ПараметрыЦентраМониторинга.ВариантДампа)
												И ОбщегоНазначения.ЭтоWindowsСервер()												
												И ТекущаяУниверсальнаяДата() < ПараметрыЦентраМониторинга.ОкончаниеСбораДампов;
												
		Если НачатьСборИОтправкуОтчетовОбОшибках Тогда
			Идентификатор = СобранныеПараметры["ИнформацияКлиента"]["ПараметрыКлиента"]["ХешПользователя"];
			КлючФоновогоЗадания = "СборИОтправкаОтчетовОбОшибкахНаСервереВФоне" + Идентификатор;
			
			Отбор = Новый Структура;
			Отбор.Вставить("Ключ", КлючФоновогоЗадания);
			Отбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
			АктивныеФоновыеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
			
			Если АктивныеФоновыеЗадания.Количество() = 0 Тогда
				ПараметрыФоновогоЗадания = Новый Массив;
				ПараметрыФоновогоЗадания.Добавить(Истина);
				ПараметрыФоновогоЗадания.Добавить(Идентификатор);
				ФоновыеЗадания.Выполнить("ЦентрМониторингаСлужебный.СобратьИОтправитьДампы",
					ПараметрыФоновогоЗадания,
					КлючФоновогоЗадания,
					НСтр("ru = 'Сбор и отправка отчетов об ошибках'"));
				КонецЕсли;
		Иначе
			Если ПараметрыЦентраМониторинга.СборПолныхДамповВключен[ИмяКомпьютера()] = Истина Тогда
				ПрекратитьСборПолныхДампов();
			КонецЕсли;
		КонецЕсли;	
	КонецЕсли;
		
КонецПроцедуры

Процедура ПриПериодическомПолученииДанныхКлиентаНаСервереВФоне(Параметры) Экспорт
	
	ЗаписатьСтатистикуЭкрановКлиента(Параметры);
	ЗаписатьИнформациюОСистеме(Параметры);
	ЗаписатьИнформацияКлиента(Параметры);
	ЗаписатьДанныеСКлиента(Параметры);
	
КонецПроцедуры

// Параметры:
//   ТекущиеДела - см. ТекущиеДелаСервер.ТекущиеДела.
//
Процедура ПриЗаполненииСпискаТекущихДел(ТекущиеДела) Экспорт
	
	// Право изменять константу имеет только администратор системы.
	Если НЕ Пользователи.ЭтоПолноправныйПользователь(, Истина) Тогда
		Возврат;
	КонецЕсли;
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга();
	
	МодульТекущиеДелаСервер = ОбщегоНазначения.ОбщийМодуль("ТекущиеДелаСервер");
	
	Разделы = МодульТекущиеДелаСервер.РазделыДляОбъекта("Обработка.НастройкиЦентраМониторинга");
	Если Разделы.Количество() = 0 Тогда
		// Не вынесены в командный интерфейс.
		РазделАдминистрирование = Метаданные.Подсистемы.Найти("Администрирование");
		Если РазделАдминистрирование = Неопределено Тогда
			Возврат;
		КонецЕсли;
		Разделы.Добавить(РазделАдминистрирование);
	КонецЕсли;
	
	// 1. Обработать запрос на получение дампов.
	ЗапросНаПолучениеДампов = ПараметрыЦентраМониторинга.ОтправлятьФайлыДампов = 2 И ПараметрыЦентраМониторинга.БазовыеПроверкиПройдены;
	Для Каждого Раздел Из Разделы Цикл
		Дело = ТекущиеДела.Добавить();
		Дело.Идентификатор  = "ЗапросНаПолучениеДампов";
		Дело.ЕстьДела       = ЗапросНаПолучениеДампов;
		Дело.Важное         = Истина;
		Дело.СкрыватьВНастройках = Истина;
		Дело.Владелец       = Раздел;
		Дело.Представление  = НСтр("ru = 'Предоставить отчеты об ошибках'");
		Дело.Количество     = 0;
		Дело.Подсказка      = НСтр("ru = 'Зарегистрированы аварийные завершения работы приложения. Пожалуйста, расскажите нам об этой проблеме.'");
		Дело.ПараметрыФормы = Новый Структура("Вариант", "Запрос");
		Дело.Форма          = "Обработка.НастройкиЦентраМониторинга.Форма.ЗапросНаСборИОтправкуОтчетовОбОшибках";
	КонецЦикла;

	// 2. Обработать запрос на отправку дампов.
	ЕстьДампы = ПараметрыЦентраМониторинга.Свойство("ВариантыДампов") И ПараметрыЦентраМониторинга.ВариантыДампов.Количество();
	ЗапросНаОтправку = ПараметрыЦентраМониторинга.ОтправлятьФайлыДампов = 1
						И НЕ ПустаяСтрока(ПараметрыЦентраМониторинга.ВариантДампа)
						И ЕстьДампы
						И ПараметрыЦентраМониторинга.СпрашиватьПередОтправкой
						И ПараметрыЦентраМониторинга.ТипДампа = "3"
						И Не ПустаяСтрока(ПараметрыЦентраМониторинга.ИнформацияОДампах)
						И ПараметрыЦентраМониторинга.БазовыеПроверкиПройдены;
	Для Каждого Раздел Из Разделы Цикл
		Дело = ТекущиеДела.Добавить();
		Дело.Идентификатор  = "ЗапросНаОтправкуДампов";
		Дело.ЕстьДела       = ЗапросНаОтправку;
		Дело.Важное         = Ложь;
		Дело.Владелец       = Раздел;
		Дело.Представление  = НСтр("ru = 'Отправить отчеты об ошибках'");
		Дело.Количество     = 0;
		Дело.Подсказка      = НСтр("ru = 'Отчеты об аварийном завершении собраны и подготовлены. Пожалуйста, согласуйте их отправку.'");
		Дело.ПараметрыФормы = Новый Структура;
		Дело.Форма          = "Обработка.НастройкиЦентраМониторинга.Форма.ЗапросНаОтправкуОтчетовОбОшибках";
	КонецЦикла;
	
	// 3. Запрос контактной информации.
	ЕстьЗапросКонтактнойИнформации = ПараметрыЦентраМониторинга.ЗапросКонтактнойИнформации = 3;
	Для Каждого Раздел Из Разделы Цикл
		Дело = ТекущиеДела.Добавить();
		Дело.Идентификатор  = "ЗапросКонтактнойИнформации";
		Дело.ЕстьДела       = ЕстьЗапросКонтактнойИнформации;
		Дело.Важное         = Истина;
		Дело.Владелец       = Раздел;
		Дело.Представление  = НСтр("ru = 'Сообщить о проблемах производительности'");
		Дело.Количество     = 0;
		Дело.Подсказка      = НСтр("ru = 'Обнаружены проблемы производительности. Пожалуйста, расскажите нам об этих проблемах.'");
		Дело.ПараметрыФормы = Новый Структура("ПоЗапросу", Истина);
		Дело.Форма          = "Обработка.НастройкиЦентраМониторинга.Форма.ОтправкаКонтактнойИнформации";
	КонецЦикла;
	
КонецПроцедуры

Процедура ОтключитьРегистрациюСобытий() Экспорт
	
	НовыеПараметры = Новый Структура;
	НовыеПараметры.Вставить("РегистрироватьИнформациюОСистеме", Ложь);
	НовыеПараметры.Вставить("РегистрироватьВерсииПодсистем", Ложь);
	НовыеПараметры.Вставить("РегистрироватьДампы", Ложь);
	НовыеПараметры.Вставить("РегистрироватьБизнесСтатистику", Ложь);
	НовыеПараметры.Вставить("РегистрироватьСтатистикуКонфигурации", Ложь);
	НовыеПараметры.Вставить("РегистрироватьНастройкуКонфигурации", Ложь);
	НовыеПараметры.Вставить("РегистрироватьПроизводительность", Ложь);
	НовыеПараметры.Вставить("РегистрироватьПроизводительностьТехнологическую", Ложь);
	УстановитьПараметрыЦентраМониторинга(НовыеПараметры);
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

#Область РаботаСРегламентнымиЗаданиями

Функция ПолучитьРегламентноеЗадание(ИмяРегламентногоЗадания, СоздатьНовое = Истина)
	Результат = Неопределено;
	
	УстановитьПривилегированныйРежим(Истина);
	Задания = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Новый Структура("Метаданные", ИмяРегламентногоЗадания));
	Если Задания.Количество() = 0 Тогда
		Если СоздатьНовое Тогда
			Задание = РегламентныеЗадания.СоздатьРегламентноеЗадание(Метаданные["РегламентныеЗадания"][ИмяРегламентногоЗадания]);
			Задание.Использование = Истина;
			Задание.Записать();
			Результат = Задание;
		КонецЕсли;
	Иначе
		Результат = Задания[0];
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

Процедура УстановитьРасписаниеПоУмолчанию(Задание)
	Задание.Расписание.ПериодПовтораДней = 1;
	Задание.Расписание.ПериодПовтораВТечениеДня = 600;
	Задание.Записать();
КонецПроцедуры

Процедура УдалитьРегламентноеЗадание(ИмяРегламентногоЗадания)
	РегЗадание = ПолучитьРегламентноеЗадание(ИмяРегламентногоЗадания, Ложь);
	Если РегЗадание <> Неопределено Тогда
		РегЗадание.Удалить();
	КонецЕсли;
КонецПроцедуры

Процедура ЦентрМониторингаРегламентноеЗадание() Экспорт
	ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.СборИОтправкаСтатистики);
	
	НеобходимаЗаписьОценкиПроизводительности = Ложь;
	
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	ДатаЗапуска = ТекущаяУниверсальнаяДата();
	ПараметрыЦентраМониторинга = Новый Структура();
	
	ПараметрыЦентраМониторинга.Вставить("ВключитьЦентрМониторинга");
	ПараметрыЦентраМониторинга.Вставить("ЦентрОбработкиИнформацииОПрограмме");
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьДампы");
	ПараметрыЦентраМониторинга.Вставить("РегистрацияДамповСледующееФормирование");
	ПараметрыЦентраМониторинга.Вставить("РегистрацияДамповПериодФормирования");
	
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьБизнесСтатистику");
	ПараметрыЦентраМониторинга.Вставить("БизнесСтатистикаСледующееФормирование");
	ПараметрыЦентраМониторинга.Вставить("БизнесСтатистикаПериодФормирования");
	
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьСтатистикуКонфигурации");
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьНастройкуКонфигурации");
	ПараметрыЦентраМониторинга.Вставить("СтатистикаКонфигурацииСледующееФормирование");
	ПараметрыЦентраМониторинга.Вставить("СтатистикаКонфигурацииПериодФормирования");
	
	ПараметрыЦентраМониторинга.Вставить("ОтправкаДанныхСледующееФормирование");
	ПараметрыЦентраМониторинга.Вставить("ОтправкаДанныхПериодФормирования");
	ПараметрыЦентраМониторинга.Вставить("ДатаОповещения");
	ПараметрыЦентраМониторинга.Вставить("ПринудительнаяОтправкаМинидампов");
	ПараметрыЦентраМониторинга.Вставить("ТаймаутОтветаПользователя");
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	
	Если (ПараметрыЦентраМониторинга.ВключитьЦентрМониторинга ИЛИ ПараметрыЦентраМониторинга.ЦентрОбработкиИнформацииОПрограмме) И ЭтоГлавныйУзел() Тогда 
		Если ПараметрыЦентраМониторинга.РегистрироватьДампы И ДатаЗапуска >= ПараметрыЦентраМониторинга.РегистрацияДамповСледующееФормирование Тогда
			Попытка
				РегистрацияДампов();
			Исключение
				Комментарий = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
				ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Регистрация дампов'", 
					ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, Комментарий);
				УстановитьПараметрЦентраМониторинга("РегистрироватьДампы", Ложь);
				ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистики("ЦентрМониторинга.РегистрацияДампов.Ошибка", 1, Комментарий);
			КонецПопытки;
			
			ПараметрыЦентраМониторинга.РегистрацияДамповСледующееФормирование =
				ТекущаяУниверсальнаяДата() + ПараметрыЦентраМониторинга.РегистрацияДамповПериодФормирования;
			
			НеобходимаЗаписьОценкиПроизводительности = Истина;
		КонецЕсли;
		
		Если ПараметрыЦентраМониторинга.РегистрироватьБизнесСтатистику И ДатаЗапуска >= ПараметрыЦентраМониторинга.БизнесСтатистикаСледующееФормирование Тогда
			Попытка
				РегистрацияОперацийСтатистики();
			Исключение
				Комментарий = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
				ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Регистрация операций статистики'",
					ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, Комментарий);
				ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистики("ЦентрМониторинга.РегистрацияОперацийСтатистики.Ошибка", 1, Комментарий);
			КонецПопытки;
						
			ПараметрыЦентраМониторинга.БизнесСтатистикаСледующееФормирование =
			ТекущаяУниверсальнаяДата()
			+ ПараметрыЦентраМониторинга.БизнесСтатистикаПериодФормирования;
			
			НеобходимаЗаписьОценкиПроизводительности = Истина;
		КонецЕсли;
		
		Если (ПараметрыЦентраМониторинга.РегистрироватьСтатистикуКонфигурации ИЛИ ПараметрыЦентраМониторинга.РегистрироватьНастройкуКонфигурации) И ДатаЗапуска >= ПараметрыЦентраМониторинга.СтатистикаКонфигурацииСледующееФормирование Тогда
			Попытка
				СобратьСтатистикуКонфигурации(Новый Структура("РегистрироватьСтатистикуКонфигурации, РегистрироватьНастройкуКонфигурации", ПараметрыЦентраМониторинга.РегистрироватьСтатистикуКонфигурации, ПараметрыЦентраМониторинга.РегистрироватьНастройкуКонфигурации));
			Исключение
				Комментарий = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
				ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Собрать статистику конфигурации'",
					ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, Комментарий);
				ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистики("ЦентрМониторинга.СобратьСтатистикуКонфигурации.Ошибка", 1, Комментарий);
			КонецПопытки;
				
			ПараметрыЦентраМониторинга.СтатистикаКонфигурацииСледующееФормирование =
			ТекущаяУниверсальнаяДата()
			+ ПараметрыЦентраМониторинга.СтатистикаКонфигурацииПериодФормирования;
			
			НеобходимаЗаписьОценкиПроизводительности = Истина;
		КонецЕсли;
		
		Если ДатаЗапуска >= ПараметрыЦентраМониторинга.ОтправкаДанныхСледующееФормирование Тогда
			Попытка
				СформироватьПакетДляОтправки();
			Исключение
				Комментарий = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
				ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Сформировать пакет для отправки'",
					ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, Комментарий);
				ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистики("ЦентрМониторинга.СформироватьПакетДляОтправки.Ошибка", 1, Комментарий);
			КонецПопытки;
			
			Попытка
				HTTPОтвет = ОтправитьДанныеМониторинга();
				Если HTTPОтвет.КодСостояния = 200 Тогда
					// Все хорошо.
				КонецЕсли;
			Исключение
				Комментарий = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
				ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Отправить данные мониторинга'",
					ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, Комментарий);
				ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистики("ЦентрМониторинга.ОтправитьДанныеМониторинга.Ошибка", 
					1, Комментарий);
			КонецПопытки;
			
			ПараметрыЦентраМониторинга.ОтправкаДанныхСледующееФормирование = ТекущаяУниверсальнаяДата()
				+ ПолучитьПараметрыЦентраМониторинга("ОтправкаДанныхПериодФормирования");
				
			ПараметрыЦентраМониторинга.Удалить("РегистрацияДамповСледующееФормирование");
			ПараметрыЦентраМониторинга.Удалить("РегистрацияДамповПериодФормирования");
			
			ПараметрыЦентраМониторинга.Удалить("БизнесСтатистикаСледующееФормирование");
			ПараметрыЦентраМониторинга.Удалить("БизнесСтатистикаПериодФормирования");
			
			ПараметрыЦентраМониторинга.Удалить("СтатистикаКонфигурацииСледующееФормирование");
			ПараметрыЦентраМониторинга.Удалить("СтатистикаКонфигурацииПериодФормирования");
			
			НеобходимаЗаписьОценкиПроизводительности = Истина;
			
			// Установим дополнительные параметры обработки ошибок.
			УстановитьДополнительнуюИнформациюОбработкиОшибок();
		КонецЕсли;
		
		// Что бы не было записи параметров, которые установились при обработке ответа от сервиса,
		// то удалим эти параметры.
		ПараметрыЦентраМониторинга.Удалить("РегистрироватьДампы");
		ПараметрыЦентраМониторинга.Удалить("РегистрироватьБизнесСтатистику");
		ПараметрыЦентраМониторинга.Удалить("РегистрироватьСтатистикуКонфигурации");
		ПараметрыЦентраМониторинга.Удалить("РегистрироватьНастройкуКонфигурации");
		ПараметрыЦентраМониторинга.Удалить("ОтправкаДанныхПериодФормирования");
		
		УстановитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	Иначе
		УдалитьРегламентноеЗадание("СборИОтправкаСтатистики");
	КонецЕсли;
	
	// Убедимся, что отправка не запрещена, вариант дампа указан и срок сбора не вышел.
	ПараметрыЦентраМониторинга.Вставить("ОтправлятьФайлыДампов");
	ПараметрыЦентраМониторинга.Вставить("ВариантДампа");
	ПараметрыЦентраМониторинга.Вставить("ОкончаниеСбораДампов");
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	
	НачатьСборИОтправкуОтчетовОбОшибках = Не ПараметрыЦентраМониторинга.ОтправлятьФайлыДампов = 0
											И Не ПустаяСтрока(ПараметрыЦентраМониторинга.ВариантДампа)
											И ОбщегоНазначения.ЭтоWindowsСервер()
											И ДатаЗапуска < ПараметрыЦентраМониторинга.ОкончаниеСбораДампов;
	Если НачатьСборИОтправкуОтчетовОбОшибках Тогда
		
		Если НЕ ЗначениеЗаполнено(ПараметрыЦентраМониторинга.ДатаОповещения) Тогда
			// Установим дату срабатывания оповещения.
			УстановитьПараметрЦентраМониторинга("ДатаОповещения", ДатаЗапуска);
		ИначеЕсли ДатаЗапуска > ПараметрыЦентраМониторинга.ДатаОповещения + ПараметрыЦентраМониторинга.ТаймаутОтветаПользователя * 86400
			И ПараметрыЦентраМониторинга.ПринудительнаяОтправкаМинидампов = 2 Тогда
			// Истек таймаут, включаем принудительную отправку.
			УстановитьПараметрЦентраМониторинга("ПринудительнаяОтправкаМинидампов", 1);	
			ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистики("ЦентрМониторинга.РегистрацияДампов.ПринудительнаяОтправкаМинидамповВключена", 1);
		КонецЕсли;
		
		Если ОбщегоНазначения.ИнформационнаяБазаФайловая() Тогда
			// Для файловой базы сбор и отправка происходят в ПриПериодическомПолученииДанныхКлиентаНаСервере.
		Иначе    			
			// Проверим, существует ли регламентное задание.			
			РегЗадание = ПолучитьРегламентноеЗадание("СборИОтправкаОтчетовОбОшибках", Ложь);
			Если РегЗадание = Неопределено Тогда
				РегЗадание = ПолучитьРегламентноеЗадание("СборИОтправкаОтчетовОбОшибках", Истина);
				УстановитьРасписаниеПоУмолчанию(РегЗадание);
			КонецЕсли;                                      			
		КонецЕсли;
	КонецЕсли;											
	
	Если ОценкаПроизводительностиСуществует И НеобходимаЗаписьОценкиПроизводительности Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаСборИОтправкаСтатистики", ВремяНачала);
	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область РаботаСБизнесСтатистикой

Процедура РазобратьБуферОперацийСтатистики(ТекущаяДата)
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(Новый Структура("ПериодАгрегацииМалый, ПериодАгрегации"));
	ПериодАгрегации = ПараметрыЦентраМониторинга.ПериодАгрегацииМалый;
	ПериодУдаления = ПараметрыЦентраМониторинга.ПериодАгрегации;
				
	ОбработатьЗаписиДо = Дата(1, 1, 1) + Цел((ТекущаяДата - Дата(1, 1, 1))/ПериодАгрегации)*ПериодАгрегации;
			
	РезультатЗапросаОперации = РегистрыСведений.БуферОперацийСтатистики.ПолучитьАгрегированныеЗаписиОпераций(ОбработатьЗаписиДо, ПериодАгрегации, ПериодУдаления);
	РезультатЗапросаКомментарий = РегистрыСведений.БуферОперацийСтатистики.ПолучитьАгрегированныеЗаписиКомментарий(ОбработатьЗаписиДо, ПериодАгрегации, ПериодУдаления);
	РезультатЗапросаОбласти = РегистрыСведений.БуферОперацийСтатистики.ПолучитьАгрегированныеЗаписиОбластиСтатистики(ОбработатьЗаписиДо, ПериодАгрегации, ПериодУдаления);
	НачатьТранзакцию();
	Попытка
		РегистрыСведений.ЗамерыОперацииСтатистики.ЗаписатьЗамеры(РезультатЗапросаОперации);
		РегистрыСведений.ЗамерыКомментарииСтатистики.ЗаписатьЗамеры(РезультатЗапросаКомментарий);
		РегистрыСведений.ЗамерыОбластиСтатистики.ЗаписатьЗамеры(РезультатЗапросаОбласти);
		
		РегистрыСведений.БуферОперацийСтатистики.УдалитьЗаписи(ОбработатьЗаписиДо);	
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		Ошибка = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииРазобратьБуферОперацийСтатистики(), 
			УровеньЖурналаРегистрации.Ошибка, Метаданные.РегистрыСведений.БуферОперацийСтатистики,, Ошибка);
		ВызватьИсключение;
	КонецПопытки;
	
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаРазобратьБуферОперацийСтатистики", ВремяНачала);
	КонецЕсли;
КонецПроцедуры

Процедура АгрегироватьЗамерыОперацийСтатистики(ТекущаяДата)
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(Новый Структура("ПериодАгрегацииМалый, ПериодАгрегации, ГраницаАгрегирования"));
	ПериодАгрегации = ПараметрыЦентраМониторинга.ПериодАгрегацииМалый;
	ПериодУдаления = ПараметрыЦентраМониторинга.ПериодАгрегации;
	
	ГраницаАгрегирования = ПараметрыЦентраМониторинга.ГраницаАгрегирования;
	ОбработатьЗаписиДо = Дата(1, 1, 1) + Цел((ТекущаяДата - Дата(1, 1, 1))/ПериодАгрегации)*ПериодАгрегации;
	
	Если ОбработатьЗаписиДо > ГраницаАгрегирования Тогда
		НачатьТранзакцию();
		Попытка
			РезультатЗапросаОперацииАгрегированные = РегистрыСведений.ЗамерыОперацииСтатистики.ПолучитьАгрегированныеЗаписи(ГраницаАгрегирования, ОбработатьЗаписиДо, ПериодАгрегации, ПериодУдаления);
			РезультатЗапросаКомментарийАгрегированные = РегистрыСведений.ЗамерыКомментарииСтатистики.ПолучитьАгрегированныеЗаписи(ГраницаАгрегирования, ОбработатьЗаписиДо, ПериодАгрегации, ПериодУдаления);
			РезультатЗапросаОбластиАгрегированные = РегистрыСведений.ЗамерыОбластиСтатистики.ПолучитьАгрегированныеЗаписи(ГраницаАгрегирования, ОбработатьЗаписиДо, ПериодАгрегации, ПериодУдаления);
			
			РегистрыСведений.ЗамерыОперацииСтатистики.УдалитьЗаписи(ГраницаАгрегирования, ОбработатьЗаписиДо);
			РегистрыСведений.ЗамерыКомментарииСтатистики.УдалитьЗаписи(ГраницаАгрегирования, ОбработатьЗаписиДо);
			РегистрыСведений.ЗамерыОбластиСтатистики.УдалитьЗаписи(ГраницаАгрегирования, ОбработатьЗаписиДо);
			
			РегистрыСведений.ЗамерыОперацииСтатистики.ЗаписатьЗамеры(РезультатЗапросаОперацииАгрегированные);
			РегистрыСведений.ЗамерыКомментарииСтатистики.ЗаписатьЗамеры(РезультатЗапросаКомментарийАгрегированные);
			РегистрыСведений.ЗамерыОбластиСтатистики.ЗаписатьЗамеры(РезультатЗапросаОбластиАгрегированные);
			
			УстановитьПараметрЦентраМониторинга("ГраницаАгрегирования", ОбработатьЗаписиДо);
			
			ЗафиксироватьТранзакцию();
		Исключение
			ОтменитьТранзакцию();
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Агрегировать замеры операций статистики'", 
				ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, 
				ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
			ВызватьИсключение;
		КонецПопытки;
	КонецЕсли;
	
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаАгрегироватьЗамерыОперацийСтатистики", ВремяНачала);
	КонецЕсли;
КонецПроцедуры

Процедура РегистрацияОперацийСтатистики()
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	ТекущаяДата = ТекущаяУниверсальнаяДата();
	
	РазобратьБуферОперацийСтатистики(ТекущаяДата);
	АгрегироватьЗамерыОперацийСтатистики(ТекущаяДата);
	УдалитьУстаревшиеДанныеОперацийСтатистики();
	
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаРегистрацияОперацийСтатистики", ВремяНачала);
	КонецЕсли;
КонецПроцедуры

Процедура УдалитьУстаревшиеДанныеОперацийСтатистики()
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(Новый Структура("ДатаКрайнегоПакета, ПериодУдаления"));
	
	ДатаКрайнегоПакета = ПараметрыЦентраМониторинга.ДатаКрайнегоПакета;
	ПериодУдаления = ПараметрыЦентраМониторинга.ПериодУдаления;
	
	ГраницаУдаления = Дата(1,1,1) + Цел((ДатаКрайнегоПакета - Дата(1,1,1))/ПериодУдаления) * ПериодУдаления;
	
	НачатьТранзакцию();
	Попытка
		РегистрыСведений.ЗамерыОперацииСтатистики.УдалитьЗаписи(Дата(1,1,1), ГраницаУдаления);
		РегистрыСведений.ЗамерыКомментарииСтатистики.УдалитьЗаписи(Дата(1,1,1), ГраницаУдаления);
		РегистрыСведений.ЗамерыОбластиСтатистики.УдалитьЗаписи(Дата(1,1,1), ГраницаУдаления);
		РегистрыСведений.ЗамерыСтатистики.УдалитьЗаписи(Дата(1,1,1), ГраницаУдаления);
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Удалить устаревшие данные операций статистики'", 
			ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, 
			ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ВызватьИсключение;
	КонецПопытки;
	
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаУдалитьУстаревшиеДанныеОперацийСтатистики", ВремяНачала);
	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область РаботаСJSON

Функция СформироватьJSONСтруктуру(ИмяСекции, Данные, ДополнительныеПараметры = Неопределено)
	Если ДополнительныеПараметры = Неопределено Тогда
		ДополнительныеПараметры = Новый Соответствие;
	КонецЕсли;
	
	ДатаНачала = ДополнительныеПараметры["ДатаНачала"];
	ДатаОкончания = ДополнительныеПараметры["ДатаОкончания"];
	ДопПараметры = ДополнительныеПараметры["ДопПараметры"];
	КолонкиИндекса = ДополнительныеПараметры["КолонкиИндекса"];
	
	Если ТипЗнч(Данные) = Тип("РезультатЗапроса") Тогда
		JSONСтруктура = СформироватьJSONСтруктуруРезультатЗапроса(ИмяСекции, Данные, ДатаНачала, ДатаОкончания, ДопПараметры, КолонкиИндекса);
	ИначеЕсли ТипЗнч(Данные) = Тип("ТаблицаЗначений") Тогда
		JSONСтруктура = СформироватьJSONСтруктуруТаблицаЗначений(ИмяСекции, Данные, ДатаНачала, ДатаОкончания, ДопПараметры, КолонкиИндекса);
	КонецЕсли;
	
	Возврат JSONСтруктура;
КонецФункции

Функция СформироватьJSONСтруктуруРезультатЗапроса(ИмяСекции, Данные, ДатаНачала, ДатаОкончания, ДопПараметры, КолонкиИндекса)
	JSONСтруктура = Новый Соответствие;
	
	Секция = Новый Структура;
	
	
	Если ДатаНачала <> Неопределено Тогда
		Секция.Вставить("date_start", ДатаНачала);
	КонецЕсли;
	
	Если ДатаОкончания <> Неопределено Тогда
		Секция.Вставить("date_end", ДатаОкончания);
	КонецЕсли;
	
	Если ДопПараметры <> Неопределено Тогда
		Для Каждого Параметр Из ДопПараметры Цикл
			Секция.Вставить(Параметр.Ключ, Параметр.Значение);
		КонецЦикла;
	КонецЕсли;
			
	Строки = Новый Массив;
	Выборка = Данные.Выбрать();
	// Предназначена для хранения структуры данных.
	СтруктурыКоллекций = Новый Структура;
	// Предназначено для хранения коллекций данных в виде ключевое поле - реквизиты со значениями.
	СоответствияКоллекций = Новый Соответствие; 
	// Список исключаемых из выгрузки колонок. Их данные идут в СоответствияКоллекций.
	ИсключаемыеКолонки = Новый Соответствие;
	Если КолонкиИндекса <> Неопределено Тогда
		ИндексыЗначений = Новый Соответствие;
		Для Каждого ТекКолонка Из КолонкиИндекса Цикл
			ИндексыЗначений.Вставить(ТекКолонка.Ключ, Новый Соответствие);
			Если ТекКолонка.Значение.Количество() Тогда
				СоответствияКоллекций.Вставить(ТекКолонка.Ключ, Новый Соответствие);
				СтруктураОбъекта = Новый Структура;
				Для Каждого Запись Из ТекКолонка.Значение Цикл
					СтруктураОбъекта.Вставить(Запись.Ключ);
					ИсключаемыеКолонки.Вставить(Запись.Ключ, Истина);
				КонецЦикла;
				СтруктурыКоллекций.Вставить(ТекКолонка.Ключ, СтруктураОбъекта);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Колонки = Новый Массив;
	Для Каждого ТекКолонка Из Данные.Колонки Цикл
		Если ИсключаемыеКолонки[ТекКолонка.Имя] = Истина Тогда
			Продолжить;
		КонецЕсли;
		Колонки.Добавить(ТекКолонка.Имя);
	КонецЦикла;
	Секция.Вставить("columns", Колонки);
	
	Пока Выборка.Следующий() Цикл
		Строка = Новый Массив;
		Для Каждого ТекКолонка Из Колонки Цикл
			ЗначениеДляДобавления = Выборка[ТекКолонка];
			Если КолонкиИндекса <> Неопределено И КолонкиИндекса[ТекКолонка] <> Неопределено Тогда
				Если КолонкиИндекса[ТекКолонка][ЗначениеДляДобавления] = Неопределено Тогда
					ИндексЗначения = КолонкиИндекса[ТекКолонка].Количество() + 1;
					КолонкиИндекса[ТекКолонка].Вставить(ЗначениеДляДобавления, ИндексЗначения);
					ИндексыЗначений[ТекКолонка].Вставить(Формат(ИндексЗначения, "ЧГ=0"), ЗначениеДляДобавления);
				КонецЕсли;
				
				ЗначениеДляДобавления = КолонкиИндекса[ТекКолонка][ЗначениеДляДобавления];
			КонецЕсли;
			
			Если СтруктурыКоллекций.Свойство(ТекКолонка) 
				И СоответствияКоллекций[ТекКолонка][Выборка[ТекКолонка]] = Неопределено Тогда
				СоответствиеОбъекта = Новый Соответствие;
				Для Каждого Запись Из СтруктурыКоллекций[ТекКолонка] Цикл
					СоответствиеОбъекта.Вставить(Запись.Ключ, Выборка[Запись.Ключ]);
				КонецЦикла;
				СоответствияКоллекций[ТекКолонка].Вставить(Выборка[ТекКолонка], СоответствиеОбъекта);
			КонецЕсли;
			
			Строка.Добавить(ЗначениеДляДобавления);
		КонецЦикла;
		Строки.Добавить(Строка);
	КонецЦикла;
	
	Для Каждого Запись Из СоответствияКоллекций Цикл
		Секция.Вставить(Запись.Ключ, Запись.Значение);
	КонецЦикла;
	Секция.Вставить("columnsValueIndex", ИндексыЗначений);
	Секция.Вставить("rows", Строки);		
	
	JSONСтруктура.Вставить(ИмяСекции, Секция);
	
	Возврат JSONСтруктура;
КонецФункции

Функция СформироватьJSONСтруктуруТаблицаЗначений(ИмяСекции, Данные, ДатаНачала, ДатаОкончания, ДопПараметры, КолонкиИндекса)
	JSONСтруктура = Новый Соответствие;
	
	Секция = Новый Структура;
	
	
	Если ДатаНачала <> Неопределено Тогда
		Секция.Вставить("date_start", ДатаНачала);
	КонецЕсли;
	
	Если ДатаОкончания <> Неопределено Тогда
		Секция.Вставить("date_end", ДатаОкончания);
	КонецЕсли;
	
	Если ДопПараметры <> Неопределено Тогда
		Для Каждого Параметр Из ДопПараметры Цикл
			Секция.Вставить(Параметр.Ключ, Параметр.Значение);
		КонецЦикла;
	КонецЕсли;
			
	Строки = Новый Массив;
	// Предназначена для хранения структуры данных.
	СтруктурыКоллекций = Новый Структура;
	// Предназначено для хранения коллекций данных в виде ключевое поле - реквизиты со значениями.
	СоответствияКоллекций = Новый Соответствие; 
	// Список исключаемых из выгрузки колонок. Их данные идут в СоответствияКоллекций.
	ИсключаемыеКолонки = Новый Соответствие;
	Если КолонкиИндекса <> Неопределено Тогда
		ИндексыЗначений = Новый Соответствие;
		Для Каждого ТекКолонка Из КолонкиИндекса Цикл
			ИндексыЗначений.Вставить(ТекКолонка.Ключ, Новый Соответствие);
			Если ТекКолонка.Значение.Количество() Тогда
				СоответствияКоллекций.Вставить(ТекКолонка.Ключ, Новый Соответствие);
				СтруктураОбъекта = Новый Структура;
				Для Каждого Запись Из ТекКолонка.Значение Цикл
					СтруктураОбъекта.Вставить(Запись.Ключ);
					ИсключаемыеКолонки.Вставить(Запись.Ключ, Истина);
				КонецЦикла;
				СтруктурыКоллекций.Вставить(ТекКолонка.Ключ, СтруктураОбъекта);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Колонки = Новый Массив;
	Для Каждого ТекКолонка Из Данные.Колонки Цикл
		Если ИсключаемыеКолонки[ТекКолонка.Имя] = Истина Тогда
			Продолжить;
		КонецЕсли;
		Колонки.Добавить(ТекКолонка.Имя);
	КонецЦикла;
	Секция.Вставить("columns", Колонки);
	
	Для Каждого Выборка Из Данные Цикл
		Строка = Новый Массив;
		Для Каждого ТекКолонка Из Колонки Цикл
			ЗначениеДляДобавления = Выборка[ТекКолонка];
			Если КолонкиИндекса <> Неопределено И КолонкиИндекса[ТекКолонка] <> Неопределено Тогда
				Если КолонкиИндекса[ТекКолонка][ЗначениеДляДобавления] = Неопределено Тогда
					ИндексЗначения = КолонкиИндекса[ТекКолонка].Количество() + 1;
					КолонкиИндекса[ТекКолонка].Вставить(ЗначениеДляДобавления, ИндексЗначения);
					ИндексыЗначений[ТекКолонка].Вставить(Формат(ИндексЗначения, "ЧГ=0"), ЗначениеДляДобавления);
				КонецЕсли;
				
				ЗначениеДляДобавления = КолонкиИндекса[ТекКолонка][ЗначениеДляДобавления];
			КонецЕсли;
			
			Если СтруктурыКоллекций.Свойство(ТекКолонка) 
				И СоответствияКоллекций[ТекКолонка][Выборка[ТекКолонка]] = Неопределено Тогда
				СоответствиеОбъекта = Новый Соответствие;
				Для Каждого Запись Из СтруктурыКоллекций[ТекКолонка] Цикл
					СоответствиеОбъекта.Вставить(Запись.Ключ, Выборка[Запись.Ключ]);
				КонецЦикла;
				СоответствияКоллекций[ТекКолонка].Вставить(Выборка[ТекКолонка], СоответствиеОбъекта);
			КонецЕсли;
			
			Строка.Добавить(ЗначениеДляДобавления);
		КонецЦикла;
		Строки.Добавить(Строка);
	КонецЦикла;
	
	Для Каждого Запись Из СоответствияКоллекций Цикл
		Секция.Вставить(Запись.Ключ, Запись.Значение);
	КонецЦикла;
	Секция.Вставить("columnsValueIndex", ИндексыЗначений);
	Секция.Вставить("rows", Строки);		
	
	JSONСтруктура.Вставить(ИмяСекции, Секция);
	
	Возврат JSONСтруктура;
КонецФункции

Функция СформироватьСтруктуруJSONДляОтправки(Параметры)
	ДатаНачала = Параметры.ДатаНачала;
	ДатаОкончания = Параметры.ДатаОкончания;
	
	ТопДамповКоличество = Параметры.ТопДамповКоличество;
	ТопApdex = Параметры.TopApdex;
	ТопApdexTech = Параметры.TopApdexTech;
	ПериодУдаления = Параметры.ПериодУдаления;
	
	ПараметрыЦентраМониторинга = Новый Структура();
	ПараметрыЦентраМониторинга.Вставить("ИдентификаторИнформационнойБазы");
	ПараметрыЦентраМониторинга.Вставить("ИдентификаторИнформационнойБазыПостоянный");
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьИнформациюОСистеме");
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьВерсииПодсистем");
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьДампы");
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьБизнесСтатистику");
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьСтатистикуКонфигурации");
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьНастройкуКонфигурации");
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьПроизводительность");
	ПараметрыЦентраМониторинга.Вставить("РегистрироватьПроизводительностьТехнологическую");
	ПараметрыЦентраМониторинга.Вставить("СтатистикаКонфигурацииСледующаяОтправка");
	ПараметрыЦентраМониторинга.Вставить("СтатистикаКонфигурацииПериодОтправки");
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	
	ОтправлятьСтатистикуКонфигурации = Параметры.ДатаЗапуска >= ПараметрыЦентраМониторинга.СтатистикаКонфигурацииСледующаяОтправка;
	
	Если ПараметрыЦентраМониторинга.РегистрироватьИнформациюОСистеме Тогда
		Инфо = ПолучитьСистемнуюИнформацию();
	КонецЕсли;
	
	Если ПараметрыЦентраМониторинга.РегистрироватьВерсииПодсистем И ОтправлятьСтатистикуКонфигурации Тогда
		Подсистемы = ВерсииПодсистем();
	КонецЕсли;
	
	
	Если ПараметрыЦентраМониторинга.РегистрироватьДампы Тогда
		ТопДампов = РегистрыСведений.ДампыПлатформы.ПолучитьТопВариантов(ДатаНачала, ДатаОкончания, ТопДамповКоличество,, Истина);
		
		ДополнительныеПараметры = Новый Соответствие;
		ДополнительныеПараметры.Вставить("ДатаНачала", ДатаНачала);
		ДополнительныеПараметры.Вставить("ДатаОкончания", ДатаОкончания);
		СекцияDUMPS = СформироватьJSONСтруктуру("dumps", ТопДампов, ДополнительныеПараметры);
	КонецЕсли;
	
	Если ПараметрыЦентраМониторинга.РегистрироватьБизнесСтатистику Тогда
		
		РезультатЗапроса = РегистрыСведений.ЗамерыОперацииСтатистики.ПолучитьЗамеры(ДатаНачала, ДатаОкончания, ПериодУдаления);
		КолонкиИндекса = Новый Соответствие;
		КолонкиИндекса.Вставить("ОперацияСтатистики", Новый Соответствие);
		КолонкиИндекса.Вставить("Период", Новый Соответствие);
		
		ДополнительныеПараметры = Новый Соответствие;
		ДополнительныеПараметры.Вставить("ДатаНачала", ДатаНачала);
		ДополнительныеПараметры.Вставить("ДатаОкончания", ДатаОкончания);
		ДополнительныеПараметры.Вставить("КолонкиИндекса", КолонкиИндекса);
		СекцияОперацииСтатистики = СформироватьJSONСтруктуру("OperationStatistics", РезультатЗапроса, ДополнительныеПараметры);
		СекцияОперацииСтатистики["OperationStatistics"].Вставить("AggregationPeriod", ПериодУдаления);
		
		РезультатЗапроса = РегистрыСведений.ЗамерыКомментарииСтатистики.ПолучитьЗамеры(ДатаНачала, ДатаОкончания, ПериодУдаления);
		КолонкиИндекса = Новый Соответствие;
		КолонкиИндекса.Вставить("ОперацияСтатистики", Новый Соответствие);
		КолонкиИндекса.Вставить("Период", Новый Соответствие);
		КолонкиИндекса.Вставить("КомментарийСтатистики", Новый Соответствие);
		
		ДополнительныеПараметры = Новый Соответствие;
		ДополнительныеПараметры.Вставить("ДатаНачала", ДатаНачала);
		ДополнительныеПараметры.Вставить("ДатаОкончания", ДатаОкончания);
		ДополнительныеПараметры.Вставить("КолонкиИндекса", КолонкиИндекса);
		СекцияКомментарииСтатистики = СформироватьJSONСтруктуру("CommentsStatistics", РезультатЗапроса, ДополнительныеПараметры);
		
		СекцияКомментарииСтатистики["CommentsStatistics"]["columnsValueIndex"].Удалить("ОперацияСтатистики");
		СекцияКомментарииСтатистики["CommentsStatistics"]["columnsValueIndex"].Удалить("Период");
		СекцияКомментарииСтатистики["CommentsStatistics"].Вставить("AggregationPeriod", ПериодУдаления);
		
		РезультатЗапроса = РегистрыСведений.ЗамерыОбластиСтатистики.ПолучитьЗамеры(ДатаНачала, ДатаОкончания, ПериодУдаления);
		КолонкиИндекса = Новый Соответствие;
		КолонкиИндекса.Вставить("ОперацияСтатистики", Новый Соответствие);
		КолонкиИндекса.Вставить("Период", Новый Соответствие);
		КолонкиИндекса.Вставить("ОбластьСтатистики", Новый Соответствие);
		
		ДополнительныеПараметры = Новый Соответствие;
		ДополнительныеПараметры.Вставить("ДатаНачала", ДатаНачала);
		ДополнительныеПараметры.Вставить("ДатаОкончания", ДатаОкончания);
		ДополнительныеПараметры.Вставить("КолонкиИндекса", КолонкиИндекса);
		СекцияОбластиСтатистики = СформироватьJSONСтруктуру("StatisticalAreas", РезультатЗапроса, ДополнительныеПараметры);
		СекцияОбластиСтатистики["StatisticalAreas"]["columnsValueIndex"].Удалить("ОперацияСтатистики");
		СекцияОбластиСтатистики["StatisticalAreas"]["columnsValueIndex"].Удалить("Период");
		СекцияОбластиСтатистики["StatisticalAreas"].Вставить("AggregationPeriod", ПериодУдаления);
		
		РезультатЗапроса = РегистрыСведений.ЗамерыСтатистики.ПолучитьЗамерыЧаса(ДатаНачала, ДатаОкончания);
		КолонкиИндекса = Новый Соответствие;
		КолонкиИндекса.Вставить("ОперацияСтатистики", Новый Соответствие);
		КолонкиИндекса.Вставить("Период", Новый Соответствие);
		
		ДополнительныеПараметры = Новый Соответствие;
		ДополнительныеПараметры.Вставить("КолонкиИндекса", КолонкиИндекса);
		СекцияОперацииСтатистикиКлиентЧас = СформироватьJSONСтруктуру("OperationStatisticsClientHour", РезультатЗапроса, ДополнительныеПараметры);
		
		РезультатЗапроса = РегистрыСведений.ЗамерыСтатистики.ПолучитьЗамерыСутки(ДатаНачала, ДатаОкончания);
		КолонкиИндекса = Новый Соответствие;
		КолонкиИндекса.Вставить("ОперацияСтатистики", Новый Соответствие);
		КолонкиИндекса.Вставить("Период", Новый Соответствие);
		
		ДополнительныеПараметры = Новый Соответствие;
		ДополнительныеПараметры.Вставить("КолонкиИндекса", КолонкиИндекса);
		СекцияОперацииСтатистикиКлиентСутки = СформироватьJSONСтруктуру("OperationStatisticsClientDay", РезультатЗапроса, ДополнительныеПараметры);
		
	КонецЕсли;
	
	РазделениеПоОбластямДанныхВключено = РазделениеПоОбластямДанныхВключено();
	
#Область СекцияStatisticsConfiguration
	Если ПараметрыЦентраМониторинга.РегистрироватьСтатистикуКонфигурации И ОтправлятьСтатистикуКонфигурации Тогда
		Если РазделениеПоОбластямДанныхВключено Тогда
			РезультатЗапросаИмена = РегистрыСведений.СтатистикаКонфигурации.ПолучитьИменаСтатистики(0);
			ТаблицаЗначенийИмена = РезультатЗапросаИмена.Выгрузить();
			
			Массив = Новый Массив;
			КЧ_10_0 = Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Неотрицательный);
			Массив.Добавить(Тип("Число"));
			ОписаниеТиповЧисло_10_0 = Новый ОписаниеТипов(Массив, КЧ_10_0,,,);
			ТаблицаЗначенийИмена.Колонки.Добавить("ИндексСтроки", ОписаниеТиповЧисло_10_0);
			СтруктураИменМетаданных = Новый Соответствие;
			Для Каждого ТекСтрока Из ТаблицаЗначенийИмена Цикл
				ИндексСтроки = ТаблицаЗначенийИмена.Индекс(ТекСтрока);
				ТекСтрока.ИндексСтроки = ИндексСтроки;
				СтруктураИменМетаданных.Вставить(ИндексСтроки, ТекСтрока.ОперацияСтатистикиНаименование); 
			КонецЦикла;
			
			СекцияСтатистикаКонфигурации = Новый Структура("StatisticsConfiguration", Новый Структура);
			СекцияСтатистикаКонфигурации.StatisticsConfiguration.Вставить("MetadataName", Метаданные.Имя);
			СекцияСтатистикаКонфигурации.StatisticsConfiguration.Вставить("WorkingMode", ?(ОбщегоНазначения.ИнформационнаяБазаФайловая(), "F", "S"));
			СекцияСтатистикаКонфигурации.StatisticsConfiguration.Вставить("DivisionByRegions", РазделениеПоОбластямДанныхВключено);
			СекцияСтатистикаКонфигурации.StatisticsConfiguration.Вставить("MetadataIndexName", Новый Соответствие);
			Для Каждого ТекСтрока Из ТаблицаЗначенийИмена Цикл
				СекцияСтатистикаКонфигурации.StatisticsConfiguration.MetadataIndexName.Вставить(Строка(ТекСтрока.ИндексСтроки), ТекСтрока.ОперацияСтатистикиНаименование);
			КонецЦикла;
						
			СекцияСтатистикаКонфигурации.StatisticsConfiguration.Вставить("StatisticsConfigurationByRegions", Новый Соответствие);
			ОбластиДанныхРезультат = РегистрыСведений.СтатистикаКонфигурации.ПолучитьОбластиДанныхРезультатЗапроса();
			Выборка = ОбластиДанныхРезультат.Выбрать();
			Пока Выборка.Следующий() Цикл
				ОбластьДанныхСтрока = Строка(Выборка.ОбластьДанных);
				ОбластьДанныхСсылка = РегистрыСведений.ОбластиСтатистики.ПолучитьСсылку(ОбластьДанныхСтрока);
				
				Если РегистрыСведений.ОбластиСтатистики.СобиратьСтатистикуКонфигурации(ОбластьДанныхСтрока) Тогда
					РезультатЗапроса = РегистрыСведений.СтатистикаКонфигурации.ПолучитьСтатистику(0, ТаблицаЗначенийИмена, ОбластьДанныхСсылка);
					СтатистикаКонфигурацииОбласти = СформироватьJSONСтруктуру(ОбластьДанныхСтрока, РезультатЗапроса);
					СекцияСтатистикаКонфигурации.StatisticsConfiguration.StatisticsConfigurationByRegions.Вставить(ОбластьДанныхСтрока, СтатистикаКонфигурацииОбласти[ОбластьДанныхСтрока]); 
				КонецЕсли;
			КонецЦикла;
			ДанныеОбИспользуемыхРасширениях = Новый Структура;
		Иначе
			РезультатЗапроса = РегистрыСведений.СтатистикаКонфигурации.ПолучитьСтатистику(0);
			ДопПараметры = Новый Структура("MetadataName", Метаданные.Имя);
			ДопПараметры.Вставить("WorkingMode", ?(ОбщегоНазначения.ИнформационнаяБазаФайловая(), "F", "S"));
			ДопПараметры.Вставить("DivisionByRegions", РазделениеПоОбластямДанныхВключено);
			ДопПараметры.Вставить("CompatibilityMode", Строка(Метаданные.РежимСовместимости));
			ДопПараметры.Вставить("InterfaceCompatibilityMode", Строка(Метаданные.РежимСовместимостиИнтерфейса));
			ДопПараметры.Вставить("ModalityUseMode", Строка(Метаданные.РежимИспользованияМодальности));
			ДанныеОбИспользуемыхРасширениях = ДанныеОбИспользуемыхРасширениях();
			ДанныеОбИспользованииРолей = ДанныеОбИспользованииРолей();
			ДопПараметры.Вставить("UsingExtensions", ДанныеОбИспользуемыхРасширениях.ИспользованиеРасширений);
			
			ДополнительныеПараметры = Новый Соответствие;
			ДополнительныеПараметры.Вставить("ДатаНачала", ДатаНачала);
			ДополнительныеПараметры.Вставить("ДопПараметры", ДопПараметры);
			СекцияСтатистикаКонфигурации = СформироватьJSONСтруктуру("StatisticsConfiguration", РезультатЗапроса, ДополнительныеПараметры);
		КонецЕсли;
	КонецЕсли;
#КонецОбласти
	
#Область СекцияOptions
	Если ПараметрыЦентраМониторинга.РегистрироватьНастройкуКонфигурации И ОтправлятьСтатистикуКонфигурации Тогда
		Если РазделениеПоОбластямДанныхВключено Тогда
			РезультатЗапросаИмена = РегистрыСведений.СтатистикаКонфигурации.ПолучитьИменаСтатистики(1);
			ТаблицаЗначенийИмена = РезультатЗапросаИмена.Выгрузить();
			
			Массив = Новый Массив;
			КЧ_10_0 = Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Неотрицательный);
			Массив.Добавить(Тип("Число"));
			ОписаниеТиповЧисло_10_0 = Новый ОписаниеТипов(Массив, КЧ_10_0,,,);
			ТаблицаЗначенийИмена.Колонки.Добавить("ИндексСтроки", ОписаниеТиповЧисло_10_0);
			СтруктураИменМетаданных = Новый Соответствие;
			Для Каждого ТекСтрока Из ТаблицаЗначенийИмена Цикл
				ИндексСтроки = ТаблицаЗначенийИмена.Индекс(ТекСтрока);
				ТекСтрока.ИндексСтроки = ИндексСтроки;
				СтруктураИменМетаданных.Вставить(ИндексСтроки, ТекСтрока.ОперацияСтатистикиНаименование); 
			КонецЦикла;
			
			СекцияНастройкаКонфигурации = Новый Структура("Options", Новый Структура);
			СекцияНастройкаКонфигурации.Options.Вставить("MetadataName", Метаданные.Имя);
			СекцияНастройкаКонфигурации.Options.Вставить("WorkingMode", ?(ОбщегоНазначения.ИнформационнаяБазаФайловая(), "F", "S"));
			СекцияНастройкаКонфигурации.Options.Вставить("DivisionByRegions", РазделениеПоОбластямДанныхВключено);
			СекцияНастройкаКонфигурации.Options.Вставить("MetadataIndexName", Новый Соответствие);
			Для Каждого ТекСтрока Из ТаблицаЗначенийИмена Цикл
				СекцияНастройкаКонфигурации.Options.MetadataIndexName.Вставить(Строка(ТекСтрока.ИндексСтроки), ТекСтрока.ОперацияСтатистикиНаименование);
			КонецЦикла;
			
			СекцияНастройкаКонфигурации.Options.Вставить("OptionsByRegions", Новый Соответствие);
			ОбластиДанныхРезультат = РегистрыСведений.СтатистикаКонфигурации.ПолучитьОбластиДанныхРезультатЗапроса();
			Выборка = ОбластиДанныхРезультат.Выбрать();
			Пока Выборка.Следующий() Цикл
				ОбластьДанныхСтрока = Строка(Выборка.ОбластьДанных);
				ОбластьДанныхСсылка = РегистрыСведений.ОбластиСтатистики.ПолучитьСсылку(ОбластьДанныхСтрока);
				
				Если РегистрыСведений.ОбластиСтатистики.СобиратьСтатистикуКонфигурации(ОбластьДанныхСтрока) Тогда
					РезультатЗапроса = РегистрыСведений.СтатистикаКонфигурации.ПолучитьСтатистику(1, ТаблицаЗначенийИмена, ОбластьДанныхСсылка);
					СтатистикаКонфигурацииОбласти = СформироватьJSONСтруктуру(ОбластьДанныхСтрока, РезультатЗапроса);
					СекцияНастройкаКонфигурации.Options.OptionsByRegions.Вставить(ОбластьДанныхСтрока, СтатистикаКонфигурацииОбласти[ОбластьДанныхСтрока]); 
				КонецЕсли;
			КонецЦикла;
		Иначе
			РезультатЗапроса = РегистрыСведений.СтатистикаКонфигурации.ПолучитьСтатистику(1);
			ДопПараметры = Новый Структура("MetadataName", Метаданные.Имя);
			ДопПараметры.Вставить("WorkingMode", ?(ОбщегоНазначения.ИнформационнаяБазаФайловая(), 0, 1));
			
			ДополнительныеПараметры = Новый Соответствие;
			ДополнительныеПараметры.Вставить("ДатаНачала", ДатаНачала);
			ДополнительныеПараметры.Вставить("ДопПараметры", ДопПараметры);
			СекцияНастройкаКонфигурации = СформироватьJSONСтруктуру("Options", РезультатЗапроса, ДополнительныеПараметры);
		КонецЕсли;
	КонецЕсли;
#КонецОбласти
		
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительностиСлужебный = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительностиСлужебный");
		
		Если ПараметрыЦентраМониторинга.РегистрироватьПроизводительность Тогда
			РезультатЗапроса = МодульОценкаПроизводительностиСлужебный.ПолучитьТопAPDEX(ДатаНачала, ДатаОкончания, ПериодУдаления, ТопApdex);
			КолонкиИндекса = Новый Соответствие;
			КолонкиИндекса.Вставить("Period", Новый Соответствие);
			КоллекцияКлючевойОперации = Новый Соответствие;
			КоллекцияКлючевойОперации.Вставить("KOD");
			КоллекцияКлючевойОперации.Вставить("KON");
			КолонкиИндекса.Вставить("KOHash", КоллекцияКлючевойОперации);
						
			ДополнительныеПараметры = Новый Соответствие;
			ДополнительныеПараметры.Вставить("ДатаНачала", ДатаНачала);
			ДополнительныеПараметры.Вставить("ДатаОкончания", ДопПараметры);
			ДополнительныеПараметры.Вставить("КолонкиИндекса", КолонкиИндекса);
			СекцияТопAPDEX = СформироватьJSONСтруктуру("TopApdex", РезультатЗапроса, ДополнительныеПараметры);	
			СекцияТопAPDEX["TopApdex"].Вставить("AggregationPeriod", ПериодУдаления);
		КонецЕсли;
		
		Если ПараметрыЦентраМониторинга.РегистрироватьПроизводительностьТехнологическую Тогда
			РезультатЗапроса = МодульОценкаПроизводительностиСлужебный.ПолучитьТопAPDEXТехнологический(ДатаНачала, ДатаОкончания, ПериодУдаления, ТопApdexTech);
			КолонкиИндекса = Новый Соответствие;
			КолонкиИндекса.Вставить("Period", Новый Соответствие);
			КоллекцияКлючевойОперации = Новый Соответствие;
			КоллекцияКлючевойОперации.Вставить("KOD");
			КоллекцияКлючевойОперации.Вставить("KON");
			КолонкиИндекса.Вставить("KOHash", КоллекцияКлючевойОперации);
			
			ДополнительныеПараметры = Новый Соответствие;
			ДополнительныеПараметры.Вставить("ДатаНачала", ДатаНачала);
			ДополнительныеПараметры.Вставить("ДатаОкончания", ДопПараметры);
			ДополнительныеПараметры.Вставить("КолонкиИндекса", КолонкиИндекса);
			СекцияТопAPDEXСлужебные = СформироватьJSONСтруктуру("TopApdexTechnology", РезультатЗапроса, ДополнительныеПараметры);
			СекцияТопAPDEXСлужебные["TopApdexTechnology"].Вставить("AggregationPeriod", ПериодУдаления);
		КонецЕсли;
	КонецЕсли;
	
	ИдентификаторИнформационнойБазы = Строка(ПараметрыЦентраМониторинга.ИдентификаторИнформационнойБазы);
	ИдентификаторИнформационнойБазыПостоянный = Строка(ПараметрыЦентраМониторинга.ИдентификаторИнформационнойБазыПостоянный);
	JSONСтруктура = Новый Структура;
	JSONСтруктура.Вставить("id",  ИдентификаторИнформационнойБазы);
	JSONСтруктура.Вставить("idConst",  ИдентификаторИнформационнойБазыПостоянный);
	JSONСтруктура.Вставить("versionPacket",  "1.0.10.0");
	JSONСтруктура.Вставить("datePacket",  ТекущаяУниверсальнаяДата());
	
	Если ПараметрыЦентраМониторинга.РегистрироватьИнформациюОСистеме Тогда
		JSONСтруктура.Вставить("info",  Инфо);
	КонецЕсли;
	
	Если ПараметрыЦентраМониторинга.РегистрироватьВерсииПодсистем И ОтправлятьСтатистикуКонфигурации Тогда
		JSONСтруктура.Вставить("versions",  Подсистемы);
	КонецЕсли;
		
	Если ПараметрыЦентраМониторинга.РегистрироватьДампы Тогда
		JSONСтруктура.Вставить("dumps", СекцияDUMPS["dumps"]);
		ДанныеОПолныхДампах = Новый Структура;
		ДанныеОПолныхДампах.Вставить("sendingResult", Параметры.РезультатОтправки);
		ДанныеОПолныхДампах.Вставить("sendDumps", Параметры.ОтправлятьФайлыДампов);
		ДанныеОПолныхДампах.Вставить("askBeforeSending", Параметры.СпрашиватьПередОтправкой);
		JSONСтруктура.Вставить("FullDumps", ДанныеОПолныхДампах);		
	КонецЕсли;
	
	Если ПараметрыЦентраМониторинга.РегистрироватьБизнесСтатистику Тогда
		БизнесСтатистика = Новый Структура;
		БизнесСтатистика.Вставить("OperationStatistics", СекцияОперацииСтатистики["OperationStatistics"]);
		БизнесСтатистика.Вставить("CommentsStatistics", СекцияКомментарииСтатистики["CommentsStatistics"]);
		БизнесСтатистика.Вставить("StatisticalAreas", СекцияОбластиСтатистики["StatisticalAreas"]);
		БизнесСтатистика.Вставить("OperationStatisticsClientHour", СекцияОперацииСтатистикиКлиентЧас["OperationStatisticsClientHour"]);
		БизнесСтатистика.Вставить("OperationStatisticsClientDay", СекцияОперацииСтатистикиКлиентСутки["OperationStatisticsClientDay"]);
		JSONСтруктура.Вставить("business", БизнесСтатистика);
	КонецЕсли;
	
		Если ПараметрыЦентраМониторинга.РегистрироватьСтатистикуКонфигурации И ОтправлятьСтатистикуКонфигурации Тогда
		JSONСтруктура.Вставить("config", СекцияСтатистикаКонфигурации["StatisticsConfiguration"]);
		JSONСтруктура.Вставить("extensionsInfo", ДанныеОбИспользуемыхРасширениях);
		JSONСтруктура.Вставить("statisticOfRoles", ДанныеОбИспользованииРолей);
	КонецЕсли;
	
	Если ПараметрыЦентраМониторинга.РегистрироватьНастройкуКонфигурации И ОтправлятьСтатистикуКонфигурации Тогда
		JSONСтруктура.Вставить("options", СекцияНастройкаКонфигурации["Options"]);
	КонецЕсли;
		
	Если ОценкаПроизводительностиСуществует Тогда
		Если ПараметрыЦентраМониторинга.РегистрироватьПроизводительность Тогда
			JSONСтруктура.Вставить("perf", СекцияТопAPDEX["TopApdex"]);
		КонецЕсли;
		
		Если ПараметрыЦентраМониторинга.РегистрироватьПроизводительностьТехнологическую Тогда
			JSONСтруктура.Вставить("internal_perf", СекцияТопAPDEXСлужебные["TopApdexTechnology"]);
		КонецЕсли;
	КонецЕсли;
	
	Если Параметры.КонтактнаяИнформацияИзменена 
		И (Параметры.ЗапросКонтактнойИнформации = 0 
		ИЛИ Параметры.ЗапросКонтактнойИнформации = 1) Тогда
		КонтактнаяИнформация = Новый Структура;
		КонтактнаяИнформация.Вставить("ЗапросКонтактнойИнформации", Параметры.ЗапросКонтактнойИнформации);
		КонтактнаяИнформация.Вставить("КонтактнаяИнформация", Параметры.КонтактнаяИнформация);
		КонтактнаяИнформация.Вставить("КонтактнаяИнформацияКомментарий", Параметры.КонтактнаяИнформацияКомментарий);
		КонтактнаяИнформация.Вставить("ЛогинПортала", Параметры.ЛогинПортала);
		JSONСтруктура.Вставить("contacts", КонтактнаяИнформация);		
	КонецЕсли;
	
	Если ОтправлятьСтатистикуКонфигурации Тогда		
		УстановитьПараметрЦентраМониторинга("СтатистикаКонфигурацииСледующаяОтправка", Параметры.ДатаЗапуска + ПараметрыЦентраМониторинга.СтатистикаКонфигурацииПериодОтправки);				
	КонецЕсли;
			
	Возврат JSONСтруктура;
КонецФункции

Функция СтруктураJSONВСтроку(JSONСтруктура) Экспорт
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет));
	ЗаписатьJSON(ЗаписьJSON, JSONСтруктура);
		
	Возврат ЗаписьJSON.Закрыть();
КонецФункции

#КонецОбласти

#Область РаботаСHTTPСервисом

Функция HTTPСервисОтправитьДанныеСлужебный(Параметры)
	
	ЗащищенноеСоединение = Неопределено;
	Если Параметры.ЗащищенноеСоединение Тогда
		ЗащищенноеСоединение = ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение();
	КонецЕсли;
	
	ИнтернетПрокси = Неопределено;
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПолучениеФайловИзИнтернета") Тогда
		МодульПолучениеФайловИзИнтернета = ОбщегоНазначения.ОбщийМодуль("ПолучениеФайловИзИнтернета");
		ИнтернетПрокси = МодульПолучениеФайловИзИнтернета.ПолучитьПрокси("https");
	КонецЕсли;
	
	HTTPСоединение = Новый HTTPСоединение(
		Параметры.Сервер, Параметры.Порт,,,
		ИнтернетПрокси,
		Параметры.Таймаут, 
		ЗащищенноеСоединение);
	
	HTTPЗапрос = Новый HTTPЗапрос(Параметры.АдресРесурса);
	
	Если Параметры.ТипДанных = "Текст" Тогда
		HTTPЗапрос.УстановитьТелоИзСтроки(Параметры.Данные);
	ИначеЕсли Параметры.ТипДанных = "ZIP" Тогда
		ИмяФайлаАрхива = ЗаписатьДанныеВАрхив(Параметры.Данные);
		ДвоичныеДанныеАрхива = Новый ДвоичныеДанные(ИмяФайлаАрхива);
		HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеАрхива);
	ИначеЕсли Параметры.ТипДанных = "ДвоичныеДанные" Тогда
		ДвоичныеДанныеАрхива = Новый ДвоичныеДанные(Параметры.Данные);
		HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеАрхива);
	КонецЕсли;
	
	Попытка
		
		ОбщегоНазначения.РазрешенДоступКИнтернетСервисам(Истина);
		
		Если Параметры.Метод = "POST" Тогда
			HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
		ИначеЕсли Параметры.Метод = "GET" Тогда
			HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
		КонецЕсли;
		
		HTTPОтветСтруктура = HTTPОтветВСтруктуру(HTTPОтвет);
		
		Если HTTPОтветСтруктура.КодСостояния = 200 Тогда
			Если Параметры.ТипДанных = "ZIP" Тогда
				УдалитьФайлы(ИмяФайлаАрхива);
			ИначеЕсли Параметры.ТипДанных = "ДвоичныеДанные" Тогда
				УдалитьФайлы(Параметры.Данные);
			КонецЕсли;
		КонецЕсли;
	Исключение
		HTTPОтветСтруктура = Новый Структура("КодСостояния", 105);
	КонецПопытки;
	
	Возврат HTTPОтветСтруктура;
КонецФункции

Функция ЗаписатьДанныеВАрхив(Данные)
	ИмяФайлаДанных = ПолучитьИмяВременногоФайла("txt");
	ИмяФайлаАрхива = ПолучитьИмяВременногоФайла("zip");
	
	ЗаписьТекста = Новый ЗаписьТекста(ИмяФайлаДанных);
	ЗаписьТекста.Записать(Данные);
	ЗаписьТекста.Закрыть();
	
	АрхивZip = Новый ЗаписьZipФайла(ИмяФайлаАрхива,,,МетодСжатияZIP.Сжатие,УровеньСжатияZIP.Максимальный);
	АрхивZip.Добавить(ИмяФайлаДанных, РежимСохраненияПутейZIP.НеСохранятьПути);
	АрхивZip.Записать();
	
	УдалитьФайлы(ИмяФайлаДанных);
	
	Возврат ИмяФайлаАрхива; 
КонецФункции

Функция HTTPОтветВСтруктуру(Ответ)
	Результат = Новый Структура;
	
	Результат.Вставить("КодСостояния", Ответ.КодСостояния);
	Результат.Вставить("Заголовки",  Новый Соответствие);
	Для каждого Параметр Из Ответ.Заголовки Цикл
		Результат.Заголовки.Вставить(Параметр.Ключ, Параметр.Значение);
	КонецЦикла;
	
	HTTPЗаголовки = HTTPЗаголовкиВНижнийРегистр(Ответ.Заголовки);
	Если HTTPЗаголовки["content-type"] <> Неопределено Тогда
		ТипСодержимого = HTTPЗаголовки["content-type"];
		Если СтрНайти(ТипСодержимого, "text/plain") > 0 Тогда
			Тело = Ответ.ПолучитьТелоКакСтроку();
			Результат.Вставить("Тело", Тело);
		ИначеЕсли СтрНайти(ТипСодержимого, "text/html") > 0 Тогда
			Тело = Ответ.ПолучитьТелоКакСтроку();
			Результат.Вставить("Тело", Тело);
		ИначеЕсли СтрНайти(ТипСодержимого, "application/json") Тогда
			Тело = Ответ.ПолучитьТелоКакСтроку();
			Результат.Вставить("Тело", Тело);
		Иначе
			Тело = "Не известный ContentType = " + ТипСодержимого + ". См. <Функция HTTPОтветВСтруктуру(Ответ) Экспорт>";
			Результат.Вставить("Тело", Тело);
		КонецЕсли;
	КонецЕсли;	
	
	Возврат Результат;
КонецФункции

Функция HTTPЗаголовкиВНижнийРегистр(Заголовки)
	
	Результат = Новый Соответствие;
	Для каждого Заголовок Из Заголовки Цикл
		Результат.Вставить(НРег(Заголовок.Ключ), Заголовок.Значение);
	КонецЦикла;
	Возврат Результат;
	
КонецФункции

#КонецОбласти

#Область РаботаСРегистрациейДампов

Процедура РегистрацияДампов()
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	ТипДампа = ПолучитьПараметрыЦентраМониторинга("ТипДампа");
	КаталогДампов = ПолучитьКаталогДампов(ТипДампа);
	
	Если КаталогДампов.Путь <> Неопределено Тогда
		// Проверим, нужно ли оповестить Администратора о падении процессов.
		ПроверитьНеобходимостьОповещенияОДампах(КаталогДампов.Путь);
		Если КаталогДампов.УдалятьДампы Тогда
			ДампыДляУдаления = РегистрыСведений.ДампыПлатформы.ПолучитьДампыДляУдаления();
			
			Для Каждого ДампДляУдаления Из ДампыДляУдаления Цикл
				Файл = Новый Файл(ДампДляУдаления.ИмяФайла);
				Если Файл.Существует() Тогда
					Попытка
						УдалитьФайлы(Файл.ПолноеИмя);
						ДампДляУдаления.ИмяФайла = "";
						РегистрыСведений.ДампыПлатформы.ИзменитьЗапись(ДампДляУдаления);
					Исключение
						ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииЦентрМониторингаУдалениеДампа(), 
							УровеньЖурналаРегистрации.Ошибка,,,
							ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
					КонецПопытки;
				Иначе
					ДампДляУдаления.ИмяФайла = "";
					РегистрыСведений.ДампыПлатформы.ИзменитьЗапись(ДампДляУдаления);
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
		
		ФайлыДампов = НайтиФайлы(КаталогДампов.Путь, "*.mdmp");
		ИменаФайловДампов = Новый Массив;
		Для Каждого ФайлДампа Из ФайлыДампов Цикл
			ИменаФайловДампов.Добавить(ФайлДампа.ПолноеИмя);
		КонецЦикла;
		
		ФайлыДамповЗарегистрированные = РегистрыСведений.ДампыПлатформы.ПолучитьЗарегистрированныеДампы(ИменаФайловДампов);
		
		Для Каждого ФайлДампа Из ФайлыДампов Цикл
			Если ФайлыДамповЗарегистрированные[ФайлДампа.ПолноеИмя] = Неопределено Тогда 
				ДампНовый = Новый Структура;
				СтруктураДампа = ОписаниеДампа(ФайлДампа.Имя);
				
				ДампНовый.Вставить("ДатаРегистрации", ТекущаяУниверсальнаяДатаВМиллисекундах());
				ДампНовый.Вставить("ВариантДампа", СтруктураДампа.Процесс + "_" + СтруктураДампа.ВерсияПлатформы + "_" + СтруктураДампа.Смещение);
				ДампНовый.Вставить("ВерсияПлатформы", ВерсияПлатформыВЧисло(СтруктураДампа.ВерсияПлатформы));
				ДампНовый.Вставить("ИмяФайла", ФайлДампа.ПолноеИмя);
				
				РегистрыСведений.ДампыПлатформы.ИзменитьЗапись(ДампНовый);
			КонецЕсли;
		КонецЦикла;
	Иначе
		УстановитьПараметрЦентраМониторинга("РегистрироватьДампы", Ложь);
	КонецЕсли;
	
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаРегистрацияДампов", ВремяНачала);
	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область РаботаСоСтатистикойКонфигурации

Процедура СобратьСтатистикуКонфигурации(ПараметрыЦентраМониторинга = Неопределено)
	Если ПараметрыЦентраМониторинга = Неопределено Тогда
		ПараметрыЦентраМониторинга.Вставить("РегистрироватьСтатистикуКонфигурации");
		ПараметрыЦентраМониторинга.Вставить("РегистрироватьНастройкуКонфигурации");
		ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	КонецЕсли;
	
	// Собирает базовую статистику по конфигурации
	// в случае существования подсистемы оценки производительности
	// замеряет длительность выполнения.
	//
#Область СтатистикаКонфигурацииБазовая
	
	Если ПараметрыЦентраМониторинга.РегистрироватьСтатистикуКонфигурации ИЛИ  ПараметрыЦентраМониторинга.РегистрироватьНастройкуКонфигурации Тогда
		
		НеобходимаЗаписьОценкиПроизводительности = Ложь;
		
		РегистрыСведений.СтатистикаКонфигурации.ОчиститьСтатистикуКонфигурации();
		
		ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
		Если ОценкаПроизводительностиСуществует Тогда
			МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
			ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
		КонецЕсли;
		
		Если ПараметрыЦентраМониторинга.РегистрироватьСтатистикуКонфигурации Тогда
			РегистрыСведений.СтатистикаКонфигурации.ЗаписатьСтатистикуКонфигурации();
			НеобходимаЗаписьОценкиПроизводительности = Истина;
		КонецЕсли;
		
		Если ПараметрыЦентраМониторинга.РегистрироватьНастройкуКонфигурации Тогда
			РегистрыСведений.СтатистикаКонфигурации.ЗаписатьНастройкиКонфигурации();
			ПолучитьСтатистикуИспользованияППД();
			НеобходимаЗаписьОценкиПроизводительности = Истина;
		КонецЕсли;
		
		Если ОценкаПроизводительностиСуществует И НеобходимаЗаписьОценкиПроизводительности Тогда
			МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаСобратьСтатистикуКонфигурацииБазовая", ВремяНачала);
		КонецЕсли;
	КонецЕсли;
	
#КонецОбласти
	
	// Собирает статистику по конфигурации
	// в случае существования подсистемы оценки производительности
	// замеряет длительность выполнения.
	//
#Область СтатистикаКонфигурацииСтандартныеПодсистемы
	
	Если ПараметрыЦентраМониторинга.РегистрироватьСтатистикуКонфигурации Тогда
		Если ОценкаПроизводительностиСуществует Тогда
			ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
		КонецЕсли;
		
		РазделениеПоОбластямДанныхВключено = РазделениеПоОбластямДанныхВключено();
		Если РазделениеПоОбластямДанныхВключено Тогда
			ОбластиДанныхРезультатЗапроса = РегистрыСведений.СтатистикаКонфигурации.ПолучитьОбластиДанныхРезультатЗапроса();
			Выборка = ОбластиДанныхРезультатЗапроса.Выбрать();
			Пока Выборка.Следующий() Цикл
				ОбластьДанныхСтрока = Строка(Выборка.ОбластьДанных);
				Если РегистрыСведений.ОбластиСтатистики.СобиратьСтатистикуКонфигурации(ОбластьДанныхСтрока) Тогда
					Попытка
						ВойтиВОбластьДанных(Выборка.ОбластьДанных);
					Исключение
						ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Статистика конфигурации переопределяемая'", 
							ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,,
							НСтр("ru = 'Не удалось установить разделение сеанса. Область данных'", ОбщегоНазначения.КодОсновногоЯзыка()) 
								+ " = " + Формат(Выборка.ОбластьДанных, "ЧГ=0") + Символы.ПС + ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
						ВыйтиИзОбластиДанных();
						Продолжить;
					КонецПопытки;
					
					ИнтеграцияПодсистемБСП.ПриСбореПоказателейСтатистикиКонфигурации();
					ЦентрМониторингаПереопределяемый.ПриСбореПоказателейСтатистикиКонфигурации();
					ВыйтиИзОбластиДанных();
				КонецЕсли;
			КонецЦикла;
		Иначе
			ИнтеграцияПодсистемБСП.ПриСбореПоказателейСтатистикиКонфигурации();
			ЦентрМониторингаПереопределяемый.ПриСбореПоказателейСтатистикиКонфигурации();
		КонецЕсли;
		
		Если ОценкаПроизводительностиСуществует Тогда
			МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаСобратьСтатистикуКонфигурацииСтандартныеПодсистемы", ВремяНачала);
		КонецЕсли;
	КонецЕсли;
	
#КонецОбласти
	
КонецПроцедуры

#КонецОбласти

#Область РаботаСПакетыДляОтправки

Процедура СформироватьПакетДляОтправки()
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	ТекДата = ТекущаяУниверсальнаяДата(); 
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга();
	
	Параметры = Новый Структура;
	Параметры.Вставить("ДатаНачала", Дата(1,1,1) + Цел((ПараметрыЦентраМониторинга.ДатаКрайнегоПакета - Дата(1,1,1))/ПараметрыЦентраМониторинга.ПериодУдаления) * ПараметрыЦентраМониторинга.ПериодУдаления);
	Параметры.Вставить("ДатаОкончания", Дата(1,1,1) + Цел((ТекДата - Дата(1,1,1))/ПараметрыЦентраМониторинга.ПериодУдаления) * ПараметрыЦентраМониторинга.ПериодУдаления - 1);
	Параметры.Вставить("ДатаЗапуска", ТекДата);
	Параметры.Вставить("ТопДамповКоличество", 5);
	Параметры.Вставить("TopApdex", ПараметрыЦентраМониторинга.TopApdex);
	Параметры.Вставить("TopApdexTech", ПараметрыЦентраМониторинга.TopApdexTech);
	Параметры.Вставить("ПериодУдаления", ПараметрыЦентраМониторинга.ПериодУдаления);
	Параметры.Вставить("РезультатОтправки", ПараметрыЦентраМониторинга.РезультатОтправки);
	Параметры.Вставить("ОтправлятьФайлыДампов", ПараметрыЦентраМониторинга.ОтправлятьФайлыДампов);
	Параметры.Вставить("СпрашиватьПередОтправкой", ПараметрыЦентраМониторинга.СпрашиватьПередОтправкой);
	// Контактная информация.
	Параметры.Вставить("ЗапросКонтактнойИнформации", ПараметрыЦентраМониторинга.ЗапросКонтактнойИнформации);
	Параметры.Вставить("КонтактнаяИнформация", ПараметрыЦентраМониторинга.КонтактнаяИнформация);
	Параметры.Вставить("КонтактнаяИнформацияКомментарий", ПараметрыЦентраМониторинга.КонтактнаяИнформацияКомментарий);
	Параметры.Вставить("ЛогинПортала", ПараметрыЦентраМониторинга.ЛогинПортала);
	Параметры.Вставить("КонтактнаяИнформацияИзменена", ПараметрыЦентраМониторинга.КонтактнаяИнформацияИзменена);
		
	НачатьТранзакцию();
	Попытка
		JSONСтруктура = СформироватьСтруктуруJSONДляОтправки(Параметры);
		РегистрыСведений.ПакетыДляОтправки.ЗаписатьНовыйПакет(ТекДата, JSONСтруктура, ПараметрыЦентраМониторинга.НомерКрайнегоПакета + 1);
		
		ПараметрыЦентраМониторингаЗапись = Новый Структура("ДатаКрайнегоПакета, НомерКрайнегоПакета");
		ПараметрыЦентраМониторингаЗапись.ДатаКрайнегоПакета = ТекДата;
		ПараметрыЦентраМониторингаЗапись.НомерКрайнегоПакета = ПараметрыЦентраМониторинга.НомерКрайнегоПакета + 1;
		УстановитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторингаЗапись);
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Формирование пакета для отправки'", 
			ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, 
			ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ВызватьИсключение;
	КонецПопытки;
	
	РегистрыСведений.ПакетыДляОтправки.УдалитьСтарыеПакеты();
	
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаСформироватьПакетДляОтправки", ВремяНачала);
	КонецЕсли;
КонецПроцедуры

Функция ОтправитьДанныеМониторинга(ТестовыйПакет = Ложь)
	Параметры = ПолучитьПараметрыСервисаОтправки();
	
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	НомераПакетовДляОтправки = РегистрыСведений.ПакетыДляОтправки.ПолучитьНомераПакетов();
	Для Каждого НомерПакета Из НомераПакетовДляОтправки Цикл
		Пакет = РегистрыСведений.ПакетыДляОтправки.ПолучитьПакет(НомерПакета);
		Если Пакет <> Неопределено Тогда
						
			ХешПакета = Пакет.ХешПакета;
			НомерПакетаДляОтправки = Формат(Пакет.НомерПакета, "ЧН=0; ЧГ=0");
			Идентификатор = Строка(Параметры.ИдентификаторИнформационнойБазы);
			
			АдресРесурса = Параметры.АдресРесурса;
			Если Прав(АдресРесурса, 1) <> "/" Тогда
				АдресРесурса = АдресРесурса + "/";
			КонецЕсли;
			АдресРесурса = АдресРесурса + Идентификатор + "/" + НомерПакетаДляОтправки + "/" + ХешПакета;
			
			ПараметрыHTTP = Новый Структура;
			ПараметрыHTTP.Вставить("Сервер", Параметры.Сервер);
			ПараметрыHTTP.Вставить("АдресРесурса", АдресРесурса);
			ПараметрыHTTP.Вставить("Данные", Пакет.ТелоПакета);
			ПараметрыHTTP.Вставить("Порт", Параметры.Порт);
			ПараметрыHTTP.Вставить("ЗащищенноеСоединение", Параметры.ЗащищенноеСоединение);	
			ПараметрыHTTP.Вставить("Метод", "POST");
			ПараметрыHTTP.Вставить("ТипДанных", "Текст");
			ПараметрыHTTP.Вставить("Таймаут", 60);
			
			HTTPОтвет = HTTPСервисОтправитьДанныеСлужебный(ПараметрыHTTP);
			
			Если HTTPОтвет.КодСостояния = 200 Тогда
				ПараметрыОтвета = ОбщегоНазначения.JSONВЗначение(HTTPОтвет.Тело, , Ложь);
				Если Не ТестовыйПакет Тогда
					УстановитьПараметрыОтправки(ПараметрыОтвета);
				Иначе
					Если ПараметрыОтвета.Свойство("foundCopy") И ПараметрыОтвета.foundCopy Тогда
						ВыполнитьДействияПриОбнаруженииКопии();
					Иначе
						УстановитьПараметрЦентраМониторинга("ОзнакомительныйПакетОтправлен", Истина);
					КонецЕсли;						
				КонецЕсли;
				РегистрыСведений.ПакетыДляОтправки.УдалитьПакет(НомерПакета);
			Иначе
				Прервать;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаОтправитьДанныеМониторинга", ВремяНачала);
	КонецЕсли;
	
	Возврат HTTPОтвет;
КонецФункции

#КонецОбласти

#Область РаботаСПараметрамиЦентраМониторинга

Функция ВыполнятьЗамерыПроизводительности()
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительностиВызовСервераПовтИсп = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительностиВызовСервераПовтИсп");
		ВыполнятьЗамерыПроизводительности = МодульОценкаПроизводительностиВызовСервераПовтИсп.ВыполнятьЗамерыПроизводительности();
	Иначе
		ВыполнятьЗамерыПроизводительности = Неопределено;
	КонецЕсли;
	
	Возврат ВыполнятьЗамерыПроизводительности;
КонецФункции

Функция ПолучитьПараметрыПоУмолчанию()
	ПараметрыКонстанты = Новый Структура;
	
	// Параметры сбора информации о системе.
	//
	ПараметрыКонстанты.Вставить("ВключитьЦентрМониторинга", Ложь);
	
	// Признак центра обработки
	// Истина	- сторонний разработчик.
	//
	ПараметрыКонстанты.Вставить("ЦентрОбработкиИнформацииОПрограмме", Ложь);
	
	// Идентификатор информационной базы.
	//
	ИдентификаторИнформационнойБазы = Новый УникальныйИдентификатор();
	ПараметрыКонстанты.Вставить("ИдентификаторИнформационнойБазы", ИдентификаторИнформационнойБазы);
	ПараметрыКонстанты.Вставить("ИдентификаторИнформационнойБазыПостоянный", ИдентификаторИнформационнойБазы);
	
	// Параметры сбора информации о системе.
	//
	ПараметрыКонстанты.Вставить("РегистрироватьИнформациюОСистеме", Ложь);
	
	// Параметры сбора информации о версиях подсистем.
	//
	ПараметрыКонстанты.Вставить("РегистрироватьВерсииПодсистем", Ложь);
	
	// Параметры сбора дампов
	//
	ПараметрыКонстанты.Вставить("РегистрацияДамповСледующееФормирование", Дата(1,1,1));
	ПараметрыКонстанты.Вставить("РегистрацияДамповПериодФормирования", 600);
	ПараметрыКонстанты.Вставить("РегистрироватьДампы", Ложь);
	
	// Параметры сбора бизнес статистики.
	//
	ПараметрыКонстанты.Вставить("ПериодАгрегацииМалый", 60);
	ПараметрыКонстанты.Вставить("ПериодАгрегации", 600);
	ПараметрыКонстанты.Вставить("ПериодУдаления", 3600);
	ПараметрыКонстанты.Вставить("ГраницаАгрегирования", Дата(1,1,1));
	ПараметрыКонстанты.Вставить("БизнесСтатистикаСледующееФормирование", Дата(1,1,1));
	ПараметрыКонстанты.Вставить("БизнесСтатистикаПериодФормирования", 600);
	ПараметрыКонстанты.Вставить("РегистрироватьБизнесСтатистику", Ложь);
	
	// Параметры сбора статистики конфигурации.
	//
	ПараметрыКонстанты.Вставить("СтатистикаКонфигурацииСледующееФормирование", Дата(1,1,1));
	ПараметрыКонстанты.Вставить("СтатистикаКонфигурацииПериодФормирования", 86400);
	ПараметрыКонстанты.Вставить("РегистрироватьСтатистикуКонфигурации", Ложь);
	ПараметрыКонстанты.Вставить("РегистрироватьНастройкуКонфигурации", Ложь);
	
	// Параметры сбора производительности.
	// 	Если параметр ОценкаПроизводительностиВключена равен нулю, тогда выключена.
	// 	Если параметр ОценкаПроизводительностиВключена равен единице, тогда включена центром мониторинга.
	// 	Если параметр ОценкаПроизводительностиВключена равен двум, тогда включена оценкой производительности.
	// 	Если параметр ОценкаПроизводительностиВключена равен трем, тогда выключена оценкой производительности.
	//
	ПараметрыКонстанты.Вставить("ОценкаПроизводительностиВключена", 0);
	
	ПараметрыКонстанты.Вставить("РегистрироватьПроизводительность", Ложь);
	ПараметрыКонстанты.Вставить("TopApdex", 10);
	ПараметрыКонстанты.Вставить("РегистрироватьПроизводительностьТехнологическую", Ложь);
	ПараметрыКонстанты.Вставить("TopApdexTech", 10);
	ПараметрыКонстанты.Вставить("ВыполнятьЗамерыПроизводительности", ВыполнятьЗамерыПроизводительности());
	
	// Параметры отправки данных
	//
	ПараметрыКонстанты.Вставить("ОтправкаДанныхСледующееФормирование", Дата(1,1,1));
	ПараметрыКонстанты.Вставить("ОтправкаДанныхПериодФормирования", 607800);
	ПараметрыКонстанты.Вставить("ДатаКрайнегоПакета", Дата(1,1,1));
	ПараметрыКонстанты.Вставить("СтатистикаКонфигурацииСледующаяОтправка", Дата(2010,1,1));
	ПараметрыКонстанты.Вставить("СтатистикаКонфигурацииПериодОтправки", 607800);	
	ПараметрыКонстанты.Вставить("НомерКрайнегоПакета", 0);
	ПараметрыКонстанты.Вставить("ПакетовДляОтправки", 3);
	ПараметрыКонстанты.Вставить("Сервер", "pult.1c.com");
	ПараметрыКонстанты.Вставить("АдресРесурса", "pult/v1/packet/");
	ПараметрыКонстанты.Вставить("АдресРесурсаДляДампов", "pult/v1/dump/");
	ПараметрыКонстанты.Вставить("Порт", 443);
	ПараметрыКонстанты.Вставить("ЗащищенноеСоединение", Истина);
	
	// Параметры сбора и отправки отчетов об ошибках (дампов).
	//
	// ОтправлятьФайлыДампов
	//	0 - нет,
	//  1 - да,
	//  2 - нет ответа на вопрос, еще никогда не спрашивали.
	ПараметрыКонстанты.Вставить("ОтправлятьФайлыДампов", 2);
	ПараметрыКонстанты.Вставить("ВариантДампа", "");
	// Факт прохождения базовых проверок, например, свободное место и права на изменение файла логов.
	// По сути нужен для формирования оповещений.
	ПараметрыКонстанты.Вставить("БазовыеПроверкиПройдены", Ложь); 
	ПараметрыКонстанты.Вставить("СпрашиватьПередОтправкой", Истина);
	ПараметрыКонстанты.Вставить("РезультатОтправки", "");
	ПараметрыКонстанты.Вставить("ИнформацияОДампах", ""); // Информация, которая будет представлена пользователю при согласовании отправки.
	ПараметрыКонстанты.Вставить("РезервМестаВыключен", 40);
	ПараметрыКонстанты.Вставить("РезервМестаВключен", 20);
	ПараметрыКонстанты.Вставить("ОкончаниеСбораДампов", Дата(2017,1,1));
	// Хранит список компьютеров, где включен сбор полных, (а иногда - мини) дампов.
	ПараметрыКонстанты.Вставить("СборПолныхДамповВключен", Новый Соответствие);
	ПараметрыКонстанты.Вставить("ВариантыДампов", Новый Соответствие);
	ПараметрыКонстанты.Вставить("ВариантыДамповОдобренные", Новый Соответствие);
	// Параметры проверки частоты падения дампов.
	ПараметрыКонстанты.Вставить("ГлубинаПроверкиДампов", 604800);
	ПараметрыКонстанты.Вставить("МинимальноеКоличествоДампов", 10000);
	ПараметрыКонстанты.Вставить("ПроверкаДамповСледующая", Дата(1,1,1));
	ПараметрыКонстанты.Вставить("ПроверкаДамповПериодичность", 14400);
	// Определяет тип собираемых дампов. По умолчанию - минидампы.
	ПараметрыКонстанты.Вставить("ТипДампа", "0"); // "0" - минидамп, "3" - полный дамп.
	
	// Принудительная отправка мини дампов.
	ПараметрыКонстанты.Вставить("ТаймаутОтветаПользователя", 14); // Сколько дней ждать ответа Администратора, в днях.
	ПараметрыКонстанты.Вставить("ПринудительнаяОтправкаМинидампов", 0); // Сколько дней ждать ответа Администратора, в днях.
	ПараметрыКонстанты.Вставить("ДатаОповещения", Дата(1,1,1)); // Дата регистрации запроса дампов или оповещения о дампах.
	
	
	// Параметры отправки тестового пакета.
	//
	ПараметрыКонстанты.Вставить("ТестовыйПакетОтправлен", Ложь);
	ПараметрыКонстанты.Вставить("ЧислоПопытокОтправкиТестовогоПакета", 0);
	
	// Параметры отправки ознакомительного пакета (для получения идентификатора.
	//
	ПараметрыКонстанты.Вставить("ОзнакомительныйПакетОтправлен", Ложь);
	
	// Настройки обработки ошибок.
	//
	ПараметрыКонстанты.Вставить("УстановитьНастройкиОбработкиОшибокПринудительно", Ложь); // УстановитьНастройкиОбработкиОшибокПринудительно.
	ПараметрыКонстанты.Вставить("ВариантОтображенияСообщенияОбОшибке", "Авто"); // ВариантОтображенияСообщенияОбОшибке.
	ПараметрыКонстанты.Вставить("АдресСервисаРегистрацииОшибок", ""); // АдресСервисаРегистрацииОшибок.
	ПараметрыКонстанты.Вставить("ОтправлятьОтчет", "Авто"); // ОтправлятьОтчет.
	ПараметрыКонстанты.Вставить("ВключатьПодробныйТекстОшибкиВОтчет", "Авто"); // ВключатьПодробныйТекстОшибкиВОтчет.
	ПараметрыКонстанты.Вставить("ВключатьСведенияОбИнформационнойБазеВОтчет", "Авто"); // ВключатьСведенияОбИнформационнойБазеВОтчет.
	
	// Параметры получения контактной информации.
	//
	// ЗапросКонтактнойИнформации
	//	0 - Пользователь отказался,
	//  1 - Пользователь согласился,
	//  2 - нет ответа на вопрос, еще никогда не спрашивали.
	//  3 - получен запрос на предоставление контактной информации.
	ПараметрыКонстанты.Вставить("ЗапросКонтактнойИнформации", 2);
	ПараметрыКонстанты.Вставить("КонтактнаяИнформация", "");
	ПараметрыКонстанты.Вставить("КонтактнаяИнформацияКомментарий", "");
	ПараметрыКонстанты.Вставить("ЛогинПортала", "");
	ПараметрыКонстанты.Вставить("КонтактнаяИнформацияИзменена", Ложь);
	
	Возврат ПараметрыКонстанты; 
КонецФункции

Функция ПолучитьПараметрыЦентраМониторинга(Параметры = Неопределено) Экспорт
	ПараметрыКонстанты = Константы.ПараметрыЦентраМониторинга.Получить().Получить();
	Если ПараметрыКонстанты = Неопределено Тогда
		ПараметрыКонстанты = Новый Структура;
	КонецЕсли;
	
	ПараметрыПоУмолчанию = ПолучитьПараметрыПоУмолчанию();
	
	Для Каждого ТекПараметр Из ПараметрыПоУмолчанию Цикл
		Если НЕ ПараметрыКонстанты.Свойство(ТекПараметр.Ключ) Тогда
			ПараметрыКонстанты.Вставить(ТекПараметр.Ключ, ТекПараметр.Значение);
		КонецЕсли;
	КонецЦикла;
	
	Если ПараметрыКонстанты = Неопределено Тогда
		ПараметрыКонстанты = ПараметрыПоУмолчанию;
	КонецЕсли;
	
	Если Параметры = Неопределено Тогда
		Параметры = ПараметрыКонстанты;
	Иначе
		Если ТипЗнч(Параметры) = Тип("Структура") Тогда
			Для Каждого ТекПараметр Из Параметры Цикл
				Параметры[ТекПараметр.Ключ] = ПараметрыКонстанты[ТекПараметр.Ключ];
			КонецЦикла;
		ИначеЕсли ТипЗнч(Параметры) = Тип("Строка") Тогда
			Параметры = ПараметрыКонстанты[Параметры];
		КонецЕсли;
	КонецЕсли;
	
	ПараметрыКонстанты.Вставить("ВыполнятьЗамерыПроизводительности", ВыполнятьЗамерыПроизводительности());
	
	Возврат Параметры;
КонецФункции

Функция УстановитьПараметрыОтправки(Параметры)
	ПараметрыОтправки = Новый Структура;
	ПараметрыОтправки.Вставить("ОценкаПроизводительностиВключена");
	ПараметрыОтправки.Вставить("ВыполнятьЗамерыПроизводительности");
	ПараметрыОтправки.Вставить("УстановитьНастройкиОбработкиОшибокПринудительно");
	ПолучитьПараметрыЦентраМониторинга(ПараметрыОтправки);
	
	ПараметрыОтправки.Вставить("РегистрироватьИнформациюОСистеме", Ложь);
	ПараметрыОтправки.Вставить("РегистрироватьВерсииПодсистем", Ложь);
	ПараметрыОтправки.Вставить("РегистрироватьДампы", Ложь);
	ПараметрыОтправки.Вставить("РегистрироватьБизнесСтатистику", Ложь);
	ПараметрыОтправки.Вставить("РегистрироватьСтатистикуКонфигурации", Ложь);
	ПараметрыОтправки.Вставить("РегистрироватьНастройкуКонфигурации", Ложь);
	ПараметрыОтправки.Вставить("РегистрироватьПроизводительность", Ложь);
	ПараметрыОтправки.Вставить("РегистрироватьПроизводительностьТехнологическую", Ложь);
	ПараметрыОтправки.Вставить("РезультатОтправки", ""); // Результат отправки дампа обнуляем при успешной отправке пакета.
	ПараметрыОтправки.Вставить("ОзнакомительныйПакетОтправлен", Истина); // Если ответ от сервиса получен, то всегда истина.
	ПараметрыОтправки.Вставить("КонтактнаяИнформацияИзменена", Ложь);  // Признак изменения контактов всегда снимаем при успешной отправке.
	
	СоответствиеПараметров = Новый Структура;
	СоответствиеПараметров.Вставить("info", "РегистрироватьИнформациюОСистеме");
	СоответствиеПараметров.Вставить("versions", "РегистрироватьВерсииПодсистем");
	СоответствиеПараметров.Вставить("dumps", "РегистрироватьДампы");
	СоответствиеПараметров.Вставить("business", "РегистрироватьБизнесСтатистику");
	СоответствиеПараметров.Вставить("config", "РегистрироватьСтатистикуКонфигурации");
	СоответствиеПараметров.Вставить("options", "РегистрироватьНастройкуКонфигурации");
	СоответствиеПараметров.Вставить("perf", "РегистрироватьПроизводительность");
	СоответствиеПараметров.Вставить("internal_perf", "РегистрироватьПроизводительностьТехнологическую");
	
	Настройки = Параметры.packetProperties;
	Для Каждого ТекНастройка Из Настройки Цикл
		Если СоответствиеПараметров.Свойство(ТекНастройка) Тогда
			Ключ = СоответствиеПараметров[ТекНастройка];
			
			Если ПараметрыОтправки.Свойство(Ключ) Тогда
				ПараметрыОтправки[Ключ] = Истина;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Если Параметры.Свойство("settings") Тогда
		НастройкиНовые = Параметры.settings;
		НастройкиНовые = СтрЗаменить(НастройкиНовые, ";", Символы.ПС);
		НастройкиПоУмолчанию = ПолучитьПараметрыПоУмолчанию();
		Для ТекСтрока = 1 По СтрЧислоСтрок(НастройкиНовые) Цикл
			ТекНастройка = СтрПолучитьСтроку(НастройкиНовые, ТекСтрока);
			ТекНастройка = СтрЗаменить(ТекНастройка, "=", Символы.ПС);
			
			Ключ = СтрПолучитьСтроку(ТекНастройка, 1);
			Ключ = КлючДляВходящихНастроек(Ключ);
			Значение = СтрПолучитьСтроку(ТекНастройка, 2);
			
			Если НастройкиПоУмолчанию.Свойство(Ключ) Тогда
				Если ТипЗнч(НастройкиПоУмолчанию[Ключ]) = Тип("Число") Тогда
					ОписаниеЧисло = Новый ОписаниеТипов("Число");
					ПриведенноеЗначение = ОписаниеЧисло.ПривестиЗначение(Значение);
					Если Формат(ПриведенноеЗначение, "ЧН=0; ЧГ=") = Значение Тогда
						ПараметрыОтправки.Вставить(Ключ, ПриведенноеЗначение);
					КонецЕсли;
				ИначеЕсли ТипЗнч(НастройкиПоУмолчанию[Ключ]) = Тип("Строка") Тогда
					ПараметрыОтправки.Вставить(Ключ, Значение);
				ИначеЕсли ТипЗнч(НастройкиПоУмолчанию[Ключ]) = Тип("Булево") Тогда
					ОписаниеБулево = Новый ОписаниеТипов("Булево");
					ПриведенноеЗначение = ОписаниеБулево.ПривестиЗначение(Значение);
					Если Формат(ПриведенноеЗначение, "БЛ=false; БИ=true") = Значение Тогда
						ПараметрыОтправки.Вставить(Ключ, ПриведенноеЗначение);
					КонецЕсли;
				ИначеЕсли ТипЗнч(НастройкиПоУмолчанию[Ключ]) = Тип("Дата") Тогда
					ОписаниеДата = Новый ОписаниеТипов("Дата");
					ПриведенноеЗначение = ОписаниеДата.ПривестиЗначение(Значение);
					Если Формат(ПриведенноеЗначение, "ДФ=ггггММддЧЧммсс") = Значение Тогда
						ПараметрыОтправки.Вставить(Ключ, ПриведенноеЗначение);
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Если Параметры.Свойство("deliveryIntervalHours") Тогда
		ПараметрыОтправки.Вставить("ОтправкаДанныхПериодФормирования", Параметры.deliveryIntervalHours * 60 * 60);
	КонецЕсли;
	
	Если ПараметрыОтправки["РегистрироватьПроизводительность"] ИЛИ ПараметрыОтправки["РегистрироватьПроизводительностьТехнологическую"] Тогда
		// Подсистемы оценки производительности нет.
		Если ПараметрыОтправки.ВыполнятьЗамерыПроизводительности = Неопределено Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 0;
		// Выключена.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 0 И НЕ ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 1;
		// Включена оценкой производительности.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 0 И ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 2;
		// Включена центром мониторинга ранее и отключен позже, то выключаем сбор
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 1 И НЕ ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 3;
		// Включена центром мониторинга.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 1 И ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 1;
		// Включен был оценкой производительности, но потом выключен.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 2 И НЕ ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 3;
		// Включен оценкой производительности.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 2 И ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 2;
		// Был выключен, но потом включили в оценке производительности.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 3 И ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 2;
		КонецЕсли;
	Иначе
		// Подсистемы оценки производительности нет.
		Если ПараметрыОтправки.ВыполнятьЗамерыПроизводительности = Неопределено Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 0;
		// Выключена.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 0 И НЕ ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 0;
		// Включена оценкой производительности.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 0 И ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 2;
		// Включена центром мониторинга.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 1 И НЕ ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 0;
		// Включена центром мониторинга.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 1 И ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 0;
		// Включен был оценкой производительности, но потом выключен.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 2 И НЕ ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 0;
		// Включен оценкой производительности.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 2 И ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 2;
		// Был выключен, но потом включили в оценке производительности.
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 3 И ПараметрыОтправки.ВыполнятьЗамерыПроизводительности Тогда
			ПараметрыОтправки.ОценкаПроизводительностиВключена = 2;
		КонецЕсли;
	КонецЕсли;
	
	Если Параметры.Свойство("foundCopy") И Параметры.foundCopy Тогда
		ВыполнитьДействияПриОбнаруженииКопии();
		ПараметрыОтправки.Вставить("ОзнакомительныйПакетОтправлен", Ложь);
	КонецЕсли;
	
	// Настройки обработки ошибок.
	// 	
	СохраненныеПараметрыОтправки = Новый Структура;
	СохраненныеПараметрыОтправки.Вставить("УстановитьНастройкиОбработкиОшибокПринудительно");
	СохраненныеПараметрыОтправки.Вставить("ВариантОтображенияСообщенияОбОшибке"); 
	СохраненныеПараметрыОтправки.Вставить("АдресСервисаРегистрацииОшибок");
	СохраненныеПараметрыОтправки.Вставить("ОтправлятьОтчет");
	СохраненныеПараметрыОтправки.Вставить("ВключатьПодробныйТекстОшибкиВОтчет");
	СохраненныеПараметрыОтправки.Вставить("ВключатьСведенияОбИнформационнойБазеВОтчет");
	ПолучитьПараметрыЦентраМониторинга(СохраненныеПараметрыОтправки);
	РезультатОбработки = УстановкаНастроекОбработкиОшибок(СохраненныеПараметрыОтправки, ПараметрыОтправки);
	Для Каждого КлючИЗапись Из РезультатОбработки Цикл
		ПараметрыОтправки.Вставить(КлючИЗапись.Ключ, КлючИЗапись.Значение);	
	КонецЦикла;

	НачатьТранзакцию();
	Попытка
		Если ПараметрыОтправки.ОценкаПроизводительностиВключена = 0 И НЕ ПараметрыОтправки.ВыполнятьЗамерыПроизводительности = Неопределено Тогда
			МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
			МодульОценкаПроизводительности.ВключитьЗамерыПроизводительности(Ложь);
		ИначеЕсли ПараметрыОтправки.ОценкаПроизводительностиВключена = 1 И НЕ ПараметрыОтправки.ВыполнятьЗамерыПроизводительности = Неопределено Тогда
			МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");	
			МодульОценкаПроизводительности.ВключитьЗамерыПроизводительности(Истина);
		КонецЕсли;
		
		УстановитьПараметрыЦентраМониторинга(ПараметрыОтправки);
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Установка параметров отправки'", 
			ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, 
			ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ВызватьИсключение;
	КонецПопытки;
	
	Возврат ПараметрыОтправки;
	
КонецФункции

Функция КлючДляВходящихНастроек(Ключ)
	Соответствие = Новый Соответствие;
	Соответствие.Вставить("SetErrorProcessingSettingsForcibly","УстановитьНастройкиОбработкиОшибокПринудительно");
	Соответствие.Вставить("ErrorMessageDisplayVariant","ВариантОтображенияСообщенияОбОшибке");
	Соответствие.Вставить("ErrorRegistrationServiceURL","АдресСервисаРегистрацииОшибок");
	Соответствие.Вставить("SendReport","ОтправлятьОтчет");
	Соответствие.Вставить("IncludeDetailErrorDescriptionInReport","ВключатьПодробныйТекстОшибкиВОтчет");
	Соответствие.Вставить("IncludeInfobaseInformationInReport","ВключатьСведенияОбИнформационнойБазеВОтчет");	
	
	Соответствие.Вставить("ErrorMessageDisplayVariant","ВариантОтображенияСообщенияОбОшибке");
	Соответствие.Вставить("ErrorProcessingServiceURL","АдресСервисаОбработкиОшибок");
	Соответствие.Вставить("SendReportOnClient","ОтправлятьОтчетНаКлиенте");
	Соответствие.Вставить("SendReportOnServer","ОтправлятьОтчетНаСервере");
	Соответствие.Вставить("IncludeDetailErrorDescriptionInReportOnClient","ВключатьПодробныйТекстОшибкиВОтчетНаКлиенте");
	Соответствие.Вставить("IncludeDetailErrorDescriptionInReportOnServer","ВключатьПодробныйТекстОшибкиВОтчетНаСервере");
	Соответствие.Вставить("IncludeInfobaseInformationInReportOnClient","ВключатьСведенияОбИнформационнойБазеВОтчетНаКлиенте");
	Соответствие.Вставить("IncludeInfobaseInformationInReportOnServer","ВключатьСведенияОбИнформационнойБазеВОтчетНаСервере");
	Значение = Соответствие.Получить(Ключ);
	Если Значение = Неопределено Тогда
		Возврат Ключ
	КонецЕсли;
	Возврат Значение;
КонецФункции

Процедура УстановитьПараметрыЦентраМониторинга(НовыеПараметры)
	
	Блокировка = Новый БлокировкаДанных;
	Блокировка.Добавить("Константа.ПараметрыЦентраМониторинга");
	
	НачатьТранзакцию();
	
	Попытка
		Блокировка.Заблокировать();
		Параметры = ПолучитьПараметрыЦентраМониторинга();
		
		Если НовыеПараметры.Свойство("ВыполнятьЗамерыПроизводительности") Тогда
			НовыеПараметры.Удалить("ВыполнятьЗамерыПроизводительности");
		КонецЕсли;
				
		Для Каждого ТекПараметр Из НовыеПараметры Цикл
			Если НЕ Параметры.Свойство(ТекПараметр.Ключ) Тогда
				Параметры.Вставить(ТекПараметр.Ключ);
			КонецЕсли;
			
			Параметры[ТекПараметр.Ключ] = ТекПараметр.Значение;
		КонецЦикла;
		
		Хранилище = Новый ХранилищеЗначения(Параметры, Новый СжатиеДанных(9));
		Константы.ПараметрыЦентраМониторинга.Установить(Хранилище);
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Установка параметров центра мониторинга'", 
			ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка, 
			Метаданные.Константы.ПараметрыЦентраМониторинга,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

Процедура УдалитьПараметрыЦентраМониторинга()
	Параметры = Новый Структура;
	Хранилище = Новый ХранилищеЗначения(Параметры, Новый СжатиеДанных(9));
	Попытка
		Константы.ПараметрыЦентраМониторинга.Установить(Хранилище);
	Исключение
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Удалить параметры центра мониторинга'", 
			ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка, 
			Метаданные.Константы.ПараметрыЦентраМониторинга,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ВызватьИсключение;
	КонецПопытки;
КонецПроцедуры

Процедура УстановитьПараметрЦентраМониторинга(Параметр, Значение)
	
	Блокировка = Новый БлокировкаДанных;
	Блокировка.Добавить("Константа.ПараметрыЦентраМониторинга");
	
	НачатьТранзакцию();
	Попытка
		Блокировка.Заблокировать();
		Параметры = ПолучитьПараметрыЦентраМониторинга();
		
		Если НЕ Параметры.Свойство(Параметр) Тогда
			Параметры.Вставить(Параметр);
		КонецЕсли;
		
		Параметры[Параметр] = Значение;
		Хранилище = Новый ХранилищеЗначения(Параметры, Новый СжатиеДанных(9));
		Константы.ПараметрыЦентраМониторинга.Установить(Хранилище);
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Установка параметров центра мониторинга'", 
			ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка, 
			Метаданные.Константы.ПараметрыЦентраМониторинга,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

Функция ПолучитьПараметрыСервисаОтправки()
	ПараметрыСервиса = Новый Структура;
	
	ПараметрыСервиса.Вставить("ВключитьЦентрМониторинга");
	ПараметрыСервиса.Вставить("ЦентрОбработкиИнформацииОПрограмме");
	ПараметрыСервиса.Вставить("ИдентификаторИнформационнойБазы");
	ПараметрыСервиса.Вставить("Сервер");
	ПараметрыСервиса.Вставить("АдресРесурса");
	ПараметрыСервиса.Вставить("АдресРесурсаДляДампов");
	ПараметрыСервиса.Вставить("Порт");
	ПараметрыСервиса.Вставить("ЗащищенноеСоединение");
	
	ПолучитьПараметрыЦентраМониторинга(ПараметрыСервиса);
	
	Если ПараметрыСервиса.ВключитьЦентрМониторинга И НЕ ПараметрыСервиса.ЦентрОбработкиИнформацииОПрограмме Тогда
		ПараметрыСервисаПоУмолчанию = ПолучитьПараметрыПоУмолчанию();
		
		ПараметрыСервиса.Вставить("Сервер", ПараметрыСервисаПоУмолчанию.Сервер);
		ПараметрыСервиса.Вставить("АдресРесурса", ПараметрыСервисаПоУмолчанию.АдресРесурса);
		ПараметрыСервиса.Вставить("АдресРесурсаДляДампов", ПараметрыСервисаПоУмолчанию.АдресРесурсаДляДампов);
		ПараметрыСервиса.Вставить("Порт", ПараметрыСервисаПоУмолчанию.Порт);
		ПараметрыСервиса.Вставить("ЗащищенноеСоединение", ПараметрыСервисаПоУмолчанию.ЗащищенноеСоединение);
	КонецЕсли;
	
	ПараметрыСервиса.Удалить("ВключитьЦентрМониторинга");
	ПараметрыСервиса.Удалить("ЦентрОбработкиИнформацииОПрограмме");
	
	Возврат ПараметрыСервиса;
КонецФункции

#КонецОбласти

#Область РаботаСФайломНастроек

// Получает каталог сбора дампов на сервере. 
//
// Возвращаемое значение:
//   Структура:
//     * Путь - Строка -  путь к каталогу дампов.
//     * УдалятьДампы - Булево - признак удаления дампов.
//     * ОписаниеОшибки - Строка - содержит путь к каталогу дампов.
//
Функция ПолучитьКаталогДампов(ТипДампа = "0", ПрекратитьСборПолных = Ложь) Экспорт // АПК:581 Экспортная для проведения тестирования обработкой.
	КаталогНастроек = ПолучитьКаталогНастроекТехнологическогоЖурнала();
	КаталогДампов = НайтиКаталогДампов(КаталогНастроек, ТипДампа, ПрекратитьСборПолных);
	
	Возврат КаталогДампов;
КонецФункции

Функция СформироватьПутьСРазделителем(Путь)
	Если ЗначениеЗаполнено(Путь) Тогда
		РазделительПути = ПолучитьРазделительПутиСервера();
		Если Прав(Путь, 1) <> РазделительПути Тогда
			Путь = Путь + РазделительПути;
		КонецЕсли;
	КонецЕсли;
	
	Возврат Путь;
КонецФункции

Функция НайтиКаталогДампов(КаталогНастроек, ТипДампа, ПрекратитьСборПолных) 
	КаталогДампов = Новый Структура("Путь, УдалятьДампы, ОписаниеОшибки", "", Ложь, "");
	
	ИмяФайлаНастроек = "logcfg.xml";
	ПутьКаталога = СформироватьПутьСРазделителем(КаталогНастроек.Путь);
	
	СборПолныхДамповВключен = ПолучитьПараметрыЦентраМониторинга("СборПолныхДамповВключен")[ИмяКомпьютера()];
		
	Файл = Новый Файл(ПутьКаталога + ИмяФайлаНастроек);
	Если Файл.Существует() Тогда
		Попытка
			ЧтениеXML = Новый ЧтениеXML;
			ЧтениеXML.ОткрытьФайл(Файл.ПолноеИмя, Новый ПараметрыЧтенияXML(,,,,,,,Истина, Истина));
			Пока ЧтениеXML.Прочитать() Цикл
				Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеXML.ИмеетИмя И ВРЕГ(ЧтениеXML.Имя) = "DUMP" Тогда
					ПараметрыДампов = Новый Структура;
					Если ЧтениеXML.КоличествоАтрибутов() > 0 Тогда
						Пока ЧтениеXML.ПрочитатьАтрибут() Цикл
							ПараметрыДампов.Вставить(ЧтениеXML.ЛокальноеИмя, ЧтениеXML.Значение);
						КонецЦикла;
					КонецЕсли;
				КонецЕсли;
			КонецЦикла;
		Исключение
			Сообщение = НСтр("ru = 'Ошибка чтения файла настроек технологического журнала'");
			Сообщение = Сообщение + " """ +Файл.ПолноеИмя + """." + Символы.ПС;
			Сообщение = Сообщение + НСтр("ru = 'Скорее всего файл поврежден. Регистрация дампов не возможна. Удалите поврежденный файл или восстановите настройки.'");
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга'", ОбщегоНазначения.КодОсновногоЯзыка()), 
				УровеньЖурналаРегистрации.Предупреждение,,, Сообщение);
			
			КаталогДампов.Путь = Неопределено;
			КаталогДампов.ОписаниеОшибки = НСтр("ru = 'Ошибка чтения файла настроек технологического журнала'");
			Возврат КаталогДампов;
		КонецПопытки;
		
		Если ПараметрыДампов <> Неопределено Тогда
			Если НЕ ПараметрыДампов.Свойство("location") ИЛИ НЕ ПараметрыДампов.Свойство("create") ИЛИ НЕ ПараметрыДампов.Свойство("type") Тогда
				Сообщение = НСтр("ru = 'Ошибка секции сбора дампов в файле настроек технологического журнала'");
				Сообщение = Сообщение + " """ + Файл.ПолноеИмя + """." + Символы.ПС;
				Сообщение = Сообщение + НСтр("ru = 'Регистрация дампов не возможна. Удалите файл или восстановите настройки.'");
				ЧтениеXML.Закрыть();
				ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга'", ОбщегоНазначения.КодОсновногоЯзыка()), 
					УровеньЖурналаРегистрации.Предупреждение,,, Сообщение);
				
				КаталогДампов.Путь = Неопределено;
				КаталогДампов.ОписаниеОшибки = НСтр("ru = 'Ошибка секции сбора дампов в файле настроек технологического журнала'");
				Возврат КаталогДампов;
			КонецЕсли;
		КонецЕсли;
				
		Если ПараметрыДампов <> Неопределено Тогда
			КаталогДампов.Путь = СформироватьПутьСРазделителем(ПараметрыДампов.Location);
			Если СтрНайти(КаталогДампов.Путь, "80af5716-b134-4b1c-a38d-4658d1ac4196") > 0 И НЕ СборПолныхДамповВключен = Истина Тогда
				КаталогДампов.УдалятьДампы = Истина;
			КонецЕсли;
			ЧтениеXML.Закрыть();
			
			Если СтрНайти(КаталогДампов.Путь, "80af5716-b134-4b1c-a38d-4658d1ac4196") > 0 Тогда
				Если ПараметрыДампов.type <> ТипДампа Тогда
					СоздатьСекциюСбораДампов(Файл, ЧтениеXML, КаталогДампов, ТипДампа);
				ИначеЕсли НЕ ПараметрыДампов.Свойство("externaldump") Тогда
					СоздатьСекциюСбораДампов(Файл, ЧтениеXML, КаталогДампов, ТипДампа);
				ИначеЕсли ПараметрыДампов.externaldump <> "1" Тогда
					СоздатьСекциюСбораДампов(Файл, ЧтениеXML, КаталогДампов, ТипДампа);
				КонецЕсли;
			КонецЕсли;
		Иначе
			ЧтениеXML.Закрыть();
			СоздатьСекциюСбораДампов(Файл, ЧтениеXML, КаталогДампов, ТипДампа);
		КонецЕсли;
			
	Иначе
		КаталогДампов.Путь = СоздатьФайлНастроекСбораДампов(ПутьКаталога, ТипДампа);
		Если НЕ СборПолныхДамповВключен = Истина Тогда
			КаталогДампов.УдалятьДампы = Истина;
		КонецЕсли;
		Если КаталогДампов.Путь = Неопределено Тогда
			КаталогДампов.ОписаниеОшибки = НСтр("ru = 'Ошибка создания файла настроек технологического журнала. Регистрация дампов не возможна.'");
		КонецЕсли;
	КонецЕсли;
	
	Возврат КаталогДампов;
КонецФункции

Процедура СоздатьСекциюСбораДампов(Файл, ЧтениеXML, КаталогДампов, ТипДампа)
	
	Идентификатор = "80af5716-b134-4b1c-a38d-4658d1ac4196";
	
	ЧтениеXML.ОткрытьФайл(Файл.ПолноеИмя, Новый ПараметрыЧтенияXML(,,,,,,,Ложь, Ложь));
	
	ПостроительDOM = Новый ПостроительDOM;
	ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);
	ДокументDOM.Нормализовать();
	ЧтениеXML.Закрыть();
		Если ДокументDOM.ЕстьДочерниеУзлы() Тогда
		ПервыйДочерний = ДокументDOM.ПервыйДочерний;
		Если ВРЕГ(ПервыйДочерний.ИмяУзла) = "DESIGNER" Тогда
			ПутьПоУмолчанию = СтрНайти(КаталогДампов.Путь, Идентификатор) > 0;
			Если ПустаяСтрока(КаталогДампов.Путь) ИЛИ ПутьПоУмолчанию Тогда
				КаталогДампов.Путь = СформироватьПутьСРазделителем(СформироватьПутьСРазделителем(КаталогВременныхФайлов() + "Dumps") + Идентификатор);
			КонецЕсли;
			КаталогДампов.УдалятьДампы = Истина;
			
			ЭлементыДампы = ДокументDOM.ПолучитьЭлементыПоИмени("dump");
			Если ЭлементыДампы.Количество() = 0 Тогда
				
				ЭлементДампы = ДокументDOM.СоздатьЭлемент("dump");
				ЭлементДампы.УстановитьАтрибут("location", КаталогДампов.Путь);
				ЭлементДампы.УстановитьАтрибут("create", "1");
				ЭлементДампы.УстановитьАтрибут("type", ТипДампа);
				ЭлементДампы.УстановитьАтрибут("externaldump", "1");
				ПервыйДочерний.ДобавитьДочерний(ЭлементДампы);
			Иначе
				Для Каждого ТекЭлемент Из ЭлементыДампы Цикл
					ТекЭлемент.УстановитьАтрибут("externaldump", "1");
					ТекЭлемент.УстановитьАтрибут("type", ТипДампа);
					ТекЭлемент.УстановитьАтрибут("location", КаталогДампов.Путь);
				КонецЦикла;
			КонецЕсли;
			
			Попытка
				ЗаписьXML = Новый ЗаписьXML;
				ЗаписьDOM = Новый ЗаписьDOM; 
				ЗаписьXML.ОткрытьФайл(Файл.ПолноеИмя, Новый ПараметрыЗаписиXML(,,Истина,Истина));
				ЗаписьDOM.Записать(ДокументDOM, ЗаписьXML);
				ЗаписьXML.Закрыть();
			Исключение
				Сообщение = НСтр("ru = 'Ошибка записи файла настроек технологического журнала. Регистрация дампов не возможна.'");
				Сообщение = Сообщение + " """ +Файл.ПолноеИмя + """." + Символы.ПС;
				Сообщение = Сообщение + ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
				ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Регистрация дампов'", 
					ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Предупреждение,,, Сообщение);
				
				КаталогДампов.Путь = Неопределено;
				КаталогДампов.ОписаниеОшибки = НСтр("ru = 'Ошибка записи файла настроек технологического журнала. Регистрация дампов не возможна.'");
			КонецПопытки;
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

// Генерирует путь к каталогу дампов.
// Каталог дампов очищается автоматически методом РегистрацияДампов. 
// 
// Параметры:
//    ПутьКаталога - Строка - путь к каталогу, в котором хранится файл настроек технологического журнала.
// 
// Возвращаемое значение:
//    Строка
//
Функция СоздатьФайлНастроекСбораДампов(ПутьКаталога, ТипДампа)
	ИмяФайлаНастроек = "logcfg.xml";
	
	Идентификатор = "80af5716-b134-4b1c-a38d-4658d1ac4196";
	КаталогДампов = СформироватьПутьСРазделителем(СформироватьПутьСРазделителем(КаталогВременныхФайлов() + "Dumps") + Идентификатор);
	
	Попытка
		ЗаписьXML = Новый ЗаписьXML;
		ЗаписьXML.ОткрытьФайл(ПутьКаталога + ИмяФайлаНастроек);
		СборДампов =
		"<config xmlns=""http://v8.1c.ru/v8/tech-log"">
		|	<dump location=""" + КаталогДампов + """ create=""1"" type=""" + ТипДампа + """ externaldump=""1""/>
		|</config>";
		ЗаписьXML.ЗаписатьБезОбработки(СборДампов);
		ЗаписьXML.Закрыть();
	Исключение
		Сообщение = НСтр("ru = 'Ошибка создания файла настроек технологического журнала. Регистрация дампов не возможна.'");
		Сообщение = Сообщение + " """ +ПутьКаталога + ИмяФайлаНастроек + """." + Символы.ПС;
		Сообщение = Сообщение + ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга'", ОбщегоНазначения.КодОсновногоЯзыка()), 
			УровеньЖурналаРегистрации.Предупреждение,,, Сообщение);
		
		КаталогДампов = Неопределено;
		
	КонецПопытки;
	
	Возврат КаталогДампов;
КонецФункции

Функция ПолучитьКаталогНастроекТехнологическогоЖурнала()
	КаталогНастроек = Новый Структура("Путь, Существует, ОписаниеОшибки", "", Ложь, "");
	
	// Каталоги в которых осуществляли поиск, необходим как защита от зацикливания.
	КаталогиНастроек = Новый Массив;
	
	ИмяФайлаНастроек = "logcfg.xml";
	ИмяФайлаКонфигурацииНастроек = "conf.cfg";
	
	КаталогПрограммы = СформироватьПутьСРазделителем(КаталогПрограммы());
		
	ПоискКаталога = Истина;
	Счетчик = 0;
	ПутьКаталога = СформироватьПутьСРазделителем(КаталогПрограммы + "conf");
	Пока ПоискКаталога = Истина Цикл
		// Проверяем, не искали ли в текущем каталоге (защита от зацикливания).
		Если КаталогиНастроек.Найти(ПутьКаталога) <> Неопределено Тогда
			КаталогНастроек.Путь = "";
			КаталогНастроек.Существует = Ложь;
			КаталогНастроек.ОписаниеОшибки = НСтр("ru = 'Обнаружена циклическая ссылка'", ОбщегоНазначения.КодОсновногоЯзыка());
			
			ПоискКаталога = Ложь;
		Иначе
			ПолноеИмяФайлаНастроек = ПутьКаталога + ИмяФайлаНастроек;
			ФайлНастроек = Новый Файл(ПолноеИмяФайлаНастроек);
			Если ФайлНастроек.Существует() Тогда
				КаталогНастроек.Путь = ПутьКаталога;
				КаталогНастроек.Существует = Истина;
				КаталогНастроек.ОписаниеОшибки = "";
				
				ПоискКаталога = Ложь;
			Иначе
				КаталогиНастроек.Добавить(ПутьКаталога);
				
				ПолноеИмяФайлаКонфигурацииНастроек = ПутьКаталога + ИмяФайлаКонфигурацииНастроек;
				ФайлКонфигурацииНастроек = Новый Файл(ПолноеИмяФайлаКонфигурацииНастроек);
				Если ФайлКонфигурацииНастроек.Существует() Тогда
					ПутьКаталога = ПолучитьКаталогИзФайлаКонфигурацииНастроек(ФайлКонфигурацииНастроек);
					Если ПутьКаталога.Существует Тогда
						ПутьКаталога = СформироватьПутьСРазделителем(ПутьКаталога.Путь);
					Иначе
						КаталогНастроек.Путь = ПутьКаталога.Путь;
						КаталогНастроек.Существует = ПутьКаталога.Существует;
						КаталогНастроек.ОписаниеОшибки = ПутьКаталога.ОписаниеОшибки;
						
						ПоискКаталога = Ложь;
					КонецЕсли;
				Иначе
					КаталогНастроек.Путь = "";
					КаталогНастроек.Существует = Ложь;
					КаталогНастроек.ОписаниеОшибки = НСтр("ru = 'Файл конфигурации настроек в каталоге не существует'", 
						ОбщегоНазначения.КодОсновногоЯзыка()) + " " + ПутьКаталога;
					
					ПоискКаталога = Ложь;
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
		
		Счетчик = Счетчик + 1;
		
		Если Счетчик >= 100 Тогда
			ПоискКаталога = Ложь;
		КонецЕсли;
	КонецЦикла;
	
	Возврат КаталогНастроек;
КонецФункции

Функция ПолучитьКаталогИзФайлаКонфигурацииНастроек(ФайлКонфигурацииНастроек)
	КаталогНастроек = Новый Структура("Путь, Существует, ОписаниеОшибки", "", Ложь, "");
	
	СтрокаПоиска = "ConfLocation=";
	ДлинаСтрокиПоиска = СтрДлина(СтрокаПоиска);
	
	Текст = Новый ЧтениеТекста(ФайлКонфигурацииНастроек.ПолноеИмя);
	Данные = Текст.Прочитать();
	
	ИндексПоиска = СтрНайти(Данные, СтрокаПоиска);
	Если ИндексПоиска > 0 Тогда
		ДанныеБуфер = Прав(Данные, СтрДлина(Данные) - (ИндексПоиска + ДлинаСтрокиПоиска - 1));
		ИндексПоиска = СтрНайти(ДанныеБуфер, Символы.ПС);
		Если ИндексПоиска > 0 Тогда
			КаталогНастроек.Путь = СформироватьПутьСРазделителем(Лев(ДанныеБуфер, ИндексПоиска - 1));
		Иначе
			КаталогНастроек.Путь = СформироватьПутьСРазделителем(ДанныеБуфер);
		КонецЕсли;
		КаталогНастроек.Существует = Истина;
		КаталогНастроек.ОписаниеОшибки = "";
	Иначе
		КаталогНастроек.Путь = СформироватьПутьСРазделителем(ФайлКонфигурацииНастроек.Путь);
		КаталогНастроек.Существует = Ложь;
		КаталогНастроек.ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не найдена секция %1 в файле %2'", ОбщегоНазначения.КодОсновногоЯзыка()),
			"ConfLocation", ФайлКонфигурацииНастроек.ПолноеИмя);
	КонецЕсли;
		
	Возврат КаталогНастроек;
КонецФункции

#КонецОбласти

#Область РаботаСДампами

Функция ОписаниеДампа(Знач ИмяФайла)
	ИмяФайла = СтрЗаменить(ИмяФайла, "_", Символы.ПС);
	
	СтруктураДампа = Новый Структура;
	Если СтрЧислоСтрок(ИмяФайла) >= 3  Тогда
		СтруктураДампа.Вставить("Процесс", СтрПолучитьСтроку(ИмяФайла, 1));
		СтруктураДампа.Вставить("ВерсияПлатформы", СтрПолучитьСтроку(ИмяФайла, 2));
		СтруктураДампа.Вставить("Смещение", СтрПолучитьСтроку(ИмяФайла, 3));
	Иначе
		СисИнфо = Новый СистемнаяИнформация;
		СтруктураДампа.Вставить("Процесс", "userdump");
		СтруктураДампа.Вставить("ВерсияПлатформы", СисИнфо.ВерсияПриложения);
		СтруктураДампа.Вставить("Смещение", "ffffffff");
	КонецЕсли;
	
	Возврат СтруктураДампа;
КонецФункции

Функция ВерсияПлатформыВЧисло(Версия) Экспорт
	ВерсияПлатформы = СтрЗаменить(Версия, ".", Символы.ПС);
	ВерсияПлатформыЧисло = Число(Лев(СтрПолучитьСтроку(ВерсияПлатформы, 1) + "000000", 6)
		+ Лев(СтрПолучитьСтроку(ВерсияПлатформы, 2) + "000000", 6)
		+ Лев(СтрПолучитьСтроку(ВерсияПлатформы, 3) + "000000", 6)
		+ Лев(СтрПолучитьСтроку(ВерсияПлатформы, 4) + "000000", 6));
	
	Возврат ВерсияПлатформыЧисло;
КонецФункции

#КонецОбласти

#Область РаботаССистемнойИнформацией
Функция ПолучитьСистемнуюИнформацию()
	СисИнфо = Новый СистемнаяИнформация;
	
	Результат = Новый Структура;
	Результат.Вставить("computerName", ОбщегоНазначения.КонтрольнаяСуммаСтрокой(ИмяКомпьютера()));
	Результат.Вставить("osInfo", Строка(СисИнфо.ВерсияОС));
	Результат.Вставить("platformVersion", Строка(СисИнфо.ВерсияПриложения));
	Результат.Вставить("clientID", Строка(СисИнфо.ИдентификаторКлиента));
	Результат.Вставить("ram", Строка(СисИнфо.ОперативнаяПамять));
	Результат.Вставить("cpu", Строка(СисИнфо.Процессор));
	Результат.Вставить("applicationArchitecture", Строка(СисИнфо.ТипПлатформы));
	Результат.Вставить("currentLanguage", Строка(ТекущийЯзык()));
	Результат.Вставить("currentLocalizationCode", Строка(ТекущийКодЛокализации()));
	Результат.Вставить("currentSystemLanguage", Строка(ТекущийЯзыкСистемы()));
	Результат.Вставить("currentRunMode", Строка(ТекущийРежимЗапуска()));
	Результат.Вставить("sessionTimeZone", Строка(ЧасовойПоясСеанса()));
	
	Возврат Результат;
КонецФункции

Функция ВерсииПодсистем()
	
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ВерсииПодсистем.ИмяПодсистемы КАК ИмяПодсистемы,
	|	ВерсииПодсистем.Версия КАК Версия
	|ИЗ
	|	РегистрСведений.ВерсииПодсистем КАК ВерсииПодсистем";
	
	Результат = Запрос.Выполнить();
	
	Подсистемы = Новый Структура;
	Выборка = Результат.Выбрать();
	Пока Выборка.Следующий() Цикл
		Подсистемы.Вставить(Выборка.ИмяПодсистемы, Выборка.Версия);
	КонецЦикла;
	
	Возврат Подсистемы;
КонецФункции

#КонецОбласти

#Область РаботаСРасширениямиКонфигурации

Функция ДанныеОбИспользуемыхРасширениях()

	СтруктураРасширения = Новый Структура;
	                   	
	МассивРасширений = РасширенияКонфигурации.Получить();
	ИспользуютсяРасширения = МассивРасширений.Количество()>0;
	СтруктураРасширения.Вставить("ИспользованиеРасширений", ИспользуютсяРасширения);
	
	Если Не ИспользуютсяРасширения Тогда
		Возврат СтруктураРасширения;
	КонецЕсли;
	
	МассивОписанийРасширений = Новый Массив;	
	Для Каждого Расширение Из МассивРасширений Цикл
		ОписаниеРасширения = Новый Структура("Имя, Версия, Назначение, БезопасныйРежим, ЗащитаОтОпасныхДействий, Синоним");
		ЗаполнитьЗначенияСвойств(ОписаниеРасширения, Расширение);
		ОписаниеРасширения.Вставить("ЗащитаОтОпасныхДействий", ?(ОписаниеРасширения.ЗащитаОтОпасныхДействий = Неопределено, Ложь, ОписаниеРасширения.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях));
		ОписаниеРасширения.Вставить("Назначение", Строка(ОписаниеРасширения.Назначение));		
		МассивОписанийРасширений.Добавить(ОписаниеРасширения);
	КонецЦикла;
	
	СтруктураРасширения.Вставить("ОписанияРасширений", МассивОписанийРасширений);	
	
	МетаданныеРасширений = Новый Соответствие;
	ОписаниеМетаданных = ОписаниеМетаданных();
	Для Каждого СтрЗапись Из ОписаниеМетаданных Цикл
		ДобавитьИнформациюОРасширениях(СтрЗапись.Ключ, СтрЗапись.Значение, МетаданныеРасширений);
	КонецЦикла;
	
	СтруктураРасширения.Вставить("МетаданныеРасширений", МетаданныеРасширений);
	
	Возврат СтруктураРасширения;
	
КонецФункции

Процедура ДобавитьИнформациюОРасширениях(КлассОбъекта, АрхитектураОбъекта, МетаданныеРасширений)
	Для Каждого ОбъектМетаданных Из Метаданные[КлассОбъекта] Цикл
		// Сначала обходим подчиненные.
		Для Каждого ЭлементСтруктуры Из АрхитектураОбъекта Цикл
			Если ЭлементСтруктуры.Значение = "Рекурсивно" Тогда
				ДобавитьИнформациюОРасширенияхРекурсивно(ОбъектМетаданных, ЭлементСтруктуры.Ключ, АрхитектураОбъекта, МетаданныеРасширений);
			КонецЕсли;
			Для Каждого ПодчиненныйОбъект Из ОбъектМетаданных[ЭлементСтруктуры.Ключ] Цикл
				РасширениеОбъекта = ПодчиненныйОбъект.РасширениеКонфигурации(); // РасширениеКонфигурации
				Если РасширениеОбъекта = Неопределено Тогда
					Продолжить;
				КонецЕсли;		
				МетаданныеРасширений.Вставить(ПодчиненныйОбъект.ПолноеИмя(), РасширениеОбъекта.Имя);
			КонецЦикла;
		КонецЦикла;
		
		РасширениеОбъекта = ОбъектМетаданных.РасширениеКонфигурации(); // РасширениеКонфигурации
		Если РасширениеОбъекта = Неопределено Тогда
			Если ОбъектМетаданных.ЕстьИзмененияРасширениямиКонфигурации() Тогда
				МетаданныеРасширений.Вставить(ОбъектМетаданных.ПолноеИмя(), Истина);		
			КонецЕсли;
			Продолжить;
		КонецЕсли;		
		МетаданныеРасширений.Вставить(ОбъектМетаданных.ПолноеИмя(), РасширениеОбъекта.Имя);
	КонецЦикла;

КонецПроцедуры

Процедура ДобавитьИнформациюОРасширенияхРекурсивно(Объект, ИмяРекурсивногоАтрибута, АрхитектураОбъекта, МетаданныеРасширений)
	Для Каждого РекурсивныйОбъект Из Объект[ИмяРекурсивногоАтрибута] Цикл
		Для Каждого ЭлементСтруктуры Из АрхитектураОбъекта Цикл
			Если ЭлементСтруктуры.Значение = "Рекурсивно" Тогда
				ДобавитьИнформациюОРасширенияхРекурсивно(РекурсивныйОбъект, ЭлементСтруктуры.Ключ, АрхитектураОбъекта, МетаданныеРасширений);
			КонецЕсли;
			Для Каждого ПодчиненныйОбъект Из РекурсивныйОбъект[ЭлементСтруктуры.Ключ] Цикл
				РасширениеОбъекта = ПодчиненныйОбъект.РасширениеКонфигурации(); // РасширениеКонфигурации
				Если РасширениеОбъекта = Неопределено Тогда
					Продолжить;
				КонецЕсли;		
				МетаданныеРасширений.Вставить(ПодчиненныйОбъект.ПолноеИмя(), РасширениеОбъекта.Имя);
			КонецЦикла;
		КонецЦикла;
		
		РасширениеОбъекта = РекурсивныйОбъект.РасширениеКонфигурации(); // РасширениеКонфигурации
		Если РасширениеОбъекта = Неопределено Тогда
			Продолжить;
		КонецЕсли;		
		МетаданныеРасширений.Вставить(РекурсивныйОбъект.ПолноеИмя(), РасширениеОбъекта.Имя);	
	КонецЦикла;
КонецПроцедуры
 
Функция ОписаниеМетаданных()
	ОписаниеМетаданных = Новый Соответствие;
	ОписаниеМетаданных.Вставить("Подсистемы", Новый Структура("Подсистемы", "Рекурсивно"));
	ОписаниеМетаданных.Вставить("ОбщиеМодули", Новый Структура);
	ОписаниеМетаданных.Вставить("ПараметрыСеанса", Новый Структура);
	ОписаниеМетаданных.Вставить("ОбщиеРеквизиты", Новый Структура);
	ОписаниеМетаданных.Вставить("ОбщиеРеквизиты", Новый Структура);
	ОписаниеМетаданных.Вставить("ПланыОбмена", Новый Структура("Реквизиты, ТабличныеЧасти, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("КритерииОтбора", Новый Структура("Формы, Команды"));
	ОписаниеМетаданных.Вставить("ПодпискиНаСобытия", Новый Структура);
	ОписаниеМетаданных.Вставить("РегламентныеЗадания", Новый Структура);
	ОписаниеМетаданных.Вставить("ФункциональныеОпции", Новый Структура);
	ОписаниеМетаданных.Вставить("ПараметрыФункциональныхОпций", Новый Структура);
	ОписаниеМетаданных.Вставить("ОпределяемыеТипы", Новый Структура);
	ОписаниеМетаданных.Вставить("ХранилищаНастроек", Новый Структура("Формы, Макеты"));
	ОписаниеМетаданных.Вставить("ОбщиеФормы", Новый Структура);
	ОписаниеМетаданных.Вставить("ОбщиеКоманды", Новый Структура);
	ОписаниеМетаданных.Вставить("ГруппыКоманд", Новый Структура);
	ОписаниеМетаданных.Вставить("ОбщиеМакеты", Новый Структура);
	ОписаниеМетаданных.Вставить("ОбщиеКартинки", Новый Структура);
	ОписаниеМетаданных.Вставить("ПакетыXDTO", Новый Структура);
	ОписаниеМетаданных.Вставить("WebСервисы", Новый Структура);
	ОписаниеМетаданных.Вставить("HTTPСервисы", Новый Структура);
	ОписаниеМетаданных.Вставить("WSСсылки", Новый Структура);
	ОписаниеМетаданных.Вставить("ЭлементыСтиля", Новый Структура);
	ОписаниеМетаданных.Вставить("Языки", Новый Структура);	
	ОписаниеМетаданных.Вставить("Константы", Новый Структура);
	ОписаниеМетаданных.Вставить("Справочники", Новый Структура("Реквизиты, ТабличныеЧасти, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("Документы", Новый Структура("Реквизиты, ТабличныеЧасти, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("ЖурналыДокументов", Новый Структура("Графы, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("Перечисления", Новый Структура("ЗначенияПеречисления, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("Отчеты", Новый Структура("Реквизиты, ТабличныеЧасти, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("Обработки", Новый Структура("Реквизиты, ТабличныеЧасти, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("ПланыВидовХарактеристик", Новый Структура("Реквизиты, ТабличныеЧасти, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("ПланыСчетов", Новый Структура("Реквизиты, ТабличныеЧасти, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("ПланыВидовРасчета", Новый Структура("Реквизиты, ТабличныеЧасти, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("РегистрыСведений", Новый Структура("Измерения, Ресурсы, Реквизиты, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("РегистрыНакопления", Новый Структура("Измерения, Ресурсы, Реквизиты, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("РегистрыБухгалтерии", Новый Структура("Измерения, Ресурсы, Реквизиты, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("РегистрыРасчета", Новый Структура("Измерения, Ресурсы, Реквизиты, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("БизнесПроцессы", Новый Структура("Реквизиты, ТабличныеЧасти, Формы, Команды, Макеты"));
	ОписаниеМетаданных.Вставить("Задачи", Новый Структура("РеквизитыАдресации, Реквизиты, ТабличныеЧасти, Формы, Команды, Макеты"));
	
	Возврат ОписаниеМетаданных;
КонецФункции

#КонецОбласти

#Область РаботаСПодсистемойПравДоступа

Функция ДанныеОбИспользованииРолей()
	ДанныеОбИспользованииРолей = Новый Структура;
	
	// Получение данных об использовании ролей.	
	Запрос = Новый Запрос(УправлениеДоступомСлужебный.ТекстЗапросаИспользованияРолей());
	Запрос.УстановитьПараметр("ПустойУИД", ОбщегоНазначенияКлиентСервер.ПустойУникальныйИдентификатор());
	Запрос.УстановитьПараметр("ТекущаяДата", НачалоДня(ТекущаяДатаСеанса()));
	РезультатПакет = Запрос.ВыполнитьПакет();
	
	// Формирование структуры: роли в разрезе профилей групп доступа.
	КолонкиИндекса = Новый Соответствие;
	КолонкиИндекса.Вставить("ПрофильУИД", Новый Соответствие);
	КолонкиИндекса.Вставить("РольИмя", Новый Соответствие);	
	ДополнительныеПараметры = Новый Соответствие;
	ДополнительныеПараметры.Вставить("КолонкиИндекса", КолонкиИндекса);
	
	РолиПрофилей = РезультатПакет[8].Выгрузить();
	РолиПрофилей.Колонки.Добавить("ПрофильУИД", Новый ОписаниеТипов("Строка"));
	Для Каждого СтрокаТаблицы Из РолиПрофилей Цикл
		СтрокаТаблицы.ПрофильУИД = Строка(СтрокаТаблицы.Профиль.УникальныйИдентификатор());
	КонецЦикла;
	РолиПрофилей.Колонки.Удалить("Профиль");
	
	РолиПрофилейСтруктура = СформироватьJSONСтруктуру("RolesOfProfiles", РолиПрофилей, ДополнительныеПараметры);
	ДанныеОбИспользованииРолей.Вставить("RolesOfProfiles", РолиПрофилейСтруктура["RolesOfProfiles"]);
	
	// Формирование структуры: статистика по использованию профилей.
	КолонкиИндекса = Новый Соответствие;
	КолонкиИндекса.Вставить("ПрофильУИД", Новый Соответствие);	
	КолонкиИндекса.Вставить("Наименование", Новый Соответствие);
	КолонкиИндекса.Вставить("ИдентификаторПоставляемыхДанных", Новый Соответствие);
	ДополнительныеПараметры = Новый Соответствие;
	ДополнительныеПараметры.Вставить("КолонкиИндекса", КолонкиИндекса);
	
	ДанныеПрофилей = РезультатПакет[7].Выгрузить();
	ДанныеПрофилей.Колонки.Добавить("ПрофильУИД", Новый ОписаниеТипов("Строка"));
	ДанныеПрофилей.Колонки.Добавить("ИдентификаторПоставляемыхДанныхСтрока", Новый ОписаниеТипов("Строка"));
	Для Каждого СтрокаТаблицы Из ДанныеПрофилей Цикл
		СтрокаТаблицы.ИдентификаторПоставляемыхДанныхСтрока = Строка(СтрокаТаблицы.ИдентификаторПоставляемыхДанных);
		СтрокаТаблицы.ПрофильУИД = Строка(СтрокаТаблицы.Профиль.УникальныйИдентификатор());
	КонецЦикла;
	ДанныеПрофилей.Колонки.Удалить("ИдентификаторПоставляемыхДанных");
	ДанныеПрофилей.Колонки.ИдентификаторПоставляемыхДанныхСтрока.Имя = "ИдентификаторПоставляемыхДанных";
	ДанныеПрофилей.Колонки.Удалить("Профиль");
	
	Профили = СформироватьJSONСтруктуру("Profiles", ДанныеПрофилей, ДополнительныеПараметры);
	ДанныеОбИспользованииРолей.Вставить("Profiles", Профили["Profiles"]);
	
	Возврат ДанныеОбИспользованииРолей;
КонецФункции

#КонецОбласти


#Область РаботаВРежимеРазделенияПоОбластямДанных

Функция РазделениеПоОбластямДанныхВключено() Экспорт
	
	Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
		РазделениеПоОбластямДанныхВключено = МодульРаботаВМоделиСервиса.РазделениеВключено();
	Иначе
		РазделениеПоОбластямДанныхВключено = Ложь;
	КонецЕсли;
	
	Возврат РазделениеПоОбластямДанныхВключено;
	
КонецФункции

#КонецОбласти

#Область РаботаВРежимеРИБ

Функция ЭтоГлавныйУзел()
	УстановитьПривилегированныйРежим(Истина);
	
	Возврат НЕ ПланыОбмена.ГлавныйУзел() <> Неопределено;
КонецФункции

#КонецОбласти

#Область ОбщиеФункции

Функция СобытиеЖурналаРегистрацииЦентрМониторингаУдалениеДампа()
	Возврат НСтр("ru = 'Центр мониторинга.Удаление дампа'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции

Функция СобытиеЖурналаРегистрацииРазобратьБуферОперацийСтатистики()
	Возврат НСтр("ru = 'Центр мониторинга.Разобрать буфер операций статистики'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
#КонецОбласти

#Область ИнформацияКлиента

Процедура ЗаписатьСтатистикуЭкрановКлиента(Параметры)
	
	Экраны = Параметры["ИнформацияКлиента"]["ЭкраныКлиента"]; 
	ХешПользователя = Параметры["ИнформацияКлиента"]["ПараметрыКлиента"]["ХешПользователя"];
	
	Для Каждого ТекЭкран Из Экраны Цикл
		
		ИмяОперацииСтатистики = "СтатистикаКлиента.ИнформацияОСистеме.РазрешениеМонитора." + ТекЭкран;
		ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистикиСутки(ИмяОперацииСтатистики, ХешПользователя, 1);
		
		ИмяОперацииСтатистики = ИмяОперацииСтатистики + "." + Параметры["ИнформацияКлиента"]["ИнформацияОСистеме"]["ИнформацияПрограммыПросмотра"]; 
		ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистикиСутки(ИмяОперацииСтатистики, ХешПользователя, 1);
		
	КонецЦикла;
	
	КоличествоМониторовСтрока = Формат(Экраны.Количество(), "ЧГ=0");
	ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистикиСутки("СтатистикаКлиента.ИнформацияОСистеме.КоличествоМониторов." + КоличествоМониторовСтрока, ХешПользователя, 1);
	
КонецПроцедуры

Процедура ЗаписатьИнформациюОСистеме(Параметры)
	
	ХешПользователя = Параметры["ИнформацияКлиента"]["ПараметрыКлиента"]["ХешПользователя"];
	
	Для Каждого ТекИнфоОСистеме Из Параметры["ИнформацияКлиента"]["ИнформацияОСистеме"] Цикл
		ИмяОперацииСтатистики = "СтатистикаКлиента.ИнформацияОСистеме." + ТекИнфоОСистеме.Ключ + "." + ТекИнфоОСистеме.Значение;
		ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистикиСутки(ИмяОперацииСтатистики, ХешПользователя, 1);
	КонецЦикла;
	
КонецПроцедуры

Процедура ЗаписатьИнформацияКлиента(Параметры)
	
	ХешПользователя = Параметры["ИнформацияКлиента"]["ПараметрыКлиента"]["ХешПользователя"];
	
	ЗаписатьАктивностьПользователя(ХешПользователя);
	
	ИмяОперацииСтатистики = "СтатистикаКлиента.АктивныхОкон";
	Значение =  Параметры["ИнформацияКлиента"]["АктивныхОкон"];
	ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистикиЧас(ИмяОперацииСтатистики, ХешПользователя, Значение);
	
КонецПроцедуры

Процедура ЗаписатьАктивностьПользователя(ХешПользователя)
	ИмяОперацииСтатистики = "СтатистикаКлиента.АктивныхПользователей";
	ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистикиЧас(ИмяОперацииСтатистики, ХешПользователя, 1);
КонецПроцедуры

Процедура ЗаписатьДанныеСКлиента(Параметры)
	
	ТекДата = ТекущаяУниверсальнаяДата();
	
	Замеры = Параметры["Замеры"];
	Для Каждого ЗамерыТипа Из Замеры Цикл
		
		ТипЗаписи = ЗамерыТипа.Ключ;
		
		Если ТипЗаписи = 0 Тогда
			ЗаписатьДанныеСКлиентаТочные(ЗамерыТипа.Значение);
		Иначе
			ЗаписатьДанныеСКлиентаУникальные(ЗамерыТипа.Значение, ТипЗаписи, ТекДата);
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ЗаписатьДанныеСКлиентаТочные(Замеры)
	
	РегистрыСведений.БуферОперацийСтатистики.ЗаписатьОперацииБизнесСтатистики(Замеры);
			
КонецПроцедуры

Процедура ЗаписатьДанныеСКлиентаУникальные(Замеры, ТипЗаписи, ТекДата)
	
	Если ТипЗаписи = 1 Тогда
		ПериодЗаписи = НачалоЧаса(ТекДата);
	ИначеЕсли ТипЗаписи = 2 Тогда
		ПериодЗаписи = НачалоДня(ТекДата);
	КонецЕсли;
	
	ПараметрыЗаписи = Новый Структура("ИмяОперации, КлючУникальности, Значение, Замещать, ТипЗаписи, ПериодЗаписи");
	Для Каждого ТекЗамер Из Замеры Цикл
		
		ПараметрыЗаписи.ИмяОперации = ТекЗамер.Значение.ОперацияСтатистики;
		ПараметрыЗаписи.КлючУникальности = ТекЗамер.Значение.Ключ;
		ПараметрыЗаписи.Значение = ТекЗамер.Значение.Значение;
		ПараметрыЗаписи.Замещать = ТекЗамер.Значение.Замещать;
		ПараметрыЗаписи.ТипЗаписи = ТипЗаписи;
		ПараметрыЗаписи.ПериодЗаписи = ПериодЗаписи;
		
		ЗаписатьОперациюБизнесСтатистикиСлужебная(ПараметрыЗаписи);	
		
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

Процедура ПервоначальноеЗаполнение() Экспорт
	
	Если РазделениеПоОбластямДанныхВключено() Тогда
		Возврат;
	КонецЕсли;
	
	ТекДата = ТекущаяУниверсальнаяДата();
	
	УдалитьПараметрыЦентраМониторинга();
	ПараметрыЦентраМониторинга = ПолучитьПараметрыПоУмолчанию();
	
	Если ОбщегоНазначения.ИнформационнаяБазаФайловая() Тогда
		ПараметрыЦентраМониторинга.БизнесСтатистикаПериодФормирования = 3600;
	КонецЕсли;
	
	ПараметрыЦентраМониторинга.РегистрацияДамповСледующееФормирование = ТекДата + ПараметрыЦентраМониторинга.РегистрацияДамповПериодФормирования;
	ПараметрыЦентраМониторинга.БизнесСтатистикаСледующееФормирование = ТекДата + ПараметрыЦентраМониторинга.БизнесСтатистикаПериодФормирования;
	ПараметрыЦентраМониторинга.СтатистикаКонфигурацииСледующееФормирование = ТекДата + ПараметрыЦентраМониторинга.СтатистикаКонфигурацииПериодФормирования;
	
	ГСЧ = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах());
	ДельтаОтправки = ГСЧ.СлучайноеЧисло(0, 86400);
	ПараметрыЦентраМониторинга.ОтправкаДанныхСледующееФормирование = ТекДата + ДельтаОтправки;
	
	ПараметрыЦентраМониторинга.ПериодАгрегацииМалый = 600;
	ПараметрыЦентраМониторинга.ПериодАгрегации = 3600;
	ПараметрыЦентраМониторинга.ПериодУдаления = 86400;
	
	Если СтандартныеПодсистемыСервер.ЭтоБазоваяВерсияКонфигурации() Тогда
		ПараметрыЦентраМониторинга.ВключитьЦентрМониторинга = Истина;
	КонецЕсли;
	
	УстановитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	
	Если СтандартныеПодсистемыСервер.ЭтоБазоваяВерсияКонфигурации() Тогда
		РегЗадание = ПолучитьРегламентноеЗадание("СборИОтправкаСтатистики", Истина);
		УстановитьРасписаниеПоУмолчанию(РегЗадание);
	КонецЕсли;
	
КонецПроцедуры

Процедура ДобавитьИдентификаторИнформационнойБазыПостоянный() Экспорт
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга();
	ПараметрыЦентраМониторинга.Вставить("ИдентификаторИнформационнойБазыПостоянный", ПараметрыЦентраМониторинга.ИдентификаторИнформационнойБазы);
	УстановитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	
КонецПроцедуры

Процедура ВключитьОтправкуСведений(Параметры) Экспорт
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(Новый Структура("ВключитьЦентрМониторинга, ЦентрОбработкиИнформацииОПрограмме"));
	// Если уже включено, не делаем ничего.
	Если ПараметрыЦентраМониторинга.ВключитьЦентрМониторинга ИЛИ ПараметрыЦентраМониторинга.ЦентрОбработкиИнформацииОПрограмме Тогда
		Параметры.ОбработкаЗавершена = Истина;
		Возврат;
	КонецЕсли;
	ПараметрыЦентраМониторинга = Новый Структура("ВключитьЦентрМониторинга, ЦентрОбработкиИнформацииОПрограмме", Истина, Ложь);
	УстановитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	РегЗадание = ПолучитьРегламентноеЗадание("СборИОтправкаСтатистики", Истина);
	УстановитьРасписаниеПоУмолчанию(РегЗадание);
	
	Параметры.ОбработкаЗавершена = Истина;
КонецПроцедуры

Процедура ВключитьОтправкуСведенийЗаполнение(Параметры) Экспорт
	
КонецПроцедуры

Процедура ОтключитьРегистрациюСобытийПриОбновлении() Экспорт
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(Новый Структура("ВключитьЦентрМониторинга, ЦентрОбработкиИнформацииОПрограмме"));	
	Если Не ПараметрыЦентраМониторинга.ВключитьЦентрМониторинга И Не ПараметрыЦентраМониторинга.ЦентрОбработкиИнформацииОПрограмме Тогда
		// Отключим, чтобы не собирать лишнего.
		ОтключитьРегистрациюСобытий();
	КонецЕсли;
КонецПроцедуры

Процедура ЗаписатьОперациюБизнесСтатистикиСлужебная(ПараметрыЗаписи) Экспорт
	
	ПериодЗаписи = ПараметрыЗаписи.ПериодЗаписи;
	ТипЗаписи = ПараметрыЗаписи.ТипЗаписи;
	Ключ = ПараметрыЗаписи.КлючУникальности;
	ОперацияСтатистики = ЦентрМониторингаПовтИсп.ПолучитьСсылкуОперацииСтатистики(ПараметрыЗаписи.ИмяОперации);
	Значение = ПараметрыЗаписи.Значение;
	Замещать = ПараметрыЗаписи.Замещать;
	
	РегистрыСведений.ЗамерыСтатистики.ЗаписатьОперациюБизнесСтатистики(ПериодЗаписи, ТипЗаписи, Ключ, ОперацияСтатистики, Значение, Замещать);
	
КонецПроцедуры

Процедура ВыполнитьДействияПриОбнаруженииКопии()
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга();
	ПараметрыЦентраМониторинга.ИдентификаторИнформационнойБазы = Новый УникальныйИдентификатор();
	ПараметрыЦентраМониторинга.НомерКрайнегоПакета = 0;
	
	УстановитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	
	РегистрыСведений.ПакетыДляОтправки.Очистить();
	
КонецПроцедуры

Процедура ВойтиВОбластьДанных(Знач ОбластьДанных)
	
	Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
		МодульРаботаВМоделиСервиса.ВойтиВОбластьДанных(ОбластьДанных);
	КонецЕсли;
	
КонецПроцедуры

Процедура ВыйтиИзОбластиДанных()
	
	Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
		МодульРаботаВМоделиСервиса.ВыйтиИзОбластиДанных();
	КонецЕсли;
	
КонецПроцедуры

Функция ПараметрыОповещенияОДампах()
	ПолучаемыеПараметры = Новый Структура;
	ПолучаемыеПараметры.Вставить("ОтправлятьФайлыДампов");
	ПолучаемыеПараметры.Вставить("БазовыеПроверкиПройдены");
	ПолучаемыеПараметры.Вставить("ВариантыДампов");
	ПолучаемыеПараметры.Вставить("ВариантДампа");
	ПолучаемыеПараметры.Вставить("ТипДампа");
	ПолучаемыеПараметры.Вставить("СпрашиватьПередОтправкой");
	ПолучаемыеПараметры.Вставить("ИнформацияОДампах");
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(ПолучаемыеПараметры);
	
	ЗапросНаПолучениеДампов = ПараметрыЦентраМониторинга.ОтправлятьФайлыДампов = 2
								И ПараметрыЦентраМониторинга.БазовыеПроверкиПройдены;
									
	ЕстьДампы = ПараметрыЦентраМониторинга.Свойство("ВариантыДампов") И ПараметрыЦентраМониторинга.ВариантыДампов.Количество();
	ЗапросНаОтправку = ПараметрыЦентраМониторинга.ОтправлятьФайлыДампов = 1
						И НЕ ПустаяСтрока(ПараметрыЦентраМониторинга.ВариантДампа)
						И ЕстьДампы
						И ПараметрыЦентраМониторинга.СпрашиватьПередОтправкой
						И ПараметрыЦентраМониторинга.ТипДампа = "3"
						И Не ПустаяСтрока(ПараметрыЦентраМониторинга.ИнформацияОДампах)
						И ПараметрыЦентраМониторинга.БазовыеПроверкиПройдены;
						
	ПараметрыОповещенияОДампах = Новый Структура;
	ПараметрыОповещенияОДампах.Вставить("ЗапросНаПолучениеДампов", ЗапросНаПолучениеДампов);
	ПараметрыОповещенияОДампах.Вставить("ЗапросНаОтправку", ЗапросНаОтправку);
	ПараметрыОповещенияОДампах.Вставить("ИнформацияОДампах", ПараметрыЦентраМониторинга.ИнформацияОДампах);
	
	Возврат ПараметрыОповещенияОДампах;
КонецФункции

#Область СборИОтправкаДампов

// В клиент-серверном варианте вызывается регламентным заданием СборИОтправкаДампов.
// Из него запускаются два фоновых задания - СборДампов и ОтправкаДампов.
// В файловом варианте периодически запускается фоновое задание.
// Работает только под Windows. Проверка выполняется при вычислении переменной НачатьСборИОтправкуОтчетовОбОшибках.
//
Процедура СобратьИОтправитьДампы(СКлиентаНаСервере = Ложь, ИдентификаторЗадания = "") Экспорт
	
	ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.СборИОтправкаОтчетовОбОшибках);
	
	ПараметрыСбораИОтправкиДампов = ПолучитьПараметрыЦентраМониторинга();
	ВариантДампа = ПараметрыСбораИОтправкиДампов.ВариантДампа;
	ИмяКомпьютера = ИмяКомпьютера();
	ИзмененТипДампа = Ложь;
	
	// Проверим, разрешен ли сбор дампов.
	Если ПараметрыСбораИОтправкиДампов.ОтправлятьФайлыДампов = 0 Тогда
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрЦентраМониторинга("РезультатОтправки", НСтр("ru = 'Пользователь отказал в предоставлении дампов.'"));
		УстановитьПривилегированныйРежим(Ложь);
		ПрекратитьСборПолныхДампов();
		Возврат;
	КонецЕсли;
	
	// Проверим, запрашивали ли мы вообще сбор полных дампов.
	Если ПустаяСтрока(ВариантДампа) Тогда
		Возврат;
	КонецЕсли;
	
	// Проверим, не пора ли отключаться по времени.
	Если ТекущаяДатаСеанса() >= ПараметрыСбораИОтправкиДампов.ОкончаниеСбораДампов Тогда
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрЦентраМониторинга("РезультатОтправки", НСтр("ru = 'Сбор дампов прекращен по таймауту.'"));	
		УстановитьПривилегированныйРежим(Ложь);
		ПрекратитьСборПолныхДампов();
		Возврат;
	КонецЕсли;
	
	// Полные дампы собираем только в главном узле.
	Если НЕ ЭтоГлавныйУзел() Тогда 
		Возврат;
	КонецЕсли;
	
	ТребованиеДампа = ДампТребуется(ВариантДампа, ВариантДампа);
	// Если дамп не требуется - выключаем сбор.
	Если НЕ ТребованиеДампа.Требуется Тогда
		ПрекратитьСборПолныхДампов();
		Возврат;
	Иначе  		
		// Если тип собираемого дампа не совпадает с требуемым - меняем тип дампа.
		// Нужно собирать минидамп или полный и пользователь согласовал.
		Если ТребованиеДампа.ТипДампа <> ПараметрыСбораИОтправкиДампов.ТипДампа 
			И (ТребованиеДампа.ТипДампа = "0" 
				ИЛИ ПараметрыСбораИОтправкиДампов.ОтправлятьФайлыДампов = 1 
				И ТребованиеДампа.ТипДампа = "3") Тогда			
			УстановитьПривилегированныйРежим(Истина);
			УстановитьПараметрЦентраМониторинга("ТипДампа", ТребованиеДампа.ТипДампа);
			ПараметрыСбораИОтправкиДампов.ТипДампа = ТребованиеДампа.ТипДампа;
			УстановитьПривилегированныйРежим(Ложь);
			ИзмененТипДампа = Истина;
		КонецЕсли;   		
	КонецЕсли;
	
	// Проверим, сможем ли мы изменить logcfg при необходимости и получим каталог хранения дампов
	// Заодно проверим, включен ли сбор дампов.
	ТипДампа = ПараметрыСбораИОтправкиДампов.ТипДампа;
	КаталогДампов = ПолучитьКаталогДампов(ТипДампа);
	ПараметрыСбораИОтправкиДампов.Вставить("КаталогДампов", КаталогДампов.Путь);
	Если КаталогДампов.Путь = Неопределено Тогда
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрЦентраМониторинга("РезультатОтправки", КаталогДампов.ОписаниеОшибки);
		УстановитьПривилегированныйРежим(Ложь);
		ПрекратитьСборПолныхДампов();
		Возврат;	
	Иначе
		Если ПараметрыСбораИОтправкиДампов.ОтправлятьФайлыДампов = 1
			ИЛИ ПараметрыСбораИОтправкиДампов.ПринудительнаяОтправкаМинидампов = 1
			И ПараметрыСбораИОтправкиДампов.ТипДампа = "0" Тогда
			ПараметрыСбораИОтправкиДампов.СборПолныхДамповВключен.Вставить(ИмяКомпьютера, Истина);
		КонецЕсли;
	КонецЕсли;                                  
	
	// Получим данные о свободном месте на диске, куда собираются дампы.
	ПозицияРазделителя = СтрНайти(КаталогДампов.Путь, ПолучитьРазделительПутиСервера());
	Если ПозицияРазделителя = 0 Тогда
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрЦентраМониторинга("РезультатОтправки", НСтр("ru = 'Не удалось определить букву диска'"));
		УстановитьПривилегированныйРежим(Ложь);
		ПрекратитьСборПолныхДампов();
		Возврат;
	КонецЕсли;
	БукваДиска = Лев(КаталогДампов.Путь, ПозицияРазделителя-1);
		                                    	
	// Если сбор включен.
	Если ПараметрыСбораИОтправкиДампов.СборПолныхДамповВключен[ИмяКомпьютера] = Истина Тогда
		
		Если ПустаяСтрока(ИдентификаторЗадания) Тогда
			ИдентификаторЗадания = "ВыполнениеНаСервере";
		КонецЕсли;
		
		// Если изменен тип дампа, то надо очистить каталог дампов.
		Если ИзмененТипДампа Тогда
			ФайлыУдалены(КаталогДампов.Путь);
		Иначе
			// Собираем дампы.
			СобратьДампы(ПараметрыСбораИОтправкиДампов);
		КонецЕсли;
		
		// Отправляем дампы.
		ОтправитьДампы(ПараметрыСбораИОтправкиДампов);
		
		РезультатЗамера = СвободноеМестоНаДиске(БукваДиска, СКлиентаНаСервере);
		Если НЕ РезультатЗамера.Успешно Тогда
			УстановитьПривилегированныйРежим(Истина);
			УстановитьПараметрЦентраМониторинга("РезультатОтправки", РезультатЗамера.ОписаниеОшибки);
			УстановитьПривилегированныйРежим(Ложь);
			ПрекратитьСборПолныхДампов();
			Возврат;
		КонецЕсли;
		
		// Проверим, достаточно ли свободного места для сбора полных дампов.
		// Проверка идет после сбора и отправки, так как в ходе сбора и отправки дампов место освободится.
		Если РезультатЗамера.Значение/1024 < ПараметрыСбораИОтправкиДампов.РезервМестаВключен
			И ТипДампа = "3" Тогда
			УстановитьПривилегированныйРежим(Истина);
			УстановитьПараметрЦентраМониторинга("РезультатОтправки", НСтр("ru = 'Недостаточно свободного места для хранения дампов. Сбор дампов будет отключен.'"));	
			УстановитьПривилегированныйРежим(Ложь);
			ПрекратитьСборПолныхДампов();
			Возврат;
		КонецЕсли;
		
		СборПолныхДамповВключен = ПолучитьПараметрыЦентраМониторинга("СборПолныхДамповВключен");
		СборПолныхДамповВключен.Вставить(ИмяКомпьютера, Истина);
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрыЦентраМониторинга(Новый Структура("БазовыеПроверкиПройдены, СборПолныхДамповВключен, РезультатОтправки", Истина, СборПолныхДамповВключен, ""));
		УстановитьПривилегированныйРежим(Ложь);
		
	Иначе
		// Если сбор выключен.
		РезультатЗамера = СвободноеМестоНаДиске(БукваДиска, СКлиентаНаСервере);
		Если НЕ РезультатЗамера.Успешно Тогда
			УстановитьПривилегированныйРежим(Истина);
			УстановитьПараметрЦентраМониторинга("РезультатОтправки", РезультатЗамера.ОписаниеОшибки);
			УстановитьПривилегированныйРежим(Ложь);
			ПрекратитьСборПолныхДампов();
			Возврат;
		КонецЕсли;
		
		// Проверим, достаточно ли свободного места для сбора полных дампов.
		Если РезультатЗамера.Значение/1024 < ПараметрыСбораИОтправкиДампов.РезервМестаВыключен
			И ТипДампа = "3" Тогда
			УстановитьПривилегированныйРежим(Истина);
			УстановитьПараметрЦентраМониторинга("РезультатОтправки", НСтр("ru = 'Недостаточно свободного места для сбора дампов.'"));	
			УстановитьПривилегированныйРежим(Ложь);
			ПрекратитьСборПолныхДампов();
			Возврат;
		КонецЕсли;
		
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрыЦентраМониторинга(Новый Структура("БазовыеПроверкиПройдены, РезультатОтправки", Истина, ""));
		УстановитьПривилегированныйРежим(Ложь);
				
		// Автоматически формируется текущее дело в ПриЗаполненииСпискаТекущихДел.
		
	КонецЕсли;
	
	// Удаляет устаревшие файлы дампов, кроме запрошенных.
	УдалитьУстаревшиеФайлы(ВариантДампа, КаталогДампов.Путь);
			
КонецПроцедуры

Процедура СобратьДампы(Параметры)
	
	// Получаем каталог хранения дампов.
	КаталогДампов = Параметры.КаталогДампов;
	
	ИмяСвойства = ?(Параметры.СпрашиватьПередОтправкой И Параметры.ТипДампа = "3", "ВариантыДампов", "ВариантыДамповОдобренные");
	
	Если НЕ Параметры.Свойство(ИмяСвойства) Тогда
		Параметры.Вставить(ИмяСвойства, Новый Соответствие);	
	КонецЕсли;
	
	ИмяКомпьютера = ИмяКомпьютера();
		
	// Ищем дампы в каталоге.
	ФайлыДампов = НайтиФайлы(КаталогДампов, "*.mdmp");
	ЕстьИзменения = Ложь;
	// Перебираем найденные дампы.
	Для Каждого ФайлДампа Из ФайлыДампов Цикл	    
		
		// Если дампы с нулевым смещением - сразу удаляем.
		Если СтрНайти(ФайлДампа.ИмяБезРасширения, "00000000") > 0 Тогда
			ФайлыУдалены(ФайлДампа.ПолноеИмя);
			Продолжить;
		КонецЕсли;
		
		СтруктураДампа = ОписаниеДампа(ФайлДампа.Имя);
	 	
		ВариантДампа = СтруктураДампа.Процесс + "_" + СтруктураДампа.ВерсияПлатформы + "_" + СтруктураДампа.Смещение;
						
		// Если дамп с ненулевым смещением, то надо проверить, стоит ли его отправлять и соответствует ли он запрошенному.
		ТребованиеДампа = ДампТребуется(ВариантДампа, Параметры.ВариантДампа, Параметры.ТипДампа);
		Если ТребованиеДампа.Требуется Тогда
			
			ИмяАрхива = КаталогДампов + ВариантДампа + ".zip"; 
			
			// Архивируем дамп и записать о нем информацию (имя + размер).
			ЗаписьZipФайла = Новый ЗаписьZipФайла();
			ЗаписьZipФайла.Открыть(ИмяАрхива,,,МетодСжатияZIP.Сжатие);
			ЗаписьZipФайла.Добавить(ФайлДампа.ПолноеИмя);
			ЗаписьZipФайла.Записать();
			
			ФайлАрхива = Новый Файл(ИмяАрхива);
			Размер = Окр(ФайлАрхива.Размер()/1024/1024,3); // Размер файла в мегабайтах.
			
			ДанныеДампа = Новый Структура;
			ДанныеДампа.Вставить("ПолноеИмя", ИмяАрхива);
			ДанныеДампа.Вставить("Размер", Размер);
			ДанныеДампа.Вставить("ИмяКомпьютера", ИмяКомпьютера);
			
			Параметры[ИмяСвойства].Вставить(ВариантДампа, ДанныеДампа);
			
			ЕстьИзменения = Истина;
			
		КонецЕсли;
		
		// Удалить исходный дамп.
		ФайлыУдалены(ФайлДампа.ПолноеИмя);
		
	КонецЦикла;
	
	Если ЕстьИзменения Тогда 
		ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(Новый Структура(ИмяСвойства));
		Для Каждого Запись Из Параметры[ИмяСвойства] Цикл
			ПараметрыЦентраМониторинга[ИмяСвойства].Вставить(Запись.Ключ, Запись.Значение);	
		КонецЦикла;
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрЦентраМониторинга(ИмяСвойства, ПараметрыЦентраМониторинга[ИмяСвойства]);
		УстановитьПривилегированныйРежим(Ложь);
	КонецЕсли;
	
КонецПроцедуры

Процедура ОтправитьДампы(Параметры)
	
	Параметры.Вставить("ВариантыДамповОдобренные", ПолучитьПараметрыЦентраМониторинга("ВариантыДамповОдобренные"));
	
	Если Параметры.СпрашиватьПередОтправкой И Параметры.ТипДампа = "3" Тогда
		
		Если Параметры.Свойство("ВариантыДампов") И Параметры.ВариантыДампов.Количество() Тогда
	
			ШаблонЗапросДляОтправки = НСтр("ru = 'Для отправки подготовлены отчеты об ошибках (%1 шт.)
		                             |Общий объем данных: %2 МБ.
		                             |Отправить указанные файлы для анализа в фирму ""1С""?'");	
			
			ОбщийОбъем = 0;
			ВсегоШтук = 0;
						
			Для Каждого Запись Из Параметры.ВариантыДампов Цикл
				
				ВариантДампа = Запись.Ключ;
				ДанныеДампа = Запись.Значение; // Структура
				
				// Спросим у сервиса ЦМ нужен ли такой дамп.
				ТребованиеДампа = ДампТребуется(ВариантДампа, Параметры.ВариантДампа, Параметры.ТипДампа);
				Если ТребованиеДампа.Требуется Тогда
					ВсегоШтук = ВсегоШтук + 1;
					ОбщийОбъем = ОбщийОбъем + ДанныеДампа.Размер;
				Иначе
					ФайлыУдалены(ДанныеДампа.ПолноеИмя);
				КонецЕсли;
				
			КонецЦикла;
			
			// Спросим у пользователя, хочет ли он отправить дампы.
			ЗапросДляОтправки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонЗапросДляОтправки, ВсегоШтук, Формат(ОбщийОбъем,"ЧДЦ=; ЧН=0"));
			УстановитьПривилегированныйРежим(Истина);
			УстановитьПараметрЦентраМониторинга("ИнформацияОДампах", ЗапросДляОтправки);
			УстановитьПривилегированныйРежим(Ложь);
			
		КонецЕсли;
		
	Иначе
		Для Каждого Запись Из Параметры.ВариантыДампов Цикл
			Параметры.ВариантыДамповОдобренные.Вставить(Запись.Ключ, Запись.Значение);
		КонецЦикла;
		
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрЦентраМониторинга("ВариантыДамповОдобренные", Параметры.ВариантыДамповОдобренные);
		УстановитьПривилегированныйРежим(Ложь);
		
	КонецЕсли;             
	
	ИмяКомпьютера = ИмяКомпьютера();
	ТребуемыйДамп = Параметры.ВариантДампа;
	
	// Отправляем дампы.
	МассивОтправленных = Новый Массив;
	Для Каждого Запись Из Параметры.ВариантыДамповОдобренные Цикл
		// Есть смысл проверять, на той ли мы машине.
		Если ИмяКомпьютера <> Запись.Значение.ИмяКомпьютера Тогда
			Продолжить;
		КонецЕсли;
		Если ОтправкаДампа(Запись.Ключ, Запись.Значение, ТребуемыйДамп, Параметры.ТипДампа) Тогда
			МассивОтправленных.Добавить(Запись.Ключ);
		КонецЕсли;
	КонецЦикла;
	
	// Отправленные дампы убираем из константы.
	ЕстьИзменения = Ложь;
	Параметры.Вставить("ВариантыДамповОдобренные", ПолучитьПараметрыЦентраМониторинга("ВариантыДамповОдобренные"));
	Для Каждого Элемент Из МассивОтправленных Цикл
		Параметры.ВариантыДамповОдобренные.Удалить(Элемент);
		ЕстьИзменения = Истина;
	КонецЦикла;
	Если ЕстьИзменения Тогда 
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрЦентраМониторинга("ВариантыДамповОдобренные", Параметры.ВариантыДамповОдобренные);
		УстановитьПривилегированныйРежим(Ложь);
	КонецЕсли;
	
КонецПроцедуры

Процедура ПрекратитьСборПолныхДампов()
	
	Прекращен = Истина;
	
	// Очистить параметры сбора дампов.
	НовыеПараметры = Новый Структура;
	НовыеПараметры.Вставить("ВариантДампа", "");
	НовыеПараметры.Вставить("ВариантыДампов", Новый Соответствие);
	НовыеПараметры.Вставить("ВариантыДамповОдобренные", Новый Соответствие);
	НовыеПараметры.Вставить("ИнформацияОДампах", "");
	НовыеПараметры.Вставить("ТипДампа", "0");
	НовыеПараметры.Вставить("ДатаОповещения", Дата(1,1,1));
	НовыеПараметры.Вставить("БазовыеПроверкиПройдены", Ложь);
	
	Попытка
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрыЦентраМониторинга(НовыеПараметры);
		УстановитьПривилегированныйРежим(Ложь);
	Исключение
		// Не удалось отключить сбор полных дампов.
		Прекращен = Ложь;
	КонецПопытки;
	
	// Изменить logcfg.
	КаталогДампов = ПолучитьКаталогДампов("0", Истина);
	Если КаталогДампов.Путь = Неопределено Тогда
		// Не удалось изменить logcfg
		Прекращен = Ложь;
	КонецЕсли;
	// Удалить файлы дампов.
	Если КаталогДампов.Путь <> Неопределено Тогда
		Если НЕ ФайлыУдалены(КаталогДампов.Путь) Тогда
			// Не удалось удалить файлы дампов.
			Прекращен = Ложь;	
		КонецЕсли;
	КонецЕсли;	 
	
	Если Прекращен Тогда
		СборПолныхДамповВключен = ПолучитьПараметрыЦентраМониторинга("СборПолныхДамповВключен");
		СборПолныхДамповВключен.Удалить(ИмяКомпьютера());
		УстановитьПривилегированныйРежим(Истина);
		УстановитьПараметрЦентраМониторинга("СборПолныхДамповВключен", СборПолныхДамповВключен); 
		УстановитьПривилегированныйРежим(Ложь);
		УдалитьРегламентноеЗадание("СборИОтправкаОтчетовОбОшибках");
	КонецЕсли;
	
КонецПроцедуры

Процедура УдалитьУстаревшиеФайлы(ТребуемыйДамп, ПутьККаталогу)
	
	МассивФайлов = НайтиФайлы(ПутьККаталогу,"*");
	Для Каждого Файл Из МассивФайлов Цикл             		
		СтруктураДампа = ОписаниеДампа(Файл.Имя);	 	
		ВариантДампа = СтруктураДампа.Процесс + "_" + СтруктураДампа.ВерсияПлатформы + "_" + СтруктураДампа.Смещение;
		Если ВариантДампа = ТребуемыйДамп Тогда
			Продолжить;
		КонецЕсли;
		
		// Удалим файл старше трех дней.
		Если Файл.Существует() И ТекущаяДатаСеанса() - Файл.ПолучитьВремяИзменения() > 3*86400 Тогда
			ФайлыУдалены(Файл.ПолноеИмя);
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Функция СвободноеМестоНаДиске(БукваДиска, СКлиентаНаСервере)
	
	РезультатЗапроса = Новый Структура;
	РезультатЗапроса.Вставить("Значение", 0);
	РезультатЗапроса.Вставить("Успешно", Истина);
	РезультатЗапроса.Вставить("ОписаниеОшибки", ""); 
	
	КоманднаяСтрока = "typeperf ""\LogicalDisk(" + БукваДиска + ")\Free Megabytes"" -sc 1";
	
	ПараметрыЗапускаПрограммы = ФайловаяСистема.ПараметрыЗапускаПрограммы();
	ПараметрыЗапускаПрограммы.ДождатьсяЗавершения = Истина;
	ПараметрыЗапускаПрограммы.ПолучитьПотокВывода = Истина;
	ПараметрыЗапускаПрограммы.ПолучитьПотокОшибок = Истина;
	ПараметрыЗапускаПрограммы.КодировкаИсполнения = "OEM";
	
	РезультатЗапуска = ФайловаяСистема.ЗапуститьПрограмму(КоманднаяСтрока, ПараметрыЗапускаПрограммы);
	
	ПотокОшибок = РезультатЗапуска.ПотокОшибок;
	ПотокВывода = РезультатЗапуска.ПотокВывода;
	
	Если ЗначениеЗаполнено(ПотокОшибок) Тогда 
		РезультатЗапроса.Успешно = Ложь;
		РезультатЗапроса.ОписаниеОшибки = НСтр("ru = 'Ошибка при выполнении команды typeperf'");
	Иначе 
		МассивСтрок = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ПотокВывода, Символы.ПС, Истина, Истина);
		Если МассивСтрок.Количество() >= 2 Тогда
			ИскомаяСтрока = МассивСтрок[1];
			МассивПодстрок = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ИскомаяСтрока, ",", Истина, Истина);
			Если МассивПодстрок.Количество() >= 2 Тогда
				ИскомаяСтрока = МассивПодстрок[1];
				ИскомаяСтрока = СтрЗаменить(ИскомаяСтрока,"""","");
				Попытка
					РезультатЗапроса.Значение = Число(ИскомаяСтрока);
					ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистикиСутки(
						"СтатистикаКлиента.ИнформацияОСистеме.СвободноНаДиске." + БукваДиска, "", РезультатЗапроса.Значение, Истина);
				Исключение
					РезультатЗапроса.Успешно = Ложь;
					РезультатЗапроса.ОписаниеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
				КонецПопытки;
			КонецЕсли;
		Иначе
			РезультатЗапроса.Успешно = Ложь;
			РезультатЗапроса.ОписаниеОшибки = НСтр("ru = 'Не удалось разобрать результат typeperf'");
		КонецЕсли;
	КонецЕсли;
	
	Возврат РезультатЗапроса;
	
КонецФункции

// Возвращает необходимость сбора дампа.
// Если тип дампа указан, возвращает только необходимость.
// Если тип дампа не указан, возвращает необходимость и тип.
// В случае недоступности сервиса собираем полные.
//
Функция ДампТребуется(ВариантДампа, ЗапрошенныйДамп, ТипДампа = "")
	
	Результат = Новый Структура("Требуется, ТипДампа", Ложь, ТипДампа);
	ТребуемыеДампы = ТребуемыеДампы(ВариантДампа);
	
	// Если запрос не удалось выполнить, будем считать, что дамп требуется в том случае,
	// когда он совпадает с с требуемым дампом.
	Если НЕ ТребуемыеДампы.ЗапросУспешен Тогда
		Если ВариантДампа = ЗапрошенныйДамп Тогда
			Результат.Требуется = Истина;
			Результат.ТипДампа = "3";
		КонецЕсли;
	Иначе
		// Проверка при сборе/отправке.
		Если Не ПустаяСтрока(ТипДампа) Тогда
			Если ТипДампа = "0" И ТребуемыеДампы.Минидамп Тогда
				Результат.Требуется = Истина;
			ИначеЕсли ТипДампа = "3" И ТребуемыеДампы.ПолныйДамп Тогда
				Результат.Требуется = Истина;
			КонецЕсли;
		Иначе
			// На случай, когда надо определить тип собираемого дампа.
			Если ТребуемыеДампы.Минидамп Тогда
				Результат.Требуется = Истина;
				Результат.ТипДампа = "0";
			ИначеЕсли ТребуемыеДампы.ПолныйДамп Тогда
				Результат.Требуется = Истина;
				Результат.ТипДампа = "3";
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;  
	
	Возврат Результат;
	
КонецФункции

// Возвращает требуемые типы дампов по варианту дампа.
//
Функция ТребуемыеДампы(ВариантДампа)
	Результат = Новый Структура("ЗапросУспешен, Минидамп, ПолныйДамп", Ложь, Ложь, Ложь);
	
	// Обратимся к http-сервису.
	Параметры = ПолучитьПараметрыСервисаОтправки(); 
		
	// Узнаем, актуален ли дамп. 	
	АдресРесурса = Параметры.АдресРесурсаДляДампов;
	Если Прав(АдресРесурса, 1) <> "/" Тогда
		АдресРесурса = АдресРесурса + "/";
	КонецЕсли;
	
	ГУИД = Строка(Параметры.ИдентификаторИнформационнойБазы);
	АдресРесурса = АдресРесурса + "IsDumpNeeded" + "/" + ГУИД + "/" + ВариантДампа + "/json";
	
	ПараметрыHTTP = Новый Структура;
	ПараметрыHTTP.Вставить("Сервер", Параметры.Сервер);
	ПараметрыHTTP.Вставить("АдресРесурса", АдресРесурса);
	ПараметрыHTTP.Вставить("Данные", "");
	ПараметрыHTTP.Вставить("Порт", Параметры.Порт);
	ПараметрыHTTP.Вставить("ЗащищенноеСоединение", Параметры.ЗащищенноеСоединение);	
	ПараметрыHTTP.Вставить("Метод", "GET");
	ПараметрыHTTP.Вставить("ТипДанных", "");
	ПараметрыHTTP.Вставить("Таймаут", 60);
	
	HTTPОтвет = HTTPСервисОтправитьДанныеСлужебный(ПараметрыHTTP);
	
	Если HTTPОтвет.КодСостояния = 200 Тогда
		Ответ = ОбщегоНазначения.JSONВЗначение(HTTPОтвет.Тело, , Ложь);
		Результат.Минидамп = Ответ.MiniDump;
		Результат.ПолныйДамп = Ответ.FullDump;
		Результат.ЗапросУспешен = Истина;
	КонецЕсли;
	
	Возврат Результат;
КонецФункции 

Функция МожноЗагружатьДамп(ВариантДампа, ТипДампа)
	
	Результат = Ложь;
	
	// Обратимся к http-сервису.
	Параметры = ПолучитьПараметрыСервисаОтправки(); 
		
	// Узнаем, актуален ли дамп. 	
	АдресРесурса = Параметры.АдресРесурсаДляДампов;
	Если Прав(АдресРесурса, 1) <> "/" Тогда
		АдресРесурса = АдресРесурса + "/";
	КонецЕсли;
	
	ГУИД = Строка(Параметры.ИдентификаторИнформационнойБазы);
	АдресРесурса = АдресРесурса + "CanLoadDump" + "/" + ГУИД + "/" + ВариантДампа + "/" + ТипДампа;
	
	ПараметрыHTTP = Новый Структура;
	ПараметрыHTTP.Вставить("Сервер", Параметры.Сервер);
	ПараметрыHTTP.Вставить("АдресРесурса", АдресРесурса);
	ПараметрыHTTP.Вставить("Данные", "");
	ПараметрыHTTP.Вставить("Порт", Параметры.Порт);
	ПараметрыHTTP.Вставить("ЗащищенноеСоединение", Параметры.ЗащищенноеСоединение);	
	ПараметрыHTTP.Вставить("Метод", "GET");
	ПараметрыHTTP.Вставить("ТипДанных", "");
	ПараметрыHTTP.Вставить("Таймаут", 60);
	
	HTTPОтвет = HTTPСервисОтправитьДанныеСлужебный(ПараметрыHTTP);
	
	Если HTTPОтвет.КодСостояния = 200 Тогда
		Результат = HTTPОтвет.Тело = "true";
	КонецЕсли;
		
	Возврат Результат;
	
КонецФункции

Функция ОтправкаДампа(ВариантДампа, Данные, ТребуемыйДамп, ТипДампа)
	
	РезультатОтправки = Ложь;
	
	// Проверим, существует ли файл.
	// Могут быть такие ситуации, когда дамп есть в списке одобренных, но по факту файла уже нет.
	// Тогда считаем, что он успешно отправлен.
	Файл = Новый Файл(Данные.ПолноеИмя);
	Если НЕ Файл.Существует() Тогда
		Возврат Истина;
	КонецЕсли;
	
	// Проверим, актуален ли еще дамп. Если нет - удалим.
	ТребованиеДампа = ДампТребуется(ВариантДампа, ТребуемыйДамп, ТипДампа);
	Если Не ТребованиеДампа.Требуется Тогда
		ФайлыУдалены(Данные.ПолноеИмя);
		Возврат Истина;
	КонецЕсли;
	
	// Проверим, разрешит ли нам сервер загружать дамп, возможно нужно подождать.
	Если Не МожноЗагружатьДамп(ВариантДампа, ТипДампа) Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Параметры = ПолучитьПараметрыСервисаОтправки();
	
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	// Отправим дамп через http-сервис.
	ГУИД = Строка(Параметры.ИдентификаторИнформационнойБазы);
	Хеш = Новый ХешированиеДанных(ХешФункция.CRC32);
	Хеш.ДобавитьФайл(Данные.ПолноеИмя);
	ХешСуммаДампа = Формат(Хеш.ХешСумма,"ЧГ=0"); 
	
	АдресРесурса = Параметры.АдресРесурсаДляДампов;
	Если Прав(АдресРесурса, 1) <> "/" Тогда
		АдресРесурса = АдресРесурса + "/";
	КонецЕсли;
	
	АдресРесурса = АдресРесурса + "LoadDump" + "/" + ГУИД + "/" + ВариантДампа + "/" + ХешСуммаДампа + "/" + ТипДампа;
	
	ПараметрыHTTP = Новый Структура;
	ПараметрыHTTP.Вставить("Сервер", Параметры.Сервер);
	ПараметрыHTTP.Вставить("АдресРесурса", АдресРесурса);
	ПараметрыHTTP.Вставить("Данные", Данные.ПолноеИмя);
	ПараметрыHTTP.Вставить("Порт", Параметры.Порт);
	ПараметрыHTTP.Вставить("ЗащищенноеСоединение", Параметры.ЗащищенноеСоединение);	
	ПараметрыHTTP.Вставить("Метод", "POST");
	ПараметрыHTTP.Вставить("ТипДанных", "ДвоичныеДанные");
	ПараметрыHTTP.Вставить("Таймаут", 0);
	
	// Архив удаляется при успешной отправке.
	HTTPОтвет = HTTPСервисОтправитьДанныеСлужебный(ПараметрыHTTP);
	
	Если HTTPОтвет.КодСостояния = 200 Тогда
		РезультатОтправки = HTTPОтвет.Тело = "true";	
	КонецЕсли;
		
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаОтправитьОтчетОбОшибках", ВремяНачала);
	КонецЕсли;
	
	Возврат РезультатОтправки;
		
КонецФункции

Функция ФайлыУдалены(Путь, Маска = "")
	Попытка
		УдалитьФайлы(Путь, Маска)
	Исключение
		Возврат Ложь;
	КонецПопытки;
	Возврат Истина;
КонецФункции

Процедура ПроверитьНеобходимостьОповещенияОДампах(ПутьККаталогуДампов)
	
	ПараметрыЦентраМониторинга = Новый Структура();
	ПараметрыЦентраМониторинга.Вставить("ОтправлятьФайлыДампов");
	ПараметрыЦентраМониторинга.Вставить("ВариантДампа");
	ПараметрыЦентраМониторинга.Вставить("ОкончаниеСбораДампов");
	ПараметрыЦентраМониторинга.Вставить("ГлубинаПроверкиДампов");
	ПараметрыЦентраМониторинга.Вставить("МинимальноеКоличествоДампов");
	ПараметрыЦентраМониторинга.Вставить("ПроверкаДамповСледующая");
	ПараметрыЦентраМониторинга.Вставить("ПроверкаДамповПериодичность");
	ПараметрыЦентраМониторинга.Вставить("ТипДампа");
	ПараметрыЦентраМониторинга.Вставить("РезервМестаВыключен");
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	
	// Администратор отказался от сбора и отправки дампов.
	Если ПараметрыЦентраМониторинга.ОтправлятьФайлыДампов = 0 Тогда
		Возврат;
	КонецЕсли;
	
	ТекущаяДата = ТекущаяУниверсальнаяДата();
	// Сбор дампов уже включен, не нужно проверок.
	Если Не ПараметрыЦентраМониторинга.ОтправлятьФайлыДампов = 0
		И Не ПустаяСтрока(ПараметрыЦентраМониторинга.ВариантДампа)
		И ТекущаяДата < ПараметрыЦентраМониторинга.ОкончаниеСбораДампов Тогда
		Возврат;
	КонецЕсли;  
	
	// Если время следующей проверки не подошло.
	Если ПараметрыЦентраМониторинга.ПроверкаДамповСледующая > ТекущаяДата Тогда
		Возврат;
	КонецЕсли;
	
	УстановитьПараметрЦентраМониторинга("ПроверкаДамповСледующая", ТекущаяДата + ПараметрыЦентраМониторинга.ПроверкаДамповПериодичность);
	
	ДатаНачала = ТекущаяДата - ПараметрыЦентраМониторинга.ГлубинаПроверкиДампов;
	
	СисИнфо = Новый СистемнаяИнформация;
	
	ТопДампов = РегистрыСведений.ДампыПлатформы.ПолучитьТопВариантов(ДатаНачала, ТекущаяДата, 10, СисИнфо.ВерсияПриложения);
	Для Каждого СтрокаТаблицы Из ТопДампов Цикл
		// Если дампов возникло больше минимума, проверяем, нужен ли он.
		Если СтрокаТаблицы.КоличествоВариантов >=	ПараметрыЦентраМониторинга.МинимальноеКоличествоДампов Тогда
			// Если дамп нужен, то инициируем его сбор.
			ТребованиеДампа = ДампТребуется(СтрокаТаблицы.ВариантДампа, "");
			Если ТребованиеДампа.Требуется Тогда
				Если ТребованиеДампа.ТипДампа = "3" Тогда
					// Для полного дампа проверяем, достаточно ли места.
					ПозицияРазделителя = СтрНайти(ПутьККаталогуДампов, ПолучитьРазделительПутиСервера());
					Если ПозицияРазделителя = 0 Тогда
						Продолжить;	
					КонецЕсли;
					БукваДиска = Лев(ПутьККаталогуДампов, ПозицияРазделителя-1);
					РезультатЗамера = СвободноеМестоНаДиске(БукваДиска, Ложь);
					Если НЕ РезультатЗамера.Успешно Тогда
						Продолжить;
					КонецЕсли;
					Если РезультатЗамера.Значение/1024 < ПараметрыЦентраМониторинга.РезервМестаВыключен Тогда
						Продолжить;
					КонецЕсли;
				КонецЕсли;
				
			    // Устанавливаем параметры сбора дампов.
				НовыеПараметры = Новый Структура;
				НовыеПараметры.Вставить("ВариантДампа", СтрокаТаблицы.ВариантДампа);
				НовыеПараметры.Вставить("ОкончаниеСбораДампов", НачалоДня(ТекущаяДата)+30*86400);
				// Пока пользователь не согласился, на даем возможности включить сбор полных дампов.
				Если ПараметрыЦентраМониторинга.ОтправлятьФайлыДампов = 1 Тогда
					НовыеПараметры.Вставить("ТипДампа", ТребованиеДампа.ТипДампа);
				Иначе
					НовыеПараметры.Вставить("ТипДампа", "0");
				КонецЕсли;
				УстановитьПараметрыЦентраМониторинга(НовыеПараметры);
				ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистики("ЦентрМониторинга.РегистрацияДампов.ОповеститьАдминистратора", 1);
								
				// Прерываем обход коллекции, т.к. запросили сбор дампов у Администратора.
				Прервать;
				
			КонецЕсли;
		Иначе
			// Прерываем обход коллекции, если дампов меньше минимума.
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область ОтправкаТестовогоПакета

// Отправляет тестовый пакет в центр мониторинга.
// Параметры:
//  ПараметрыВыполнения        - Структура:
//   * Итератор          	   - Число - при вызове извне должен быть равен 0.
//   * ОтправкаТестовогоПакета - Булево.
//   * ПолучениеИдентификатора - Булево.
//
Процедура ОтправитьТестовыйПакет(ПараметрыВыполнения, АдресРезультата) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	РезультатВыполнения = Новый Структура("Успешно, КраткоеПредставлениеОшибки", Истина, "");
	
	ОценкаПроизводительностиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности");
	Если ОценкаПроизводительностиСуществует Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	// Отключим, чтобы не отправить лишнего.
	ОтключитьРегистрациюСобытий();
	
	ДатаЗапуска = ТекущаяУниверсальнаяДата();
	ПараметрыЦентраМониторинга = Новый Структура();
	ПараметрыЦентраМониторинга.Вставить("ТестовыйПакетОтправлен");
	ПараметрыЦентраМониторинга.Вставить("ЧислоПопытокОтправкиТестовогоПакета");
	ПараметрыЦентраМониторинга.Вставить("ОтправкаДанныхСледующееФормирование");
	ПараметрыЦентраМониторинга.Вставить("ОтправкаДанныхПериодФормирования");
	ПараметрыЦентраМониторинга.Вставить("ВключитьЦентрМониторинга");
	ПараметрыЦентраМониторинга.Вставить("ЦентрОбработкиИнформацииОПрограмме");
	ПараметрыЦентраМониторинга.Вставить("ОзнакомительныйПакетОтправлен");
	
	ПараметрыЦентраМониторинга = ПолучитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
	
	Если ОтправкаТестовогоПакетаВозможна(ПараметрыЦентраМониторинга, ДатаЗапуска) И ПараметрыВыполнения.ОтправкаТестовогоПакета
		ИЛИ ПолученияИдентификатораВозможно(ПараметрыЦентраМониторинга) И ПараметрыВыполнения.ПолучениеИдентификатора Тогда
		
		Попытка
			СформироватьПакетДляОтправки();
		Исключение
			РезультатВыполнения.Успешно = Ложь;
			РезультатВыполнения.КраткоеПредставлениеОшибки = НСтр("ru = 'Ошибка при формировании пакета.'");
			Комментарий = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Сформировать тестовый пакет для отправки'",
				ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, Комментарий);
		КонецПопытки;
		
		Попытка
			HTTPОтвет = ОтправитьДанныеМониторинга(ПараметрыВыполнения.ОтправкаТестовогоПакета);
			Если HTTPОтвет.КодСостояния = 200 Тогда
				ПараметрыЦентраМониторинга.ТестовыйПакетОтправлен = Истина;
			Иначе
				РезультатВыполнения.Успешно = Ложь;
				РезультатВыполнения.КраткоеПредставлениеОшибки = НСтр("ru = 'Ошибка при отправке пакета.'");
				Шаблон = НСтр("ru = 'Ошибка HTTP при отправке пакета. Код %1'");
				Комментарий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, HTTPОтвет.КодСостояния); 
				ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Отправить тестовые данные мониторинга'",
					ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, Комментарий);
			КонецЕсли;
		Исключение
			РезультатВыполнения.Успешно = Ложь;
			РезультатВыполнения.КраткоеПредставлениеОшибки = НСтр("ru = 'Ошибка при отправке пакета.'");
			Комментарий = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Центр мониторинга.Отправить тестовые данные мониторинга'",
				ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, Комментарий);
			ЦентрМониторинга.ЗаписатьОперациюБизнесСтатистики("ЦентрМониторинга.ОтправитьДанныеМониторинга.Ошибка", 
				1, Комментарий);
		КонецПопытки;
		
		Если РезультатВыполнения.Успешно Тогда
			ПараметрыВыполнения.Вставить("Итератор", ПараметрыВыполнения.Итератор + 1);
		КонецЕсли;
		
		ОзнакомительныйПакетОтправлен = ПолучитьПараметрыЦентраМониторинга("ОзнакомительныйПакетОтправлен");
		
		Если РезультатВыполнения.Успешно И НЕ ОзнакомительныйПакетОтправлен И ПараметрыВыполнения.Итератор < 2 Тогда
			// Идентификатор изменился, необходимо повторить отправку.
			ОтправитьТестовыйПакет(ПараметрыВыполнения, АдресРезультата);
		ИначеЕсли РезультатВыполнения.Успешно И ОзнакомительныйПакетОтправлен Тогда	
		
			Если ПараметрыВыполнения.ПолучениеИдентификатора Тогда
				// Отправим пакет с данными через час.
				УстановитьПараметрЦентраМониторинга("ОтправкаДанныхСледующееФормирование", ТекущаяУниверсальнаяДата() + 3600); 
				ПоместитьВоВременноеХранилище(РезультатВыполнения, АдресРезультата);
				Если ОценкаПроизводительностиСуществует Тогда
					МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ЦентрМониторингаЗнакомство", ВремяНачала);
				КонецЕсли;
			КонецЕсли; 			
		ИначеЕсли ПараметрыВыполнения.ПолучениеИдентификатора И НЕ РезультатВыполнения.Успешно Тогда
			ПоместитьВоВременноеХранилище(РезультатВыполнения, АдресРезультата);		
		КонецЕсли;
		
		Если ПараметрыВыполнения.ОтправкаТестовогоПакета Тогда
			ПараметрыЦентраМониторинга.ОтправкаДанныхСледующееФормирование = ТекущаяУниверсальнаяДата()
			+ ПолучитьПараметрыЦентраМониторинга("ОтправкаДанныхПериодФормирования");
			ПараметрыЦентраМониторинга.ЧислоПопытокОтправкиТестовогоПакета = ПараметрыЦентраМониторинга.ЧислоПопытокОтправкиТестовогоПакета + 1;
			
			ПараметрыЦентраМониторинга.Удалить("ОтправкаДанныхПериодФормирования");
			ПараметрыЦентраМониторинга.Удалить("ВключитьЦентрМониторинга");
			ПараметрыЦентраМониторинга.Удалить("ЦентрОбработкиИнформацииОПрограмме");
			ПараметрыЦентраМониторинга.Удалить("ОзнакомительныйПакетОтправлен");
			
			УстановитьПараметрыЦентраМониторинга(ПараметрыЦентраМониторинга);
		КонецЕсли;
		
	ИначеЕсли ПараметрыВыполнения.ПолучениеИдентификатора И ПараметрыЦентраМониторинга.ОзнакомительныйПакетОтправлен Тогда
		ПоместитьВоВременноеХранилище(РезультатВыполнения, АдресРезультата);	
	КонецЕсли;
		
	УстановитьПривилегированныйРежим(Ложь);
	
КонецПроцедуры

Функция ОтправкаТестовогоПакетаВозможна(ПараметрыЦентраМониторинга, ДатаЗапуска)
	Возврат НЕ ПараметрыЦентраМониторинга.ТестовыйПакетОтправлен И ПараметрыЦентраМониторинга.ЧислоПопытокОтправкиТестовогоПакета < 3
		И ЭтоГлавныйУзел() И ДатаЗапуска >= ПараметрыЦентраМониторинга.ОтправкаДанныхСледующееФормирование;
КонецФункции
	
Функция ПолученияИдентификатораВозможно(ПараметрыЦентраМониторинга)
	Возврат (ПараметрыЦентраМониторинга.ВключитьЦентрМониторинга ИЛИ ПараметрыЦентраМониторинга.ЦентрОбработкиИнформацииОПрограмме)
		И ЭтоГлавныйУзел() И ПараметрыЦентраМониторинга.ОзнакомительныйПакетОтправлен = Ложь;
КонецФункции

#КонецОбласти

#Область НастройкаОбработкиОшибок

Процедура УстановитьДополнительнуюИнформациюОбработкиОшибок() Экспорт
	ИдентификаторИнформационнойБазы = ЦентрМониторинга.ИдентификаторИнформационнойБазы();
	// Если идентификатор не задан - ничего не делаем.
	Если Не ЗначениеЗаполнено(ИдентификаторИнформационнойБазы) Тогда
		Возврат;
	КонецЕсли;
	Если ОбщегоНазначения.РазделениеВключено() И ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
		ОбластьДанных = МодульРаботаВМоделиСервиса.ЗначениеРазделителяСеанса();
	Иначе
		ОбластьДанных = 0;
	КонецЕсли;

	Если БезопасныйРежим() = Истина Тогда
		УстановитьОтключениеБезопасногоРежима(Истина);
	КонецЕсли;
	УстановитьПривилегированныйРежим(Истина);
	ОбщиеНастройки = ОбработкаОшибок.ПолучитьОбщиеНастройки();
	УстановитьПривилегированныйРежим(Ложь);

	ДополнительнаяИнформация = Новый Структура;
	Если ЗначениеЗаполнено(ОбщиеНастройки.ДополнительнаяИнформацияОтчета) Тогда
		// Считаем, что внутри json. Если нет, то кто-то установил руками. Тогда ничего не меняем - так и должно быть.
		ДополнительнаяИнформация = ОбщегоНазначения.JSONВЗначение(ОбщиеНастройки.ДополнительнаяИнформацияОтчета, , Ложь);
	КонецЕсли;
	Если ДополнительнаяИнформация.Свойство("guid") 
		И ДополнительнаяИнформация.guid = ИдентификаторИнформационнойБазы Тогда
		Возврат;
	КонецЕсли;
	ДополнительнаяИнформация.Вставить("guid", ИдентификаторИнформационнойБазы);
	ДополнительнаяИнформация.Вставить("region", ОбластьДанных);
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет));
	ЗаписатьJSON(ЗаписьJSON, ДополнительнаяИнформация);
	ОбщиеНастройки.ДополнительнаяИнформацияОтчета = ЗаписьJSON.Закрыть();
	
	УстановитьПривилегированныйРежим(Истина);
	ОбработкаОшибок.УстановитьОбщиеНастройки(ОбщиеНастройки);
	УстановитьПривилегированныйРежим(Ложь);
	
КонецПроцедуры

Функция УстановкаНастроекОбработкиОшибок(СохраненныеПараметры, ПолученныеПараметры)
	
	РезультатОбработки = Новый Структура;
	
	Если БезопасныйРежим() = Истина Тогда
		УстановитьОтключениеБезопасногоРежима(Истина);
	КонецЕсли;
	УстановитьПривилегированныйРежим(Истина);
	ОбщиеНастройки = ОбработкаОшибок.ПолучитьОбщиеНастройки();
	ПеречислениеРежимОтправкиИнформацииОбОшибке = РежимОтправкиИнформацииОбОшибке;
	ПеречислениеВариантОтображенияСообщенияОбОшибке = ВариантОтображенияСообщенияОбОшибке;
	УстановитьПривилегированныйРежим(Ложь);
// 	Сравниваем с сохраненными параметрами, чтобы убедиться, что руками пользователь ничего не менял.
	Если ПолученныеПараметры.Свойство("АдресСервисаРегистрацииОшибок") 
		И (ОбщиеНастройки.АдресСервисаОбработкиОшибок  = СохраненныеПараметры.АдресСервисаРегистрацииОшибок
		ИЛИ ПолученныеПараметры.УстановитьНастройкиОбработкиОшибокПринудительно) Тогда
		ОбщиеНастройки.АдресСервисаОбработкиОшибок  = ПолученныеПараметры.АдресСервисаРегистрацииОшибок;
		РезультатОбработки.Вставить("АдресСервисаРегистрацииОшибок", ПолученныеПараметры.АдресСервисаРегистрацииОшибок);
	КонецЕсли;
	Если ПолученныеПараметры.Свойство("ОтправлятьОтчет") 
		И (ОбщиеНастройки.ОтправлятьОтчетНаКлиенте = ПеречислениеРежимОтправкиИнформацииОбОшибке[СохраненныеПараметры.ОтправлятьОтчет]
		ИЛИ ПолученныеПараметры.УстановитьНастройкиОбработкиОшибокПринудительно) Тогда
		ОбщиеНастройки.ОтправлятьОтчетНаКлиенте = ПеречислениеРежимОтправкиИнформацииОбОшибке[ПолученныеПараметры.ОтправлятьОтчет];	
		РезультатОбработки.Вставить("ОтправлятьОтчет", ПолученныеПараметры.ОтправлятьОтчет);
	КонецЕсли;
	Если ПолученныеПараметры.Свойство("ВариантОтображенияСообщенияОбОшибке") 
		И (ОбщиеНастройки.ВариантОтображенияСообщения = ПеречислениеВариантОтображенияСообщенияОбОшибке[СохраненныеПараметры.ВариантОтображенияСообщенияОбОшибке]
		ИЛИ ПолученныеПараметры.УстановитьНастройкиОбработкиОшибокПринудительно) Тогда
		ОбщиеНастройки.ВариантОтображенияСообщения = ПеречислениеВариантОтображенияСообщенияОбОшибке[ПолученныеПараметры.ВариантОтображенияСообщенияОбОшибке];
		// Текст сообщения.
		ПараметрыДляТекстаСообщения = Новый Структура("ОбщиеНастройки", ОбщиеНастройки);
		СтрокаСообщения = СтроковыеФункции.ФорматированнаяСтрока(
			СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(	
				НСтр("ru = '<span style=""font:%1"">К сожалению, возникла непредвиденная ситуация</span>'"),
				"ШрифтОченьКрупныйШрифтТекста"));
		ТекстыСообщенияОбОшибке = Новый ТекстыСообщенияОбОшибке(СтрокаСообщения, СтрокаСообщения);
		ОбщиеНастройки.ТекстыСообщенийОбОшибках.Вставить(КатегорияОшибки.ПрочаяОшибка, ТекстыСообщенияОбОшибке);	
		РезультатОбработки.Вставить("ВариантОтображенияСообщенияОбОшибке", ПолученныеПараметры.ВариантОтображенияСообщенияОбОшибке);
	КонецЕсли;
	Если ПолученныеПараметры.Свойство("ВключатьПодробныйТекстОшибкиВОтчет") 
		И (ОбщиеНастройки.ВключатьПодробныйТекстОшибкиВОтчетНаКлиенте = ПеречислениеРежимОтправкиИнформацииОбОшибке[СохраненныеПараметры.ВключатьПодробныйТекстОшибкиВОтчет]
		ИЛИ ПолученныеПараметры.УстановитьНастройкиОбработкиОшибокПринудительно) Тогда
		ОбщиеНастройки.ВключатьПодробныйТекстОшибкиВОтчетНаКлиенте = ПеречислениеРежимОтправкиИнформацииОбОшибке[ПолученныеПараметры.ВключатьПодробныйТекстОшибкиВОтчет];
		РезультатОбработки.Вставить("ВключатьПодробныйТекстОшибкиВОтчет", ПолученныеПараметры.ВключатьПодробныйТекстОшибкиВОтчет);
	КонецЕсли;
	Если ПолученныеПараметры.Свойство("ВключатьСведенияОбИнформационнойБазеВОтчет") 
		И (ОбщиеНастройки.ВключатьСведенияОбИнформационнойБазеВОтчетНаКлиенте = ПеречислениеРежимОтправкиИнформацииОбОшибке[СохраненныеПараметры.ВключатьСведенияОбИнформационнойБазеВОтчет]
		ИЛИ ПолученныеПараметры.УстановитьНастройкиОбработкиОшибокПринудительно) Тогда
		ОбщиеНастройки.ВключатьСведенияОбИнформационнойБазеВОтчетНаКлиенте = ПеречислениеРежимОтправкиИнформацииОбОшибке[ПолученныеПараметры.ВключатьСведенияОбИнформационнойБазеВОтчет];
		РезультатОбработки.Вставить("ВключатьСведенияОбИнформационнойБазеВОтчет", ПолученныеПараметры.ВключатьСведенияОбИнформационнойБазеВОтчет);
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	ОбработкаОшибок.УстановитьОбщиеНастройки(ОбщиеНастройки);
	УстановитьПривилегированныйРежим(Ложь);	
	
	РезультатОбработки.Вставить("УстановитьНастройкиОбработкиОшибокПринудительно", ПолученныеПараметры.УстановитьНастройкиОбработкиОшибокПринудительно);	
		
	Возврат РезультатОбработки;
	
КонецФункции

#КонецОбласти

#Область ДанныеИспользованияППД

Процедура ПолучитьСтатистикуИспользованияППД()
	Если ПолнотекстовыйПоиск.ПолучитьРежимПолнотекстовогоПоиска() = РежимПолнотекстовогоПоиска.Запретить Тогда
		Возврат;
	КонецЕсли;
	ЧасовАктуальностиИндекса = Окр((ТекущаяДатаСеанса() - ПолнотекстовыйПоиск.ДатаАктуальности())/3600);                              
	УстановленнаяВерсияПолнотекстовогоПоиска = ?(ПолнотекстовыйПоиск.ПолучитьВерсиюПолнотекстовогоПоиска() = ВерсияПолнотекстовогоПоиска.Версия1,1,2);
	ЦентрМониторинга.ЗаписатьСтатистикуОбъектаКонфигурации("ПолнотекстовыйПоиск.Версия", УстановленнаяВерсияПолнотекстовогоПоиска); 
	ЦентрМониторинга.ЗаписатьСтатистикуОбъектаКонфигурации("ПолнотекстовыйПоиск.ЧасовАктуальностиИндекса", ЧасовАктуальностиИндекса);   
КонецПроцедуры

#КонецОбласти

#КонецОбласти