Каталог решений - Логирование в 1С

Логирование в 1С

Логирование в 1С

В наличии

Часто бывает необходимо отслеживать состояние часто повторяющихся регламентных заданий. Например, синхронизация данных с IP-телефонией, которая может производиться каждую минуту, синхронизация с сайтами, синхронизация данных с различными системами.
Использовать для этих целей логирование 1С чрезвычайно неэффективно и не удобно.
В таких случаях удобно использовать подход, применяемый в Unix-системах: писать логи в обычные текстовые файлы, а потом делать их обработку через эффективно работающие Unix-команды: grep, tail, cat, less и т.п.

Категория:

Описание

Итак, рассмотрим программную реализацию в 1С:

Название модуля — К2_Лог

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Данная библиотека определяет базовую работу с текстовыми логами
// данные функции рекомендуется использовать во всех конфигурациях.
// Так же, как следствие, того, что библиотека используется везде - присутствует функция определения операционной системы
///////////////////////////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////
// Общесистемные процедуры и функции
/////////////////////////////////////////////

// Определяем платформу операционной системы
Функция ОпределитьПлатформу ()Экспорт 
	
	СисИнф = Новый СистемнаяИнформация;
	Если  СисИнф.ТипПлатформы = ТипПлатформы.Windows_x86 Или  СисИнф.ТипПлатформы = ТипПлатформы.Windows_x86_64  Тогда
		Значение = "Wind"; // Лучше выдавала бы Win - так логичнее
	ИначеЕсли  СисИнф.ТипПлатформы = ТипПлатформы.Linux_x86 Или  СисИнф.ТипПлатформы = ТипПлатформы.Linux_x86_64  Тогда 
		Значение = "Lin";
	ИначеЕсли  СисИнф.ТипПлатформы = ТипПлатформы.MacOS_x86 Или  СисИнф.ТипПлатформы = ТипПлатформы.MacOS_x86_64  Тогда 
		Значение = "Mac";
	Иначе
		Значение = Неопределено;
	КонецЕсли;
	   Возврат Значение;
   КонецФункции
   
// Функция возвращает является ли данная система Windows или нет   
Функция IsWin() Экспорт
	Возврат ОпределитьПлатформу()="Wind";
КонецФункции

Функция РазностьВремени(Время1, Время2);
	Возврат (Время2 - Время1);
КонецФункции



////////////////////////////////////////////
// Функции логирования
////////////////////////////////////////////

// Сохраняет информацию в лог
Процедура Лог(ИмяФайла, ЛогСтрока, ДатаВремя, ЭтоНачало=Истина) Экспорт
	
	// Определение даты и времени
	Сейчас=ДатаВремя;
	Разница=0;
	Если ЭтоНачало Тогда
		ДатаВремя=ТекущаяДата();
		Сейчас=ДатаВремя;
	Иначе	
		ДатаВремя2=ТекущаяДата();
		Разница=РазностьВремени(ДатаВремя,ДатаВремя2);
		Сейчас=ДатаВремя2;
	КонецЕсли;
	
	
	// Если полный путь не указан, то пишем в c:\log
	Если Найти(ИмяФайла, "\") = 0 тогда
  		ИмяФайла = "C:\Log\"+ ИмяФайла;
	КонецЕсли;
	
    // Если не указано расширение - указываем
	Если Найти(ИмяФайла, ".") = 0 тогда
        ИмяФайла = ИмяФайла+".txt";
	КонецЕсли;
	
	
	// Форматирую разницу в секнды, минуты, часы
	Если Разница<60 Тогда
		Разница = Строка(Разница)+" сек";
	ИначеЕсли Разница<3600 Тогда	
		Разница = Строка(Окр(Разница/60,2))+" мин";
	Иначе 
		Разница = Строка(Окр(Разница/3600,2))+" часов";
	КонецЕсли;		
	
	
	ЛогСтрока=""+Сейчас+"|"+ПараметрыСеанса.ТекущийПользователь+"|"+ЛогСтрока+"|"+Разница;
	
	Попытка
	
		Если IsWin() Тогда
	
				fso=Новый COMОбъект("Scripting.FileSystemObject");	
		
				Если Не fso.FileExists(ИмяФайла) Тогда
					file=fso.CreateTextFile(ИмяФайла, -1, 0); //создать файл, перезаписывая существующий.
					file.WriteLine(ЛогСтрока); 
					file.Close(); 
				Иначе
					file=fso.OpenTextFile(ИмяФайла, 8, 0); //дополнить файл
					file.WriteLine(ЛогСтрока); 
					file.Close(); 
				КонецЕсли;
			
		Иначе
			ЗапуститьПриложение("echo "+ЛогСтрока+">>"+ИмяФайла);
		КонецЕсли;		
		
	Исключение
		Попытка
			ЗапуститьПриложение("echo _LogErr>>C:\Log\_err.txt");
		Исключение
		КонецПопытки;
	КонецПопытки;
			

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


// Формирует лог сообщений
Процедура ЛогСообщений(Модуль, ЛогСтрока, ДатаВремя, ЭтоНачало=Истина) Экспорт
	 Лог(Модуль, ЛогСтрока, ДатаВремя,ЭтоНачало);	 
	 //Лог("_Сообщения", Модуль+" - "+ЛогСтрока, ДатаВремя,ЭтоНачало);	 
КонецПроцедуры


// Формирует лог обработок
Процедура ЛогОбработок(НазваниеОбработки, ЛогСтрока, ДатаВремя, ЭтоНачало=Истина) Экспорт
	 Лог("Обр_"+НазваниеОбработки, ЛогСтрока, ДатаВремя, ЭтоНачало);
	 //Лог("_Обработки", НазваниеОбработки+" - "+ЛогСтрока, ДатаВремя, ЭтоНачало);
КонецПроцедуры	

// Формирует лог обмена
Процедура ЛогОбмен(НазваниеОбработки, ЛогСтрока, ДатаВремя, ЭтоНачало=Истина) Экспорт
	 Лог("Обмен_"+НазваниеОбработки, ЛогСтрока, ДатаВремя, ЭтоНачало);
	 //Лог("_Обмен", НазваниеОбработки+" - "+ЛогСтрока, ДатаВремя, ЭтоНачало);
КонецПроцедуры	


// Формирует лог регламентных заданий
Процедура ЛогРегламентныхЗаданий(НазваниеРегламентногоЗадания,ЛогСтрока, ДатаВремя, ЭтоНачало=Истина)
	  Лог("РЗ_"+НазваниеРегламентногоЗадания,ЛогСтрока, ДатаВремя, ЭтоНачало);
	  //Лог("_РегламентныеЗадания",НазваниеРегламентногоЗадания+" - "+ЛогСтрока, ДатаВремя, ЭтоНачало);
КонецПроцедуры	



// Выдает сообщение на экран и записывает в файл
Процедура Сообщ(Модуль, ТестСообщения) Экспорт
	  ДатаВремя=ТекущаяДата();
	  ЛогСообщений(Модуль, ТестСообщения, ДатаВремя);
	  //Сообщить(ТестСообщения);	
КонецПроцедуры	

// Начало произвольного сообщения со счетчиком
Процедура СообщНач(Модуль, ТестСообщения, ДатаВремя) Экспорт
	  ЛогСообщений(Модуль, ТестСообщения, ДатаВремя, Истина);
	  //Сообщить(ТестСообщения);	
КонецПроцедуры	

// Конец произвольного сообщения со счетчиком
Процедура СообщКон(Модуль, ТестСообщения, ДатаВремя) Экспорт
	  ЛогСообщений(Модуль, ТестСообщения, ДатаВремя, Ложь);
	  //Сообщить(ТестСообщения);	
КонецПроцедуры	



// Фиксация начала выполнения обработки
Процедура ЛогОбрНач(НазваниеОбработки, ЛогСтрока, ДатаВремя) Экспорт
	 ЛогОбработок(НазваниеОбработки, ЛогСтрока+" Нач", ДатаВремя, Истина);
КонецПроцедуры	

// Фиксация конца выполнения обработки
Процедура ЛогОбрКон(НазваниеОбработки, ЛогСтрока, ДатаВремя) Экспорт
	 ЛогОбработок(НазваниеОбработки, ЛогСтрока+" Кон", ДатаВремя, Ложь);
КонецПроцедуры	

// Фиксация сообщения в обработке (без вывода сообщения на экран)
Процедура ЛогОбрСообщ(НазваниеОбработки, ЛогСтрока, ДатаВремя) Экспорт
	 ЛогОбработок(НазваниеОбработки, ЛогСтрока, ДатаВремя, Ложь);
КонецПроцедуры	



// Фиксация начала регламентной задачи
Процедура ЛогРЗНач(НазваниеРегламентногоЗадания,ЛогСтрока, ДатаВремя) Экспорт 
	  ЛогРегламентныхЗаданий(НазваниеРегламентногоЗадания,ЛогСтрока+" Нач", ДатаВремя, Истина);
КонецПроцедуры	

// Фиксация окончания регламентной задачи
Процедура ЛогРЗКон(НазваниеРегламентногоЗадания,ЛогСтрока, ДатаВремя) Экспорт 
	  ЛогРегламентныхЗаданий(НазваниеРегламентногоЗадания,ЛогСтрока+" Кон", ДатаВремя, Ложь);
КонецПроцедуры	

// Фиксация сообщений в регламентных заданиях
Процедура ЛогРЗСообщ(НазваниеРегламентногоЗадания,ЛогСтрока, ДатаВремя) Экспорт 
	  ЛогРегламентныхЗаданий(НазваниеРегламентногоЗадания,ЛогСтрока, ДатаВремя, Ложь);
КонецПроцедуры	



// Фиксация начала регламентной задачи
Процедура ЛогОбменНач(НазваниеОбмена,ЛогСтрока, ДатаВремя) Экспорт 
	  ЛогОбмен(НазваниеОбмена,ЛогСтрока+" Нач", ДатаВремя, Истина);
КонецПроцедуры	

// Фиксация окончания регламентной задачи
Процедура ЛогОбменКон(НазваниеОбмена,ЛогСтрока, ДатаВремя) Экспорт 
	  ЛогОбмен(НазваниеОбмена,ЛогСтрока+" Кон", ДатаВремя, Ложь);
КонецПроцедуры	

// Фиксация сообщений в регламентных заданиях
Процедура ЛогОбменСообщ(НазваниеОбмена,ЛогСтрока, ДатаВремя) Экспорт 
	  ЛогОбмен(НазваниеОбмена,ЛогСтрока, ДатаВремя, Ложь);
КонецПроцедуры	



// Сохраняет сообщение в лог
Процедура СообщЛог(Модуль, ТестСообщения) Экспорт
   ДатаВремя=ТекущаяДата();
   Лог(Модуль, ТестСообщения, ДатаВремя);
КонецПроцедуры

// Процедура фиксации ошибок в логе ошибок
Процедура Ошибка(ТестСообщения) Экспорт
   ДатаВремя=ТекущаяДата();
   Лог("_err", ТестСообщения, ДатаВремя, Ложь);
КонецПроцедуры	

// Процедура фиксации ошибок с указанием текущей даты
Процедура ОшибкаД(ТестСообщения, ДатаВремя) Экспорт
   Лог("_err", ТестСообщения, ДатаВремя, Ложь);
КонецПроцедуры	



Процедура ОшибкаС(ТестСообщения) Экспорт
   ДатаВремя=ТекущаяДата();
   Лог("_err", ТестСообщения, ДатаВремя, Ложь);  
 
   Сообщить(ТестСообщения);
КонецПроцедуры	

// Фиксирует ошибку в логе и выдает сообщение о ошибке.
// Так же, вызывает исключение о ошибке.
Процедура ОшибкаСообщить(ТестСообщения, Отказ = Ложь) Экспорт
   ДатаВремя=ТекущаяДата();
   Лог("_err", ТестСообщения, ДатаВремя, Ложь);
   
   ОбщегоНазначения.СообщитьОбОшибке(ТестСообщения, Отказ);
   
   //Сообщить(ТестСообщения);
КонецПроцедуры	


Процедура ПодклЛог(ТестСообщения) Экспорт
   ДатаВремя=ТекущаяДата();
   Лог("_conn", ТестСообщения, ДатаВремя, Ложь);
КонецПроцедуры	


Процедура Отладка(Модуль,ТестСообщения) Экспорт
   ДатаВремя=ТекущаяДата();
   Лог(Модуль, ТестСообщения, ДатаВремя, Ложь);
КонецПроцедуры	


	
Процедура ОтладкаС(Модуль,ТестСообщения) Экспорт
   ДатаВремя=ТекущаяДата();
   Лог(Модуль, ТестСообщения, ДатаВремя, Ложь);
   Сообщить(ТестСообщения);
КонецПроцедуры	


// Формирует лог веб-процессов
Процедура ЛогWeb(НазваниеWeb,ЛогСтрока, ДатаВремя, ЭтоНачало=Истина)
	  Лог("Web_"+НазваниеWeb,ЛогСтрока, ДатаВремя, ЭтоНачало);
	  //Лог("_РегламентныеЗадания",НазваниеРегламентногоЗадания+" - "+ЛогСтрока, ДатаВремя, ЭтоНачало);
КонецПроцедуры	



// Фиксация начала веб-процесса
Процедура ЛогWebНач(НазваниеWeb,ЛогСтрока, ДатаВремя) Экспорт 
	  ЛогWeb(НазваниеWeb,ЛогСтрока+" Нач", ДатаВремя, Истина);
КонецПроцедуры	

// Фиксация окончания веб-процесса
Процедура ЛогWebКон(НазваниеWeb,ЛогСтрока, ДатаВремя) Экспорт 
	  ЛогWeb(НазваниеWeb,ЛогСтрока+" Кон", ДатаВремя, Ложь);
КонецПроцедуры



Фиксация времени выполнения регламентных задач:

Процедура ЗагрузкаКаталогаОмеги() Экспорт
		
	Перем ТаблицаРС;	
	
	// Rudjuk 08.09.2015
	Перем ДатаВремя;
	К2_Лог.ЛогРЗНач("ЗагрузкаКаталогаОмеги","ЗагрузкаКаталогаОмеги", ДатаВремя);

......

    // Rudjuk 08.09.2015
	К2_Лог.ЛогРЗКон("ЗагрузкаКаталогаОмеги","ЗагрузкаКаталогаОмеги", ДатаВремя);
	
	
КонецПроцедуры

В данном примере мы фиксируем время выполнения регламентного задания и записываем данное время в лог. Причем, записываем и начало регламентного задания и окончания. Таким образом, если регламентное задание не завершилось — мы видим, что 2-я строка не записалась.

Фиксация ошибок

В регламентном задании, сообщения не выдаются на экран. Но, их можно писать в лог. Таким образом, если возникают ошибки, имеет смысл их фиксировать в логе.


Попытка
	Перемещение.Записать(); //РежимЗаписиДокумента.Проведение
Исключение	
	К2_Лог.Ошибка("АвтоматическоеФормированиеПеремещенийПоСвозуНеликвидов.Перемещение.Записать()." + ОписаниеОшибки());					
КонецПопытки;	


Анализ логов с помощью команд Linux

Операционная система Windows поддерживает очень ограниченный набор команд по работе с тектовыми файлами. Однако, в Linux есть ряд команд, которые позволяют обработать много гигабайтные файлы за считанные секунды.

Мы можем сделать поддержку данных команд. Они, конечно, не гораздо менее эффективно работают, чем в Linux, но позволяют сделать обработку текстовых файлов легким занятием.

Для того, чтоб команды Linux поддерживались в Windows, необходимо сделать ряд вещей:

Необходимо распаковать в системный каталог, доступный в путях пакет UnxUpdates: http://unxutils.sourceforge.net/

После этого в командной строке, будут восприниматься команды Linux.

Вывод на экран последних поступающих строк в логе:

tail -f НазваниеЛога

Данная команда полезна для мониторинга поступающих строк в лог-файл.

Поиск нужной строки в логе:

cat НазваниеЛога | grep ЧтоИщем

 

has been added to your cart:
Оформление заказа