Обсуждение статьи "Искусство работы с логами (Часть 9): Применяем паттерн Builder и настраиваем конфигурации по умолчанию"

 

Опубликована статья Искусство работы с логами (Часть 9): Применяем паттерн Builder и настраиваем конфигурации по умолчанию:

В этой статье демонстрируется, как кардинально упростить использование библиотеки Logify с помощью паттерна «Строитель» и автоматических конфигураций по умолчанию. Рассматриваются структура специализированных строителей, приемы работы с ними при помощи интеллектуальной подсказки (автодополнения), а также способы обеспечения функционального логирования даже без ручной настройки. Кроме того, статья описывает доработки для сборки MetaTrader 5 5100.

С тех пор как я начал использовать Logify в различных личных и профессиональных проектах, я быстро осознал, что самая большая сложность заключалась не в надёжности или функциональности самой библиотеки, а в её настройке. Logify — это мощный инструмент для управления логированием в советниках (Expert Advisors), предлагающий множество обработчиков, уровней логирования, настраиваемые форматы, языковую поддержку и многое другое. Однако всё это требовало от пользователя ручной настройки каждого обработчика, форматтера и параметра, что может быть приемлемо для небольших проектов, но быстро превращается в повторяющуюся, утомительную и чреватую ошибками задачу по мере роста количества советников и проектов.

Представьте необходимость воспроизводить для каждого советника один и тот же сложный набор конфигураций: создание специфических обработчиков для комментирования на графике, вывода в консоль, записи в файлы и базы данных; установку минимальных уровней логирования для каждого обработчика; определение конкретных форматов для сообщений об ошибках, отладочной информации, уведомлений и так далее. Каждый из этих шагов, хоть и необходимый, порождает длинный, детализированный и неинтуитивный код, нарушая поток разработки. Эта изначальная сложность становится барьером, трением, которое может отпугнуть от внедрения Logify, даже несмотря на его безупречное управление логами во время выполнения.

Это понимание подтолкнуло меня к размышлению: как можно упростить эту настройку, облегчить жизнь пользователю, не жертвуя при этом гибкостью и возможностью кастомизации? Именно тогда и родилась идея создания конструктора (builder) для Logify — класса, который позволяет собрать всю конфигурацию плавным, цепочным способом, с помощью интуитивно понятных методов, создающих обработчики с разумными шаблонами и допускающих быстрые, точечные корректировки. Цель — превратить десятки строк конфигурации в несколько вызовов методов, как если бы мы писали чёткую сводку того, что нам нужно, вместо того чтобы заниматься всей ручной сборкой.

В этой статье я покажу, как я реализовал эти улучшения. Я представлю конструктор, объяснив его дизайн и использование. А затем продемонстрирую, как можно настроить Logify, на практических примерах.


Автор: joaopedrodev

 

Не рассматривали ли вы возможность добавления регистрации остановок во время выполнения? Конечно, это нормально, если разработчик будет обрабатывать это в советнике.

 
TerminalInfoString(TERMINAL_LANGUAGE);

Язык вывода журнала ошибок по умолчанию может быть возвращен на язык терминала пользователя в соответствии с этим кодом

 

Я задаюсь вопросом, хочу ли я выводить только сообщения об ошибках и отладке. А у меня все Info, Alert и т.д. встроены в советник. Может быть, установить значение bool для каждого типа в 'enum ENUM_LOG_LEVEL', чтобы показать, что мы хотим?

В производственном коде, если мы отключим некоторые из журналов, они не должны компилироваться в финальный файл ex5.

 
Spoxus Spoxus производственном коде, если мы отключим некоторые из журналов, они не должны компилироваться в финальный файл ex5.

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

//+------------------------------------------------------------------+
//| Импорт|
//+------------------------------------------------------------------+
#include <Logify/Logify.mqh>
CLogify Logify;
//+------------------------------------------------------------------+
//| Входы|
//+------------------------------------------------------------------+
input ENUM_LOG_LEVEL InpLogLevel = LOG_LEVEL_INFO; // Уровень журнала
//+------------------------------------------------------------------+
//| Функция инициализации эксперта|
//+------------------------------------------------------------------+
int OnInit()
  {
   Logify.EnsureDefaultHandler();
   Logify.GetHandler(0).SetLevel(InpLogLevel);
   
   Logify.Debug("RSI indicator value calculated: 72.56", "Indicators", "Period: 14");
   Logify.Info("Buy order sent successfully", "Order Management", "Symbol: EURUSD, Volume: 0.1");
   Logify.Error("Failed to send sell order", 10016,"Order Management");
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+

В результате будут отображаться только сообщения с уровнем серьезности, большим или равным заданному в обработчике.

 
hini #:

Язык вывода журнала ошибок по умолчанию может быть возвращен на язык терминала пользователя в соответствии с этим кодом

Часть 10 этой статьи находится в очереди на публикацию. В ней рассматривается способ подавления идентичных журналов, а также задается язык по умолчанию для терминала. Спасибо за предложение!

 
Это лучшая статья, которую я когда-либо видел - я в восторге!
 
Spoxus Spoxus производственном коде, если мы отключим некоторые из журналов, они не должны компилироваться в финальный файл ex5.
joaopedrodev #:

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

В результате будут отображаться только сообщения с уровнем серьезности, большим или равным заданному в обработчике.

Автор показывает, как изменить уровень во время выполнения программы без модификации кода.

Я думаю, что он просто хочет показать только один уровень журнала. Для этого ему нужно изменить код, как показано ниже:

//--- E.G.
void CLogifyHandlerComment::Emit(MqlLogifyModel &data)
  {
   //--- Проверьте, разрешен ли уровень журнала
   if(data.level != this.GetLevel()) // замените '<' на '!='
     {
      return;
     }

   //--- Журналы смен для сохранения истории
   for(int i = m_config.size-1; i > 0; i--)
     {
      m_cache[i] = m_cache[i-1];
     }
   m_cache[0] = data;

   //--- Постройте полный комментарий
   string comment = BuildHeader();
   comment += FormatLogLines();
   comment += BuildFooter();

   //--- Отображение на графике
   Comment(comment);
  }