1. Архитектура ПО

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

Важные аспекты архитектуры ПО включают:

Простой пример архитектуры ПО


2. Архитектурный путь

Архитектурный путь - это организация и структурирование компонентов системы. Включает в себя логические уровни абстракции, модули, компоненты и пр. Здесь, и далее по проекту, является синонимом аббревиатуры CALMF (Contour->Application->Layer->Module->Funtion), структура проекта

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

  1. Contour (КОНТУР): master Наивысший уровень архитектуры, описывающий общий контур или границы всего приложения. На этом уровне определяются общие принципы, требования и цели разрабатываемого программного продукта.

  2. Application (ПРИЛОЖЕНИЕ): Desktop Этот уровень определяет основные компоненты приложения и их взаимодействие. Определяются области ответственности и основные функциональные блоки приложения.

  3. Layer (СЛОЙ): Backend Уровень слоя относится к разделению приложения на логические слои, каждый из которых выполняет определенные функции. Например, это может быть слой доступа к данным, бизнес-логики, представления и т.д.

  4. Module (МОДУЛЬ): library.database На этом уровне происходит декомпозиция слоев на более мелкие модули. Модуль - это логически связанный набор функций, отвечающий за определенный аспект системы. Это может включать в себя отдельные компоненты, классы или файлы.

  5. Function (ФУНКЦИЯ): query Этот уровень представляет собой конечные функции или методы, реализующие конкретные задачи внутри модуля. Функции могут быть описаны в терминах входных данных, выходных данных и выполняемой логики.

Иерархия представлена следующим образом:

Contour ->Application ->Layer ->Module ->Function

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

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


3. Примеры организации архитектуры

Возьмем типовую функцию авторизации. Допустим, функционал авторизации расположен в 3 слоях: Backend, Frontend, Database, и все слои разрабатывают 3 отдельных программиста.

Каждый из них в своей функции, отвечающей за авторизацию, отправляет 2 события в мониторинг с соответствующим TYPE_ID (Тип события)

Backend

Для разработчика архитектурный путь: Master -> MyApp -> Backend -> Auth -> SignIN

Контур Приложение Слой Модуль Функция Тип события
Master MyApp Backend Auth SignIN start
Master MyApp Backend Auth SignIN finish *

Frontend

Для разработчика архитектурный путь: Master -> MyApp -> Frontend -> AuthForm -> SignIN

Контур Приложение Слой Модуль Функция Тип события
Master MyApp Frontend AuthForm SignIN start
Master MyApp Frontend AuthForm SignIN finish *

Database

Для разработчика архитектурный путь: Master -> MyApp -> Database -> Auth -> SignIN_Routine

Контур Приложение Слой Модуль Функция Тип события
Master MyApp Database Auth SignIN_Routine start
Master MyApp Database Auth SignIN_Routine finish *

После того, как разработчик покроет этими метками код, любой пользователь системы выполняет сценария, и мы получаем статистику в виде 6 инцидентов (3 парных jobID с типами событий start-finish) для одного Контура и Приложения.

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


4. Транзакция

Транзакция - это 2 события одного jobID. Данный подход увеличивает трафик, но, мы получаем объективную исчерпывающую информацию о жизнедеятельности ПО: фактическое\среднее время выполнения функций, количество запросов функции за отчетный период (её востребованность), архитектурный путь и нагрузку на архитектурные слои.

Сформированный запрос должен пройти одну из цепочек бизнес-процесса.

4.1 Нормальная транзакция

Каждая функция архитектурного пути наблюдаемого кода покрывается метками c одним jobID дважды (далее, 2 состояния), тем самым, образуя нормальную транзакцию, состоящую из 2-х состояний: start и finish.

Первое состояние jobID: TYPE_ID=start

Второе состояние jobID: TYPE_ID=finish

4.2 Ошибочная транзакция (Инцидент)

Ошибочная транзакция или Инцидент - это транзакция из 2-х состояний, второе состояние которой не finish.

В момент запуска функции отправляем TYPE_ID=start. Если программист ведет свой учет jobID, то на старт его можно передать на старте транзакции. Все последующие операции для этого jobID будут выполняться планово. Если не введет - jobID будет сгенерирован и возвращен. Далее, его необходимо указывать для второго состояния.

В момент финиша или исключительной ситуации отправляем второе состояние TYPE_ID=finish, TYPE_ID=error, TYPE_ID=token, etc.

Второе состояние этого же jobID не равно finish. Т.е., второе состояние - это TYPE_ID=error [token, connect, etc.]

4.3 Аномальная транзакция

Если у транзакции меньше или больше 2-х состояний - она считается аномальной транзакцией

Количество инцидентов с одним jobID не равно 2!

Например, если норма = пара jobID: start->finish, то, аномалией считается следующее:

4.4 Генерация ключей

Принцип алгоритма формирования ключей на примере jobID в LC.Мониторинг


5. Ключ операции (SERVER_KEY)

Данный ключ выдается администрацией LC.Мониторинг по запросу. Им "пдописывается" каждый запрос к серверу

Подробнее о SERVER_KEY


6. Тип события (TYPE_ID)

TYPE_ID или тип события - это одно из предусмотренных базовых значений:

events_dictionary = {
    "start": {"title": "Успешный старт", "url": "[ICONS_FOLDER]/start.png"},
    "finish": {"title": "Успешный финиш", "url": "[ICONS_FOLDER]/finish.png"},
    "error": {"title": "Ошибка", "url": "[ICONS_FOLDER]/error.png"},
    "security": {"title": "Ошибка безопасности", "url": "[ICONS_FOLDER]/security.png"},
    "warning": {"title": "Предупреждение", "url": "[ICONS_FOLDER]/warning.png"},
    "alert": {"title": "Уведомление", "url": "[ICONS_FOLDER]/alert.png"},
    "process": {"title": "В процессе", "url": "[ICONS_FOLDER]/process.png"},
    "longtime": {"title": "Долгое время работы", "url": "[ICONS_FOLDER]/longtime.png"},
    "html": {"title": "Ошибка HTML или JS", "url": "[ICONS_FOLDER]/html.png"},
    "connect": {"title": "Ошибка интеграционной шины", "url": "[ICONS_FOLDER]/connect.png"},
    "zabbix": {"title": "Ошибка инфраструктуры", "url": "[ICONS_FOLDER]/zabbix.png"},
    "token": {"title": "Ошибка просроченного\несуществующего токена", "url": "[ICONS_FOLDER]/token.png"},
}

При необходимости, список может быть расширен для конкретного клиента


7. Получатель сообщения (HOOK_ID)

HOOK_ID - это идентификатор чата в Битрикс24 (возможна урезанная версия оповещений в Telegram-бот).

В случае, если у Вас еще нет Битрикс24, то как партнёр 1С-Битрикс, рекомендуем зарегистрировать бесплатную версию и начать

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

Ниже видеоскрин с последовательностью действий для создания и получения WEBHOOK в Битрикс24

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

После того, как мы подготовили webhook и создали нужный нам чат на стороне Битрикс24, можем отправить в него тестовое сообщение

Приведен пример кода на Python

import json
from bitrix24 import Bitrix24

# URL для вашего Bitrix24 REST API инициализируется
url = '[BITRIX_WEBHOOK_URL]]'

# Настройки для отправки сообщения
settings = {
    'method': 'im.message.add',
    'hook_id': '[HOOK_ID]',
    'message': 'Какое-то тестовое сообщение'
}

# Инициализация объекта Bitrix24 с использованием предоставленного URL
bx24 = Bitrix24(url)

# Функция для отправки сообщения
def send_message(settings):
    # Используем метод callMethod из экземпляра Bitrix24
    result = bx24.callMethod(settings["method"],
                              DIALOG_ID=settings["hook_id"],
                              MESSAGE=settings["message"])
    # Раскомментируйте строку ниже, если хотите видеть результат в выводе
    # print(f'result: {result}')
    if not result:
        result = False

    return result

# Вызов функции для отправки сообщения при запуске скрипта
if __name__ == '__main__':
    # Преобразование результата в строку перед использованием json.loads
    result_str = json.dumps(send_message(settings))
    print(json.loads(result_str))


8. Задание (jobID)

Уникальный идентификатор задания (jobID), представляет собой уникальное значение или метку, присвоенное определенному заданию внутри транзакции (job) или операции в системе.

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

В контексте заданий (jobs) в программировании или информационных системах, jobID может использоваться для отслеживания выполнения определенного задания, присвоения статусов, управления зависимостями между заданиями и т. д.

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

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

Например:

Транзакция ID: XYZ
  - jobID для События 1: TYPE_ID=start
  - jobID для События 2: TYPE_ID=finish // или иное состояние TYPE_ID

Рекомендуемый алгоритм генерации jobID для контроля на стороне разработчиков клиента

import time
import random
import string

def generate_random_string():
    current_microtime = str(int(time.time() * 1e6))
    random_suffix = ''.join(random.choices(string.ascii_letters + string.digits, k=32 - len(current_microtime)))
    random_string = current_microtime + random_suffix
    return random_string

# Пример использования
random_string = generate_random_string()
print(random_string)

9. Автозадачи

Адтозадача или автоматическая задача - это задача, которая создается сервисом LC.Мониторинг по результатам анализа ситуации, в нужную группу, с нужным количеством участников; назначается ответственный и сроки выполнения.

Мы придерживаемся структурированных задач, поэтому, используем подход SMART при создании всех автоматических задач.

Автозадачи делятся на 3 типа: прямые (или просто автозадачи), реверс-задачи, автопоручения.

План "прямой" автозадачи выглядит следующим образом: Название: Исправить функцию "get" :: Тип события: "vista3". Событий: (3) на 2023-12-19 19:21:02 Описание (тело) задачи: Уникальный идентификатор группы задач: 9F89A6C0AEE734F4400F10D7E6AF732D Specific (Конкретная): - Количество однотипных инцидентов - Архитектурный путь Measurable (Измеримая): ToDo - лист с конкретным сценарием исполнения - Провести анализ списка jobID идентификаторов (список jobID) - Установить пользователя, связаться, уточнить детали (список пользователей) и т.п.

Achievable (Достижимая): Технический план действий для 2+ линии СТП, согласно SLA

Relevant (Актуальная): Краткая сводка по инциденту в подобном виде:

Количество событий: 3
Пользователей МИС: 1
Пользователей ПК: 1

Появление инцидента: 2023-12-19 22:20:52
Последний инцидент: 2023-12-19 22:20:53
Общая длительность: 00:00:01

Time-Framed (Определенная во времени):

Технический план действий для 1, 2 линии СТП, тимлида и руководителя проекта, согласно SLA

План реверс-задачи аналогичен, т.к. стандартизирован по SMART и не требует изменений

Автозадачи создаются автоматически, по результатам анализа базы за последнюю минуту, если инцидентов > 2, contour > master. Если автозадача уже есть и она в стадии "Требует проверки" или "Завершена", а количество инцидентов изменилось, задача будет возобновлена.

Реверс-задачи создаются автоматически, по результатам анализа базы за последнюю минуту, если инцидентов > 0, contour = master. Возобновление реверс-задачи аналогично автозадаче

Автопоручения загружаются вручную в виде предзаполненного шаблона XLSX

9.1 taskCode

taskCode - это производная от архитектурного пути и TYPE_ID. Пример, 9F89A6C0AEE734F4400F10D7E6AF732D. Состоит из CALMF + тип события. Данный код вычисляется средствами СУБД. Данный код уникален. Он необходим для создания и контроля задачи по этому коду в Битрикс24.

Данные задачи следует считать техническим долгом разработчиков перед клиентом. Для подобных задач создается отдельная группа (проект\скрам) "Технический долг"

Алгоритм создания автозадачи:

9.2 taskID

Уникальный цифровой идентификатор с номером задачи из Битрикс24

9.3 reverse taskCode

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

Данные задачи следует считать ошибками, которые допустили разработчики при покрытии своего кода мониторингом. Для подобных задач создается отдельная группа (проект\скрам), например: "Реверс-события Мониторинга"

9.4 reverse_taskID

То же самое, что и taskID, но для реверс-задачи