owen-prometheus/main.py
2025-04-23 21:50:26 +03:00

128 lines
4.3 KiB
Python
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()