[Oscript] От базовой библиотеки до полного расцвета с ОСенью. Разработка базовой версии

13.01.25

Разработка - OneScript

Вместе создадим библиотеку на Oscript с нуля, шаг за шагом: от базовой структуры проекта до перевода на ОСень. Разберем структуру проекта, работу с файлом конфигурации, логирование, уведомления, консольный интерфейс и многое другое. Освоим весь цикл разработки и сделаем первый шаг к созданию собственных инструментов на Oscript!

Привет! Меня зовут Очаковский Владимир. Сегодня хочу предложить тебе пройти практику на OneScript. Мы будем вместе разрабатывать собственную библиотеку — от самых первых шагов до полноценной реализации, включая версию на библиотеке ОСень.

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

Хочу сразу сказать, что я не являюсь экспертом в этой области. Скорее, я такой же практик, как и ты. Наша цель — вместе пройти все этапы, разложить процесс по полочкам и на практике разобраться, как все это работает.

В конце мы получим две версии библиотеки: базовая и улучшенная на основе ОСени. А еще ты найдешь практические задания, чтобы попробовать свои силы, отточить навыки и, возможно, сделать нашу библиотеку еще лучше.

Так что, если ты готов — давай начинать!

 

Перед началом

Прежде чем мы начнем, хочу отметить, что наш мастер-класс рассчитан на тех, кто уже знаком с базовыми принципами OneScript. Мы не будем подробно разбирать основы (установка, настройка, отладка), чтобы сосредоточиться на практических аспектах разработки.

Чтобы ты смог легче погрузиться в материал и получить максимум пользы, я рекомендую ознакомиться с некоторыми полезными ресурсами заранее:

  1. Мастер-класс «OneScript. От простого к сложному с Никитой Иванченко» — отличный быстрый старт для понимания структуры и возможностей языка. В этом мастер-классе шаг за шагом создается простой проект, который затем преобразуется в реализацию на основе библиотеки ОСень. Это отличный способ увидеть весь процесс перехода от базовой идеи к более сложной реализации. Нас с тобой ждет что-то подобное!
  2. Статья «Создаем свою библиотеку для OneScript»— фундаментальная статья для создания своей библиотеки.
  3. Документация OneScript: добавь её в закладки и изучи основные разделы — она станет твоим незаменимым помощником в процессе работы.

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

 

Техническое задание

Теперь тебе предстоит ознакомиться с техническим заданием, которое станет основой для разработки нашей библиотеки.

 
 Основные моменты из технического задания

Цель: Создание библиотеки для мониторинга сервера.

Основные требования:

  1. Расширяемость:
    • Модульная структура для легкого добавления новых методов.
    • Один JSON-файл для хранения конфигурации всех методов.
  2. Функционал логирования:
    • Запись событий (успехи, ошибки) с деталями в файл и вывод в консоль.
  3. Уведомления:
    • Telegram и Email как основные виды транспорта.
    • Легкость добавления новых видов транспорта.

Метод проверки дисков:

  • Настройки: список дисков, пороговое значение (в процентах).
  • Уведомления при превышении порога.
  • Вывод информации в консоль (доступное и общее место, проблемные диски).

Расширение библиотеки (возможности):

  • Мониторинг CPU и RAM.
  • Проверка состояния служб и времени отклика сервисов.
  • Проверка доступности внешних ресурсов.

Полное техническое задание доступно по ссылке.

Я подготовил общую диаграмму деятельности и простую диаграмму классов для методов проверки, чтобы облегчить проектирование начальной архитектуры библиотеки.

Диаграмма деятельности

 

 

Диаграмма классов

 

 

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

На основе технического задания и предложенных диаграмм попробуй спроектировать начальную структуру библиотеки.

Исходя из наших требований, хотелось бы, чтобы приложение начинало работу следующим образом:

Монитор = Новый Монитор();  
Монитор.ЗапуститьМониторинг();

Теперь мы готовы перейти к реализации!


Версия Базовая

Версия ОСень

Практика

Материалы

Заключение


Версия Базовая

Структура проекта

Перед началом создания базовой версии нашей библиотеки, давай зафиксируем основные шаги и договоренности о её устройстве из документации:

 

 

Шаги по созданию структуры:

  1. Создание корневого каталога проекта:

    • Назовем корневой каталог monitor.
  2. Подготовка структуры папок:

    • В корне создаем подпапки:
      • Классы — для размещения классов библиотеки.
      • Модули — для реализации проверок и вспомогательных функций.
  3. Создание стартового файла:

    • В корне проекта создаем файл main.os, который станет точкой входа в нашу библиотеку.
  4. Создание ключевых компонентов:

    • На основе диаграммы классов создаем:
      • Класс Монитор.os в папке Классы.
      • Модуль ПроверкаДисков.os в папке Модули.

Промежуточная структура библиотеки:

  • monitor
    • Классы
      • Монитор.os
    • Модули
      • ПроверкаДисков.os
    • main.os

Реализация начального каркаса логики:

В main.os добавляем стартовый код и инструкцию #Использовать “.” для загрузки наших классов и методов:

#Использовать "."

Монитор = Новый Монитор();
Монитор.ЗапуститьМониторинг();

Все проверки располагаются в папке Модули и следуют единому шаблону наименования Проверка<Назначение>.os. Также наши проверки имеют единый интерфейс. ПроверкаДисков.os:

Процедура ВыполнитьПроверку() Экспорт
	
	Сообщить("Начало проверки дисков");

	Сообщить("Завершение проверки дисков");

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

Создадим модуль Мониторинг.os для набора общих методов по управлению проверками:

#Область Проверки

Функция ДоступныеПроверки() Экспорт

    Проверки = Новый Соответствие();
    Проверки.Вставить("ПроверкаДисков", ПроверкаДисков);

    Возврат Проверки; 

КонецФункции

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

Добавляем реализацию метода ЗапуститьМониторинг, который запускает все проверки в Монитор.os:

Процедура ЗапуститьМониторинг() Экспорт

    Проверки = Мониторинг.ДоступныеПроверки();

    Для Каждого Проверка Из Проверки Цикл
        
        Менеджер = Проверка.Значение;
        Менеджер.ВыполнитьПроверку();

    КонецЦикла;

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

Тестирование:

  • Создаем отладочный файл (launch.json).
  • Запускаем приложение, проверяя корректность работы методов.

 

 

Теперь у нас есть базовая структура и начальный функционал библиотеки. Это станет отправной точкой для дальнейшего развития и улучшений!

Файл конфигурации

На основании технического задания и предложенных диаграмм попробуй самостоятельно представить, как должен выглядеть файл config.json. Сравни свою версию с моим описанием и подумай, насколько близки они по структуре и содержанию.

 
 config.json

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

Файл конфигурации будет включать следующие параметры:

  • Настройки логирования: путь к файлу логов.
  • Список проверок, которые нужно выполнять, с параметрами для каждой проверки (например, список дисков и пороговые значения для проверки дискового пространства).
  • Настройки уведомлений: данные для подключения к Telegram и/или электронной почте.
 
 Рекомендации по хранению паролей и токенов

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

  • Секреты CI/CD
    Используй встроенные механизмы управления секретами в системе CI/CD.

  • Переменные окружения (Environment Variables)
    Храни пароли и токены в переменных окружения на сервере или рабочем окружении.

  • Локальные конфигурационные файлы, исключенные из контроля версий
    Если ты вынужден использовать файлы, не забудь добавить его в .gitignore, чтобы он не попадал в репозиторий.


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

Попробуй следующий подход:

1. Проверка синтакс-помощника

Если ты еще не знаком с синтакс-помощником, самое время это исправить.

Например, для работы с JSON я нашел там метод ПрочитатьJSON. Этот метод считывает содержимое файла и преобразует его в структуры данных. Удобно и просто — то, что нужно! Вот ссылка на метод — обязательно посмотри.

2. Исследование готовых библиотек

На GitHub есть библиотека пакетов oscript-library. Часто там можно найти уже готовые инструменты.

Например, я нашел библиотеку configor. Она как раз создана для работы с конфигурационными файлами. Там уже есть методы для чтения JSON и управления настройками. Готовый интерфейс — бери и используй!

3. Анализ похожих решений в библиотеках

Еще один крутой способ — посмотреть, как похожие задачи решаются в других библиотеках. Например, я заглянул в популярный проект vanessa-runner.

В нем есть модуль ОбщиеМетоды.os, где нашел методы ПрочитатьНастройкиФайлJSON и ПрочитатьФайлJSON. Эти методы используют библиотеку json для работы с файлами. Хотя сейчас появился метод ПрочитатьJSON, этот пример все равно полезен: можно увидеть, как организована работа с настройками.

 
 Методы из ОбщиеМетоды.os

 

Что предлагаю сделать

На основе всего этого я бы предложил такой подход:

  1. Создать отдельный класс Конфигурация.os, который будет изолировать логику работы с настройками.
  2. Включить в класс публичные методы для чтения, проверки и получения значений настроек.
  3. Для работы с JSON используем метод ПрочитатьJSON — он встроенный, простой и эффективный.

Такой способ даст нам гибкость, позволит легко менять логику и добавлять новые возможности.


ПриСозданииОбъекта

Когда мы создаем объект класса, у него есть предопределенный метод ПриСозданииОбъекта, который автоматически срабатывает при инициализации.

Конфигурация = Новый Конфигурация();

Это удобно, но заставляет задуматься: где лучше разместить логику чтения конфигурационного файла?

Есть два подхода: реализовать эту логику в методе ПриСозданииОбъекта или вынести в отдельный метод Инициализировать. Давай разберемся.

 
 Логика в ПриСозданииОбъекта

Плюсы:

  • Простота использования. После создания объекта он сразу готов к работе, дополнительных вызовов не требуется.
  • Единый путь инициализации. Это уменьшает вероятность ошибок, если разработчик забудет вызвать метод Инициализировать.

Минусы:

  • "Тяжелый" конструктор. С ростом функционала объект может выполнять слишком много задач сразу (например, настройку лога, проверку файла, чтение настроек). Это усложнит отладку.
  • Сложности тестирования. Нельзя создать объект без выполнения всей логики, что может затруднить модульные тесты.
 
 Логика в отдельном методе Инициализировать

 Плюсы:

  • Простота конструктора. Весь тяжелый функционал вынесен, что делает код более читаемым и понятным.
  • Удобство тестирования. Объект можно протестировать в разных состояниях — до и после инициализации.
  • Гибкость. Метод можно вызывать с дополнительными параметрами, если потребуется адаптировать инициализацию.

Минусы:

  • Необходимость помнить. Разработчик обязан вызывать метод Инициализировать, иначе объект не будет готов к работе.
  • Немного больше кода. Каждый раз после создания объекта придется добавлять вызов метода.

Мы можем объединить преимущества обоих подходов.

  1. В методе ПриСозданииОбъекта добавляем проверку наличия файла конфигурации. Если файла нет, сразу сообщаем об ошибке, создаем шаблонный файл или используем значения по умолчанию.
  2. Логику чтения настроек из файла реализуем в методе Инициализировать. Это позволит вызывать его позже, если потребуется.

Преимущества смешанного подхода:

  1. Раннее обнаружение критических ошибок. Например, если конфигурационный файл отсутствует, мы узнаем об этом на этапе создания объекта.
  2. Гибкость. Основная логика инициализации может быть вызвана позже, с учетом дополнительных параметров или подготовки.
  3. Удобство тестирования. Можно создавать объект без полной инициализации, что особенно полезно при модульном тестировании.
Конфигурация = Новый Конфигурация();
Конфигурация.Инициализировать();

Такой подход делает наш код понятным, удобным в использовании и масштабируемым. Что скажешь?


Перед тем как приступить к реализации, давай обсудим, как лучше связать объекты Конфигурация и Монитор. Здесь есть два варианта:

  1. Создавать экземпляр класса Конфигурация внутри Монитор в методе ПриСозданииОбъекта.
  2. Передавать объект Конфигурация в Монитор в качестве параметра (через конструктор).

Я думаю, ты уже знаешь, какой вариант правильнее выбрать, но давай все равно их разберем.

Создание экземпляра класса вне конструктора и передача его в конструктор имеет несколько преимуществ по сравнению с созданием объекта непосредственно в конструкторе. Вот основные причины:

  • Повторное использование. Один экземпляр Конфигурации можно передать нескольким объектам Монитор или другим классам.
  • Гибкость. Легко подменить экземпляр Конфигурации на другую версию, если это потребуется.
  • Тестируемость. Можно передать тестовый экземпляр или мок-объект, изолируя зависимости и делая тесты проще и предсказуемее.
  • Прозрачность. Конструктор Монитор явно показывает, что он зависит от объекта Конфигурация.
  • Следование SOLID. Класс Монитор остается сфокусированным на своей задаче, а создание и настройка конфигурации передаются внешнему коду, реализуя принцип инверсии зависимостей (Dependency Injection) и упрощая управление зависимостями. Если ты не сталкивался с данными аббревиатурами ранее, то не забивай пока себе голову — мы еще столкнемся с Dependency Injection при переходе на ОСень.
Конфигурация = Новый Конфигурация();
Конфигурация.Инициализировать();

Монитор = Новый Монитор(Конфигурация);
Монитор.ЗапуститьМониторинг();

Мы готовы двигаться дальше!


Перед тем как перейти к реализации, давай визуализируем наши изменения на диаграмме классов. Это поможет нам четко понять, как взаимодействуют объекты Конфигурация и Монитор, и убедиться, что структура соответствует нашим целям.

 

 

Обрати внимание, что у класса Конфигурация появился метод Проверки(), который возвращает загруженные проверки из конфигурационного файла. 

Кроме того, у методов ВыполнитьПроверку(ПараметрыПроверки) теперь появился параметр ПараметрыПроверки. Этот параметр будет содержать настройки конкретной проверки, которые передаются из метода ПараметрыПроверки

Давай переходить к реализации!


Начнем с файла main.os:

#Использовать "."

Конфигурация = Новый Конфигурация();
Конфигурация.Инициализировать();

Монитор = Новый Монитор(Конфигурация);
Монитор.ЗапуститьМониторинг();

Добавим параметр ПараметрыПроверки в ПроверкаДисков.os:

Процедура ВыполнитьПроверку(ПараметрыПроверки) Экспорт
	
	Сообщить("Начало проверки дисков");

	Сообщить("Завершение проверки дисков");

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

Создадим класс Конфигурация.os:

Перем Настройки;

Процедура ПриСозданииОбъекта()

	ИмяФайла = ИмяФайлаПоУмолчанию();

	ФайлКонфигурации = Новый Файл(ИмяФайла);
	Если Не ФайлКонфигурации.Существует() Тогда
		ВызватьИсключение "Не найден файл конфигурации: " + ИмяФайла;
	КонецЕсли;

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

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

Процедура Инициализировать() Экспорт

	Настройки = ПрочитатьФайлJSON(ИмяФайлаПоУмолчанию());

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

Функция Проверки() Экспорт
	Возврат Настройки["Проверки"];
КонецФункции

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

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

Функция ИмяФайлаПоУмолчанию()
	Возврат "config.json";
КонецФункции

Функция ПрочитатьФайлJSON(ИмяФайла)
	
	Сообщить("Читаю настройки из " + ИмяФайла);

	ЧтениеJSON = Новый ЧтениеJSON;
	ЧтениеJSON.ОткрытьФайл(ИмяФайла);

	Результат = ПрочитатьJSON(ЧтениеJSON, Истина);

	ЧтениеJSON.Закрыть();

	Возврат Результат;

КонецФункции

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

Доработаем класс Монитор.os для работы с конфигурацией:

Перем _Конфигурация;

Процедура ПриСозданииОбъекта(Конфигурация)

	_Конфигурация = Конфигурация;

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

Процедура ЗапуститьМониторинг() Экспорт

	ЗагруженныеПроверки = _Конфигурация.Проверки();
	ДоступныеПроверки   = Мониторинг.ДоступныеПроверки();

	Для Каждого Проверка Из ЗагруженныеПроверки Цикл

		ИмяПроверки = Проверка.Ключ;
		ПараметрыПроверки = Проверка.Значение;

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

		Если Не ПараметрыПроверки["Использовать"] Тогда
			Сообщить("Отключена проверка: " + ИмяПроверки);
			Продолжить;
		КонецЕсли;

		Менеджер.ВыполнитьПроверку(ПараметрыПроверки);

	КонецЦикла;

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

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

Тестирование:

  • В отладке убедись, что параметры передаются корректно в метод выполнения проверки:
  • Проверь корректность работы приложения в целом:

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

Текущая структура библиотеки:

  • monitor
    • Классы
      • Конфигурация.os
      • Монитор.os
    • Модули
      • Мониторинг.os
      • ПроверкаДисков.os
    • main.os
    • example_config.json

Проверка дисков

Для реализации нашей первой проверки дисков мы будем работать с методом ИнформацияОДиске из синтакс-помощника. Этот метод предоставляет информацию о доступном пространстве и общем размере диска, что идеально подходит для нашей задачи.

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

Процедура ВыполнитьПроверку(ПараметрыПроверки) Экспорт
	
	Сообщить("Начало проверки дисков");

	Диски = ПараметрыПроверки["Диски"];
	Порог = ПараметрыПроверки["Порог"];

	Для Каждого Диск Из Диски Цикл
		ПроверитьДиск(Диск, Порог);
	КонецЦикла;

	Сообщить("Завершение проверки дисков");

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

Основная идея проверки:

  1. Получить данные о дисках.
  2. Рассчитать процент свободного места.
  3. Вывести сообщение с информацией согласно техническому заданию.

Когда закончишь свою реализацию, обязательно сравни её с моей версией.

 
 ПроверкаДисков.os

Тестирование:

  • В config.json указываем настройки для проверки ПроверкаДисков:
  • Запускаем приложение, проверяя корректность работы методов:

Логирование

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

Так как это первая внешняя библиотека в нашем проекте, начнём с её установки. Выполни команду для установки:

opm i logos

Для структурированного логирования мы будем использовать основной журнал с именем нашего приложения. Давай начнем с создания модуля ПараметрыПриложения.os. В нём добавим функцию, которая возвращает имя приложения:

Функция ИмяПриложения() Экспорт
    Возврат "monitor";
КонецФункции

Теперь это имя станет основой для нашего журнала логов.

Поскольку модуль Мониторинг является основным для нашего приложения, создание и настройку логов разместим именно там, чтобы она была в одном месте. Особенностью модулей в OneScript является то, что у них есть переменные и они сохраняют значение после последнего присвоения. Это удобно для инициализации единого экземпляра объекта лога. Подключим в модуле библиотеку и создадим переменную для лога:

#Использовать logos

Перем Лог;

Теперь создадим функцию, которая будет возвращать сам лог:

Функция Лог() Экспорт

	Если Лог = Неопределено Тогда
		
		Лог = Логирование.ПолучитьЛог(ПараметрыПриложения.ИмяПриложения());

	КонецЕсли;
	
	Возврат Лог;

КонецФункции

Теперь давай найдем все строки, где используется Сообщить

 

 

И заменим их на методы библиотеки logos. Вот основные методы:

  • Лог.Информация("Информация");
  • Лог.Ошибка("Ошибка");
  • Лог.Отладка("Отладка");
  • Лог.КритичнаяОшибка("Критичная ошибка");
Лог = Мониторинг.Лог();
Лог.Информация("Информация");

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

Один из вариантов — использование конфигурационного файла logos.cfg. В этом файле можно задать уровень логирования для нашего приложения. Например:

logger.monitor=DEBUG

Задание

  1. Подключи библиотеку logos в тех модулях, где используется Сообщить.
  2. Замени вызовы Сообщить на соответствующие методы библиотеки.
  3. Проверь, что лог корректно работает, и сообщения выводятся в указанный журнал.

После выполнения задания сравни свой результат с моей версией.

 

 

Давай научимся настраивать форматирование сообщений в логах. Это позволит сделать вывод более удобным и информативным. Выполним нужные шаги по установке раскладки по документации в модуле Мониторинг.os:

Функция Лог() Экспорт

	Если Лог = Неопределено Тогда
		
		Лог = Логирование.ПолучитьЛог(ПараметрыПриложения.ИмяПриложения());
		Лог.УстановитьРаскладку(ЭтотОбъект);

	КонецЕсли;
	
	Возврат Лог;

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

Функция ПолучитьФорматированноеСообщение(Знач СобытиеЛога) Экспорт
   
	Уровень = УровниЛога.НаименованиеУровня(СобытиеЛога.ПолучитьУровень());

	ФорматированноеСообщение = СтрШаблон("%1: %2 - %3",
		ТекущаяДата(),
		Уровень,
		СобытиеЛога.ПолучитьСообщение());

	Возврат ФорматированноеСообщение;
 
 КонецФункции

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

Для записи логов в файл нужно донастроить наш лог. Так как имя файла лога указывается в конфигурационном файле, настройку вывода в файл мы выполним после чтения настроек. При этом важно учесть особенность библиотеки logos: если мы добавляем второй способ вывода (например, в файл), то первый способ (например, вывод в консоль) нужно явно указать, иначе он пропадет.

Изменения в Мониторинг.os:

#Область Логирование

Функция Лог() Экспорт

	Если Лог = Неопределено Тогда
		
		Лог = Логирование.ПолучитьЛог(ПараметрыПриложения.ИмяПриложения());
		Лог.УстановитьРаскладку(ЭтотОбъект);

		ВыводЛогаВКонсоль = Новый ВыводЛогаВКонсоль;
		Лог.ДобавитьСпособВывода(ВыводЛогаВКонсоль);

	КонецЕсли;
	
	Возврат Лог;

КонецФункции

Процедура ДобавитьВыводЛогаВФайл(ФайлЛога) Экспорт

	Лог = Лог();

	ВыводЛогаВФайл = Новый ВыводЛогаВФайл;
	ВыводЛогаВФайл.ОткрытьФайл(ФайлЛога, , Ложь);

	Лог.ДобавитьСпособВывода(ВыводЛогаВФайл);

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

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

Изменения в Конфигурация.os:

Процедура Инициализировать() Экспорт

	Настройки = ПрочитатьФайлJSON(ИмяФайлаПоУмолчанию());

	Мониторинг.ДобавитьВыводЛогаВФайл(ФайлЛога());

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

Функция ФайлЛога() Экспорт
	Возврат Настройки["ФайлЛога"];
КонецФункции

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

 

 

Кстати, вот пример настройки вывода лога через файл logos.cfg:

logger.monitor=DEBUG, result, console

appender.result=ВыводЛогаВФайл
appender.result.file=logs.txt

appender.console=ВыводЛогаВКонсоль

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

Вот что мы сделаем:

  1. Имя файла конфигурации перенесем в модуль ПараметрыПриложения:
    • В ПараметрыПриложения.os создадим функцию ИмяФайлаКонфигурации().
  2. Создадим модуль РаботаСФайлами.os для операций с файлами:
    • Вынесем всю логику, связанную с файлами, включая проверку их существования и открытие, в отдельный модуль.

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

Текущая структура библиотеки:

  • monitor
    • Классы
      • Конфигурация.os
      • Монитор.os
    • Модули
      • Мониторинг.os
      • ПараметрыПриложения.os
      • ПроверкаДисков.os
      • РаботаСФайлами.os
    • main.os
    • example_config.json
 
 Измененные файлы
 
 main.os
 
 Конфигурация.os
 
 Монитор.os
 
 Мониторинг.os
 
 ПараметрыПриложения.os
 
 ПроверкаДисков.os
 
 РаботаСФайлами.os

Уведомления

Мы дошли до реализации последнего крупного функционального блока — уведомления. Этот компонент позволит нашему приложению сообщать о результатах проверок через различные каналы связи.

Проектирование функционала

Сначала нужно продумать архитектуру. Обратимся к файлу config.json. В нем уже есть ключевая информация:

  • Имя транспорта — название канала связи (например, почта или телеграм).
  • Настройки транспорта — данные для подключения и настройки канала.

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

На основании технического задания нам нужно:

  1. Реализовать отправку уведомлений через почту и телеграм.
  2. Обеспечить возможность легкого добавления новых транспортов.

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

  • Все транспорты будут представлены модулями.
  • Создание отдельного класса для каждого транспорта избыточно, так как мы лишь вызываем конкретную реализацию функции отправки, а дополнительные состояния и сложная логика в данном случае отсутствуют.

Для наглядности представим архитектуру функционала в виде диаграммы классов:

 

 

  1. Уведомления — основной интерфейс, управляющий транспортами и уведомлениями.
    • Метод ОтправитьУведомление определяет общую логику отправки.
    • МенеджерТранспорта отвечает за подключение конкретного модуля транспорта.
  2. УведомленияПочта и УведомленияТелеграм — модули, реализующие свои методы отправки.
  3. Уведомления<НовыйТранспорт> — пример для добавления нового транспорта. Достаточно создать новый модуль и реализовать в нем метод ОтправитьУведомление.

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

Теперь, когда мы спроектировали начальную архитектуру, давай приступим к реализации. 🚀


Начальная реализация

По диаграмме классов создадим каркас методов:

Уведомления.os

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

Процедура ОтправитьУведомление(ИмяТранспорта, НастройкиТранспорта, ПараметрыУведомления) Экспорт

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

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

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

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

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

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

УведомленияПочта.os

Процедура ОтправитьУведомление(НастройкиТранспорта, ПараметрыУведомления) Экспорт
	
	Сообщить("Отправка уведомления через почту");
	
КонецПроцедуры

УведомленияТелеграм.os

Процедура ОтправитьУведомление(НастройкиТранспорта, ПараметрыУведомления) Экспорт
	
	Сообщить("Отправка уведомления через телеграм");
	
КонецПроцедуры

Итак, нам нужно определить, где именно в нашем коде будет происходить вызов отправки уведомлений. На первый взгляд, логично разместить эту логику в методе ЗапуститьМониторинг, который уже отвечает за выполнение всех проверок и координацию работы приложения.

Монитор.ЗапуститьМониторинг();

Однако стоит задуматься, соответствует ли это подход принципу единой ответственности (SRP, Single Responsibility Principle). Если мы добавим логику отправки уведомлений в ЗапуститьМониторинг, этот метод станет перегруженным и сложным для тестирования. Кроме того, это создаст дополнительную связанность кода, что ухудшит его поддержку и расширение.

Чтобы избежать этих проблем, правильнее будет выделить отправку уведомлений в отдельный метод класса Монитор. Это позволит:

  • Изолировать логику уведомлений — будет проще вносить изменения.
  • Упростить тестирование — мы сможем тестировать метод отправки уведомлений отдельно от остальных частей приложения.
  • Соблюсти принцип единой ответственности (SRP) — метод ЗапуститьМониторинг останется сфокусированным на выполнении проверок.
  • Упростить использование библиотеки — метод ОтправитьУведомления может быть вызван отдельно в других сценариях.
Монитор.ЗапуститьМониторинг();
Монитор.ОтправитьУведомления();

ОтправитьУведомления

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

Доработаем процедуру ОтправитьУведомление в модуле Уведомление.os

Процедура ОтправитьУведомление(ИмяТранспорта, НастройкиТранспорта, ПараметрыУведомления) Экспорт

	Если Не НастройкиТранспорта["Использовать"] Тогда
		Сообщить(СтрШаблон("Отправка уведомлений через ""%1"" отключена", ИмяТранспорта));
		Возврат;
	КонецЕсли;

	Менеджер = МенеджерТранспорта(ИмяТранспорта);
	Менеджер.ОтправитьУведомление(НастройкиТранспорта, ПараметрыУведомления);

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

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

 


Отправка уведомлений через почту

Для реализации отправки уведомлений через почту мы будем использовать библиотеку InternetMail. У этой библиотеки есть подробное описание, поэтому попробуй самостоятельно разработать логику в модуле УведомленияПочта.os.

Для упрощения я подготовил тебе каркас логики, который поможет быстрее приступить к реализации. После завершения работы протестируй отправку уведомлений и сравни свою реализацию с моей версией.

#Использовать InternetMail

Процедура ОтправитьУведомление(НастройкиТранспорта, ПараметрыУведомления) Экспорт
	
	Сообщить("Отправка уведомления через почту");

	Профиль = ПрофильПочты(НастройкиТранспорта);
	Сообщение = ИсходящееСообщение(НастройкиТранспорта, ПараметрыУведомления);
	
	Почта = Новый ИнтернетПочта;
	Почта.Подключиться(Профиль);
	Почта.Послать(Сообщение, , ПротоколИнтернетПочты.SMTP);
	
КонецПроцедуры

Функция ПрофильПочты(НастройкиТранспорта)

	Профиль = Новый ИнтернетПочтовыйПрофиль;

	Возврат Профиль;

КонецФункции

Функция ИсходящееСообщение(НастройкиТранспорта, ПараметрыУведомления)

	Сообщение = Новый ИнтернетПочтовоеСообщение;

	Возврат Сообщение;

КонецФункции

Поскольку мы используем файл logs.txt, который создаётся библиотекой logos и служит результатом нашего мониторинга, важно освободить этот файл после завершения мониторинга. Это необходимо, так как далее мы прикрепляем его как вложение.

Чтобы это реализовать, в конце метода ЗапуститьМониторинг необходимо вызвать:

Лог.Закрыть();

Запомни этот момент, так как в конце раздела мы к нему ещё вернёмся.

 
 УведомленияПочта.os

 


Отправка уведомлений через телеграм

Для реализации отправки уведомлений через Telegram у нас есть несколько вариантов библиотек:

Но стоит задуматься, есть ли смысл использовать такие библиотеки с большим количеством транспортов и методов, если нам нужен только один метод — sendMessage. Фактически, из этих библиотек мы будем использовать лишь функциональность, связанную с Телеграм.

Поэтому я предлагаю остановиться на библиотеке 1connector. Она упрощает работу с HTTP-запросами и идеально подходит для наших целей.

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

В рамках данного раздела мы реализуем только отправку текстового уведомления без вложений. Реализацию отправки вложений ты найдёшь в практическом разделе.

Попробуй самостоятельно написать логику для отправки уведомлений через Telegram в УведомленияТелеграм.os, протестируй её и сравни с моей реализацией.

Я рекомендую тебе отработать сценарий, при котором бот добавляется в группу и отправляет уведомления непосредственно в неё. Это полезно для уведомления ответственных лиц или команды, ответственной за мониторинг.

 
 УведомленияТелеграм.os


Логирование уведомлений

Для логирования уведомлений нам нужно изолировать их в отдельный журнал логов с именем "monitor.notification". Это позволит избежать конфликтов логов, которые возникают при использовании разных способов вывода и назначения логов.

Для реализации этой задачи:

  1. В модуле Уведомления.os создадим метод Лог(), аналогичный методу из Мониторинг.os, но с именем журнала "monitor.notification".
  2. Убедись, что журнал создается корректно и соответствует стандартам, установленным в библиотеке logos.
Функция Лог() Экспорт
	
	ИмяЛога = ПараметрыПриложения.ИмяПриложения() + ".notification";

	Если Лог = Неопределено Тогда
		Лог = Логирование.ПолучитьЛог(ИмяЛога);
	КонецЕсли;
	
	Возврат Лог;
	
КонецФункции

В рамках мастер-класса мы использовали библиотеку logos для реализации логирования мониторинга, чтобы упростить и ускорить разработку. Это позволило быстро достичь результата, но давай задумаемся о некоторых аспектах архитектуры. Приложение работает, и все требования технического задания выполнены. Однако, при масштабировании могут возникнуть определённые трудности.

Помнишь, я акцентировал внимание на строке Лог.Закрыть()? Возможно, вместо использования общего файла лога, стоило бы рассмотреть отдельное решение для формирования файла результата. Это избавило бы нас от потенциальных ошибок, связанных с освобождением ресурсов и возможных конфликтов логирования. Кроме того, если в будущем потребуется одновременно несколько экземпляров объекта Монитор, текущая реализация может столкнуться с проблемой совместного доступа.

Важно заранее думать о будущем развития приложения и учитывать, что может потребоваться гибкость в архитектуре. Попробуй проанализировать текущую реализацию — видишь ли ты места, которые могут стать узкими местами при масштабировании?

 
 Промежуточные изменения
 
 Уведомления.os
 
 УведомленияПочта.os
 
 УведомленияТелеграм.os

Задание

  1. Реализовать отправку форматированного текста
    • Убедись, что форматированный текст поддерживается одинаково для всех текущих транспортов. Это обеспечит единообразие уведомлений вне зависимости от выбранного способа отправки.
  2. Разделение текста и логов
    • Основное уведомление должно содержать только сообщения об ошибках, а полный журнал логов прикрепляй во вложение.
    • Для этого прочитай файл логов и выдели из него ошибки. Это самый простой и эффективный способ на данном этапе.
  3. Добавление имени сервера в тему
    • Включи имя сервера в тему уведомления, чтобы быстро идентифицировать источник проблемы. Это особенно полезно в многосерверной среде.

Пример уведомления почта:

 

 

Пример уведомления телеграм:

 

 

Я приложу итоговую диаграмму классов, чтобы тебе было проще спланировать и реализовать логику уведомлений. Надеюсь, она поможет тебе увидеть общую картину системы и организовать код более структурированно.

 

 

Текущая структура библиотеки:

  • monitor
    • Классы
      • Конфигурация.os
      • Монитор.os
    • Модули
      • Мониторинг.os
      • ПараметрыПриложения.os
      • ПроверкаДисков.os
      • РаботаСФайлами.os
      • Уведомления.os
      • УведомленияПочта.os
      • УведомленияТелеграм.os
    • main.os
    • example_config.json
 
 Измененные файлы
 
 main.os
 
 Конфигурация.os
 
 Монитор.os
 
 Мониторинг.os
 
 Уведомления.os
 
 УведомленияПочта.os
 
 УведомленияТелеграм.os

Сборка

Мы завершили разработку приложения по техническому заданию. Теперь нам необходимо подготовить его к удобному использованию. Рассмотрим основные сценарии использования приложения:

  • Ручной запуск: пользователь запускает приложение вручную.
  • Запуск через планировщик задач: автоматизация запуска по расписанию.
  • Запуск через CI/CD: интеграция приложения в автоматизированные пайплайны.

Вспомним какие есть варианты запуска и сборки:

  • Запуск напрямую из папки библиотеки
    • oscript main.os
  • Сборка исполняемого файла
    • oscript -make main.os monitor.exe  
    • После этого файл monitor.exe можно запускать напрямую.
  • Сборка и установка пакета
    • Создать файл packagedef, который будет описывать параметры библиотеки.
    • Выполнить сборку пакета в текущей папке командой: opm build . 
    • Установить пакет командой: opm install -f monitor-1.0.0.ospx
    • После установки мы сможем запускать приложение через имя: monitor 

Задание

  1. Создай файл packagedef, описывающий нашу библиотеку.
  2. Создай файл README.md с инструкциями по настройке и запуску приложения.
  3. Собери пакет и протестируй запуск приложения по имени.

Подсказки ищи в статье «Создаем свою библиотеку для OneScript».

Эти шаги помогут пользователю быстро разобраться с приложением и легко интегрировать его в свои процессы.

 
 packagedef

Консольный интерфейс

Представь, что тебе нужно добавить в наше приложение возможность запускать отдельные действия, минуя необходимость каждый раз править конфигурационный файл. Например, ты хочешь проверить диски, но не хочешь для этого лезть в настройки, отключать другие проверки, а потом снова всё возвращать обратно. Звучит как лишняя возня, правда?

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

Для каждой команды у нас будет свой класс. Допустим, нам нужна команда для проверки дисков. Создаём файл КомандаПроверкаДисков.os и добавляем туда базовую реализацию:

Процедура ВыполнитьКоманду(Знач Команда) Экспорт
	
	Сообщить("Проверка дисков через команду");

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

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

Далее нам нужно немного изменить main.os. Мы подключим библиотеку cli, зарегистрируем нашу команду и запустим обработку аргументов командной строки:

#Использовать cli
#Использовать logos
#Использовать "."

Перем Лог;

Процедура ВыполнитьПриложение()

	Лог = Мониторинг.Лог();

	Приложение = Новый КонсольноеПриложение(ПараметрыПриложения.ИмяПриложения(), "Мониторинг ресурсов сервера");
	Приложение.Версия("v version", ПараметрыПриложения.Версия());

	Приложение.ДобавитьКоманду("disk", "Проверка дисков", Новый КомандаПроверкаДисков);
	
	Приложение.УстановитьОсновноеДействие(ЭтотОбъект);
	Приложение.Запустить(АргументыКоманднойСтроки);
	
КонецПроцедуры

Процедура ВыполнитьКоманду(Знач КомандаПриложения) Экспорт
	
	КомандаПриложения.ВывестиСправку();
	
КонецПроцедуры

Попытка
	
	ВыполнитьПриложение();
	
Исключение
	
	Лог.КритичнаяОшибка(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
	
КонецПопытки;

Если мы сейчас запустим приложение, то вместо выполнения команды оно выведет справочную информацию. Это ожидаемо, так как пока что мы не указали аргументы для запуска нашей команды.

 

 

Чтобы отладить команду, нужно внести изменения в файл launch.json. В разделе args добавим название нашей команды — disk. Таким образом, мы передаём аргумент командной строке, чтобы приложение понимало, что именно нужно выполнить. Пример настройки:

 

 

Теперь запускаем наше приложение. Если всё настроено правильно, то команда проверки дисков выполнится, и на экран выведется сообщение: "Проверка дисков через команду".

 

 

Это подтверждает, что командный интерфейс работает корректно!

Давай теперь добавим немного реальной логики в наше приложение. По умолчанию мы сохраним поведение таким, каким оно было до появления командного интерфейса: при запуске без аргументов будут выполняться все проверки, как и раньше. Но если пользователь явно выбирает команду disk, мы выполним проверку дисков, игнорируя флаг "Использовать" из конфигурационного файла.

Это позволит комбинировать удобство командного интерфейса с существующим подходом. Теперь пользователи смогут запускать отдельные проверки быстро и гибко, не меняя настройки.

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

Для реализации новой логики нам нужно настроить состояние экземпляра класса Монитор, чтобы он мог работать с выбранной проверкой. Для этого добавим в класс переменную _ВыбраннаяПроверка, которая будет хранить информацию о том, какая проверка должна быть выполнена. Управлять её значением будем с помощью двух методов:

  • Установить проверку — задаёт значение для переменной _ВыбраннаяПроверка. Вызывается, когда нужно задать конкретную проверку. Например, для команды disk мы передаём значение "ПроверкаДисков".
  • Сбросить проверку — очищает значение переменной, возвращая её в исходное состояние. Используется для возврата к стандартному состоянию, когда проверка выполняется без конкретного выбора.
Процедура УстановитьПроверку(ВыбраннаяПроверка) Экспорт
    _ВыбраннаяПроверка = ВыбраннаяПроверка;
КонецПроцедуры

Процедура СброситьПроверку() Экспорт
    _ВыбраннаяПроверка = Неопределено;
КонецПроцедуры

Теперь мы переходим к следующему шагу: настроить выполнение нашего общего сценария таким образом, чтобы при наличии выбранной проверки экземпляр Монитор дополнительно настраивался.

Для этого нужно:

  1. Вынести основной сценарий в отдельный модуль Мониторинг, чтобы сделать его более универсальным.
  2. Создать в этом модуле экспортный метод ВыполнитьПроверки, который будет обрабатывать как стандартное выполнение всех проверок, так и запуск конкретной проверки, если она указана.
Процедура ВыполнитьПроверки(ВыбраннаяПроверка = "") Экспорт

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

    Монитор.ЗапуститьМониторинг();
    Монитор.ОтправитьУведомления();

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

Вызываем наш новый метод в main.os и КомандаПроверкаДисков.os

Процедура ВыполнитьКоманду(Знач Команда) Экспорт
	
	Лог = Мониторинг.Лог();
	Лог.Отладка("Проверка дисков через команду disk" );

	Мониторинг.ВыполнитьПроверки("ПроверкаДисков");

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

И последний шаг — настроить выполнение только выбранной проверки, игнорируя флаг "Использовать" из конфигурационного файла. Для этого нужно внести изменения в метод ЗапуститьМониторинг класса Монитор, добавив логику проверки переменной _ВыбраннаяПроверка.

Процедура ЗапуститьМониторинг() Экспорт
    
    Если ЗначениеЗаполнено(_ВыбраннаяПроверка) Тогда
        ВыполнитьВыбраннуюПроверку(_ВыбраннаяПроверка);
    Иначе
        ВыполнитьВсеПроверки();
    КонецЕсли;
    
    Лог.Закрыть();
    
КонецПроцедуры

Задание

  1. Реализовать логику выполнения проверок в процедуре ЗапуститьМониторинг и протестировать работу приложения.
  2. Добавить возможность указать диск для проверки и порог через аргументы/опции.
  3. Выполнить повторную сборку. Не забудь добавить новую зависимость в packagedef.
 
 Измененные файлы
 
 main.os
 
 КомандаПроверкаДисков.os
 
 Монитор.os
 
 Мониторинг.os
 
 ПараметрыПриложения.os

Версия ОСень

Мы с тобой реализовали базовую версию библиотеки, и ты проделал отличную работу, дойдя до конца! 🎉

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

Но на этом наше путешествие не заканчивается! В следующей части мы разберем, как можно переосмыслить нашу библиотеку, используя возможности библиотеки ОСень.

Мы начнем все сначала и шаг за шагом пройдем основные этапы разработки:

  • Структура проекта: как ОСень меняет подход к организации кода.
  • Файл конфигурации: упрощаем управление настройками.
  • Логирование: рассмотрим работу с логами через ОСень.
  • Консольный интерфейс: рассмотрим реализацию cli через ОСень.

После каждого шага мы будем анализировать, как изменился наш код: стал ли он проще, понятнее и удобнее благодаря ОСени.

Готовься к следующему этапу! 🍂

 

 

Практика

Для закрепления материала я собрал для тебя все практические задания в одном месте. Эти задачи помогут углубить понимание темы и улучшить библиотеку:

  1. Рефакторинг
    Мы разрабатывали библиотеку в рамках мастер-класса, поэтому наверняка остались моменты, которые можно улучшить. Свежим взглядом постарайся найти как минимум три области, где код можно сделать чище, удобнее или эффективнее.
  2. Новые методы проверки
    Добавь в библиотеку хотя бы один новый метод. Например, это может быть проверка доступности хранилища конфигурации или диагностика состояния сервера 1С. Не бойся проявлять фантазию — любой интересный сценарий можно добавить в функционал.
  3. Кроссплатформенность
    Реализуй новые проверки так, чтобы они работали на разных операционных системах. В рамках мастер-класса мы могли опускать такие детали, но в реальной жизни это важный момент, который стоит учесть.
  4. Прикрепление лога к уведомлениям
    Добавь возможность прикреплять файл лога к отправляемым уведомлениям Телеграм. Если для этого потребуется заменить используемую библиотеку уведомлений на другую — пробуй! Это хороший шанс поэкспериментировать.
  5. Открытие отчета Allure
    Реализуй новый метод, который открывает отчет Allure прямо из библиотеки. Это отличная практика для работы с новыми инструментами. Не забудь добавить поддержку этого метода в консольном интерфейсе.
    Монитор.ОткрытьОтчет();
  6. Покрытие тестами
    Напиши тесты для функционала библиотеки. Можешь использовать инструмент 1testrunner. Это укрепит надежность библиотеки и даст тебе дополнительный опыт в тестировании.

Ты можешь выбрать, на чём сфокусироваться, но если тебе интересны все задания, не ограничивай себя!

Не забудь поделиться своим форком репозитория в комментариях — возможно, твое решение попадет на разбор в следующей статье и твоя доработка станет примером для других разработчиков!

Пусть эта практика станет твоим шагом к более глубокому пониманию OneScript и повышению уровня твоих навыков. Удачи! 🚀

Материалы

Техническое задание на разработку библиотеки для мониторинга

Документация:

Репозиторий:

  • Версия Базовая
    • Коммиты в репозитории организованы в соответствии с нашими шагами. Это сделано для твоего удобства, чтобы ты мог легко отслеживать изменения и понимать, как развивался проект на каждом этапе.

Быстрый старт:

Библиотеки:

Набор практик и стандартов для качественной разработки в 1С

Заключение

Я надеюсь, что первая часть нашего мастер-класса оказалась для тебя полезной и увлекательной!

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

Во второй части нас ждет новое приключение — переход на библиотеку ОСень.

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

Я буду очень благодарен, если ты поддержишь этот материал и репозиторий на GitHub! Я вложили в него много сил и стараний. Поставь звезду проектам — это будет отличной поддержкой 🌟

До встречи во второй части! 

См. также

OneScript Программист Платформа 1С v8.3 Бесплатно (free)

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

10.01.2025    1314    KamranV21    12    

32

OneScript Программист Бесплатно (free)

В мире OneScript давно существуют библиотеки для облегчения работы с каким-либо классом программного обеспечения, например v8runner - помощник выполнения команд конфигуратора или gitrunner - программная обертка для запуска команд git. Есть библиотека и для работы с автономным сервером 1с. Однако библиотеке ibcmdrunner уже три года, а про нее нет ни одной публикации на инфостарте. Исправляю эту несправедливость.

09.01.2025    1028    ardn    0    

21

OneScript Программист Бесплатно (free)

Отгремел Infostart Tech Event 2024, топовое событие в мире 1С-разработки, традиционно проходящее в Санкт-Петербурге. Ваш покорный слуга в этот раз отмечал там 10-летний юбилей проекта OneScript. Отмечание проводилось в форме игры-соревнования по забегу роботов в лабиринте. Участники пытались написать алгоритм движения робота на языке 1С и сделать это быстрее других. О том, как это было – под катом.

28.10.2024    1652    Evil Beaver    11    

25

OneScript Программист Бесплатно (free)

OneScript – это скриптовый движок для автоматизации всего и вся. О том, как OneScript помогает в разработке скриптов на языке 1С, пойдет речь в статье.

10.10.2024    3570    ardn    2    

9

Инструментарий разработчика OneScript Программист Руководитель проекта Бесплатно (free)

Все мы хотя бы раз работали с конструктором запросов. Результатом его работы является синтаксически верный запрос, оформленный по некоторому стандарту. Нравится - не нравится, а привыкаешь быстро, и на запрос, написанный руками, уже не хочется смотреть... А почему бы не попробовать сделать то же самое с исходным кодом 1С? Ну я и попробовал...

23.09.2024    767    0    stopa85    5    

5

Групповая разработка (Git, хранилище) OneScript Программист Платформа 1С v8.3 Бесплатно (free)

Скрипт для работы с SonarQube и локальным репозиторием Git.<br> Цель проекта – возможность выполнить быструю проверку качества кода перед тем, как помещать доработки в рабочее хранилище. В Sonar и Git выгружается не вся конфигурация, а только объекты из заданного списка.<br> https://github.com/vkrivov/go/

02.07.2024    4767    vkrivov@yandex.ru    8    

20

DevOps и автоматизация разработки OneScript Системный администратор Программист Стажер Бесплатно (free)

Рассмотрим создание самоформирующейся документации через комментарии и соглашения: как это сделать и зачем, с описанием полного цикла от исходников конфигурации до странички в интернете

17.06.2024    6647    bayselonarrend    5    

62

OneScript Программист Стажер Бесплатно (free)

Поговорим про меню, спиннеры, прогресс-бары и прочие свистелки для CLI приложений на OneScript

20.05.2024    3177    bayselonarrend    18    

70
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. fatman78 21 13.01.25 16:42 Сейчас в теме
Отличный материал!
О каком репозитарии GitHub идет речь в просьбе поддержать репозиторий? Непонятно.
3. bayselonarrend 2244 13.01.25 16:51 Сейчас в теме
2. bayselonarrend 2244 13.01.25 16:43 Сейчас в теме
Извините)
Прикрепленные файлы:
cheburashka; +1 Ответить
4. nixel 1439 13.01.25 17:29 Сейчас в теме
Аффтар, пешы исчо!

По поводу перевода на осень - обратите внимание, что осень умеет внедрять зависимости в приватные поля класса, не обязательно использовать пластилин в конструкторе объекта и заниматься переприсваиванием параметра в поле. А если нужна какая-то дополнительная логика инициализации, то есть &ФинальныйШтрих.

А так - очень жду :)

P.S. Интересно, затроните ли вы тему мета-аннотаций. Если есть, что обсудить - стучитесь в личку в телеге или приходите в осенний чат там же.
5. nixel 1439 13.01.25 18:29 Сейчас в теме
(4) как идея - реализацию интерфейса проверок можно организовать с помощью &Приемка, как это сделано в самой осени.
6. o.nikolaev 216 13.01.25 20:51 Сейчас в теме
Отличный материал, мое почтение.
starik-2005; +1 Ответить
7. user925427 130 13.01.25 20:52 Сейчас в теме
Отлично подготовленный материал и, что становится редкостью, без грамматических ошибок.
starik-2005; +1 Ответить
Оставьте свое сообщение