Какой наиболее эффективный метод вынести параметры запуска Python-скрипта для различных хостов?

Как я могу создать собственный экспортер для мониторинга Windows-инфраструктуры, который будет преобразовывать JSON-метрики с <a href="https://github.com/LibreHardwareMonitor/LibreHardwareMonitor" rel="nofollow">LHM</a> в формат для Prometheus? У меня есть две проблемы: 

1) Если я реализую решение прямо, то получается громоздкий и зашумленный код, где метрики создаются и задаются вручную, например:
   ```python
   # создаём объект типа Gauge
   self.MB_temperature = Gauge("MB_temperature", "Motherboard Temperature, first sensor")
   self.MB_Fan_1 = Gauge("MB_Fan_1", "Motherboard Fan #1")
   ...
   self.GPU_Temperature_Core = Gauge("GPU_Temperature_Core", "GPU Core Temperature_Core")
   ```

   Нужно указать, как присваивать значения метрикам:
   ```python
   self.MB_temperature.set(LhmMetricsRespJson["Children"][0]["Children"][0]["Children"][0]["Children"][1]["Children"][0]["Value"])
   self.MB_Fan_1.set(LhmMetricsRespJson["Children"][0]["Children"][0]["Children"][0]["Children"][2]["Children"][0]["Value"])
   ...
   self.GPU_Temperature_Core.set(LhmMetricsRespJson["Children"][0]["Children"][3]["Children"][1]["Children"][0]["Value"])
   ```

2) Структура JSON-данных, получаемых от LHM, может отличаться в зависимости от аппаратного обеспечения, что делает невозможным полагаться на индексы и уровень вложенности.

Как лучше всего организовать параметры запуска скрипта для различных хостов? Как можно вынести набор "метрика (название+описание) + путь к получению её значения" в отдельные файлы для разных хостов, которые скрипт будет подтягивать во время запуска?
  • 28 января 2025 г. 16:44
Ответы на вопрос 1
Для решения вашей задачи можно использовать несколько подходов для создания и конфигурирования экспортера метрик, а также для настройки параметров запуска скрипта для различных хостов. Разделим задачу на две части: создание экспортера и управление параметрами запуска.

### Создание экспортера

1. **Динамическое создание метрик:**
   Вместо того чтобы создавать каждую метрику вручную, можно использовать динамический подход для создания метрик и их обращения. Например, вы можете определить метрики в JSON-файле и использовать их для создания объектов метрик в вашем экспортёре.

   Пример JSON-файла для конфигурации метрик (`metrics_config.json`):
   ```json
   {
       "metrics": [
           {
               "name": "MB_temperature",
               "description": "Motherboard Temperature, first sensor",
               "path": "Children[0].Children[0].Children[0].Children[1].Children[0].Value"
           },
           {
               "name": "MB_Fan_1",
               "description": "Motherboard Fan #1",
               "path": "Children[0].Children[0].Children[0].Children[2].Children[0].Value"
           },
           {
               "name": "GPU_Temperature_Core",
               "description": "GPU Core Temperature",
               "path": "Children[0].Children[3].Children[1].Children[0].Value"
           }
       ]
   }
   ```

   В вашем коде можно использовать библиотеку `jsonpath-ng` для динамической выборки значений по указанному пути:
   ```python
   import json
   from jsonpath_ng import jsonpath, parse
   from prometheus_client import Gauge

   class LHMExporter:
       def __init__(self, metrics_config_path):
           with open(metrics_config_path) as f:
               self.metrics_config = json.load(f)
           self.metrics = {}
           self.create_metrics()

       def create_metrics(self):
           for metric in self.metrics_config['metrics']:
               self.metrics[metric['name']] = Gauge(metric['name'], metric['description'])

       def update_metrics(self, lhm_data):
           for metric in self.metrics_config['metrics']:
               jsonpath_expr = parse(metric['path'])
               value = jsonpath_expr.find(lhm_data)
               if value:
                   self.metrics[metric['name']].set(value[0].value)

   # Пример использования
   exporter = LHMExporter('metrics_config.json')
   exporter.update_metrics(LhmMetricsRespJson)
   ```

2. **Обработка разных структур JSON:**
   Для обработки различных структур JSON можно использовать вариант с адаптерами или использовать `try-except`, чтобы система могла обрабатывать разные форматы данных. Создайте функции, которые будут пытаться взять данные по различным путям, а в случае неудачи переходить к следующим вариантам.

### Управление параметрами запуска

1. **Конфигурация для разных хостов:**
   Создайте конфигурационный файл (например, `config.json`), где будет храниться информация о хостах, их параметрах и метриках. Например:
   ```json
   {
       "hosts": {
           "host1": {
               "metrics_file": "host1_metrics.json"
           },
           "host2": {
               "metrics_file": "host2_metrics.json"
           }
       }
   }
   ```

2. **Загрузка конфигурации при запуске:**
   При запуске скрипта можно определить текущий хост, считывать соответствующий конфигурационный файл и загружать метрики из JSON:
   ```python
   import json
   import sys

   if len(sys.argv) != 2:
       print("Usage: python exporter.py <hostname>")
       sys.exit(1)

   hostname = sys.argv[1]

   with open('config.json') as f:
       config = json.load(f)

   metrics_file = config['hosts'][hostname]['metrics_file']
   exporter = LHMExporter(metrics_file)
   ```

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