import json import time import os import requests import logging from prometheus_client import start_http_server, Gauge from unidecode import unidecode from dotenv import load_dotenv # Настройка логгирования logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.StreamHandler() ] ) logger = logging.getLogger(__name__) load_dotenv() # Устанавливаем соответствие кириллицы латинице TRANS_TABLE = str.maketrans({ "у": "u", "с": "s", "т": "t", "а": "a", "н": "n", "о": "o", "в": "v", "л": "l", "е": "e", "ч": "ch", "а": "a", "с": "s", "т": "t", "ь": "", "п": "p", "ч": "ch", "-": "_", ".": "_", "'": "", "`": "", '"': "", "h": "h", "h": "h" # Оставляем 'h' как есть }) def sanitize_metric_name(name): # Удаляем все недопустимые символы name = unidecode(name) # Транслитерация сначала name = name.lower() # Приводим к нижнему регистру name = name.translate(TRANS_TABLE) # Применяем таблицу замен # Дополнительная очистка от недопустимых символов valid_chars = [] for c in name: if c.isalpha() or c.isdigit() or c == '_': valid_chars.append(c) elif c in ['-', '.', ' ']: valid_chars.append('_') name = ''.join(valid_chars) # Удаляем повторяющиеся подчеркивания name = '_'.join(filter(None, name.split('_'))) # Добавляем префикс, если имя начинается с цифры if name and name[0].isdigit(): name = f"metric_{name}" # Проверяем, что имя не пустое if not name: name = 'unnamed_metric' return name def get_token(): login = os.getenv("LOGIN") password = os.getenv("PASSWORD") if not login or not password: logger.error("Логин или пароль не заданы в .env") raise ValueError("Логин или пароль не заданы в .env") data = {'login': login, 'password': password} headers = { "Content-Type": "application/json", "Accept": "application/json" } try: req = requests.post("https://api.owencloud.ru/v1/auth/open/", json=data, headers=headers) req.raise_for_status() return "Bearer " + req.json()["token"] except requests.exceptions.RequestException as e: logger.error(f"Ошибка авторизации: {e}") return None def load_json_data(): token = get_token() if not token: logger.error("Не удалось получить токен. Завершаем работу.") return [] device_id = "459205" headers = {'Authorization': token} data = json.dumps({'filter': ''}) try: req = requests.post(f"https://api.owencloud.ru/v1/device/{device_id}", data=data, headers=headers) req.raise_for_status() json_response = req.json() return json_response.get("parameters", []) except requests.exceptions.RequestException as e: logger.error(f"Ошибка запроса устройства: {e}") return [] metrics = {} def main(): logger.info("Запуск сервера Prometheus на порту 8000") start_http_server(8000) logger.info("Сервер запущен") while True: parameters = load_json_data() if parameters: for param in parameters: try: metric_name = sanitize_metric_name(param["name"]) value = float(param["value"]) if metric_name not in metrics: metrics[metric_name] = Gauge(metric_name, "Описание метрики") logger.info(f"Создана новая метрика: {metric_name}") metrics[metric_name].set(value) logger.debug(f"Метрика {metric_name} обновлена: {value}") except Exception as e: logger.error(f"Ошибка обработки параметра {param}: {e}") time.sleep(60) if __name__ == "__main__": main()