logboard/test_remote_system.py
Сергей Антропов 04dfe30d58 feat: Добавлена поддержка удаленных клиентов для LogBoard+
- Создан LogBoard клиент для отправки логов с удаленных серверов
- Добавлен API эндпоинт /api/logs/remote с аутентификацией
- Реализована структурированная система сохранения логов
- Исправлена совместимость Docker client библиотеки
- Добавлена полная документация и тестирование
2025-08-20 19:25:29 +03:00

267 lines
10 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

#!/usr/bin/env python3
"""
Тестовый скрипт для проверки системы удаленных клиентов LogBoard
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
import asyncio
import aiohttp
import json
import os
import subprocess
import time
from datetime import datetime
# Конфигурация теста
SERVER_URL = os.getenv('LOGBOARD_SERVER_URL', 'http://localhost:9001')
API_KEY = os.getenv('LOGBOARD_API_KEY', 'dev-key-123')
HOSTNAME = os.getenv('HOSTNAME', 'test-host')
async def test_server_availability():
"""Тестирование доступности сервера"""
print("🔍 Проверка доступности сервера LogBoard...")
try:
async with aiohttp.ClientSession() as session:
async with session.get(
f"{SERVER_URL}/",
timeout=aiohttp.ClientTimeout(total=10)
) as response:
if response.status == 200:
print("✅ Сервер LogBoard доступен")
return True
else:
print(f"❌ Сервер недоступен, статус: {response.status}")
return False
except Exception as e:
print(f"❌ Ошибка подключения к серверу: {e}")
return False
async def test_remote_logs_endpoint():
"""Тестирование эндпоинта для удаленных логов"""
print("📤 Тестирование отправки логов...")
test_data = {
"hostname": HOSTNAME,
"container_name": "test-nginx",
"logs": [
f"{datetime.now().isoformat()} nginx: [info] Test log line 1",
f"{datetime.now().isoformat()} nginx: [info] Test log line 2",
f"{datetime.now().isoformat()} nginx: [error] Test error log",
f"{datetime.now().isoformat()} nginx: [warn] Test warning log"
],
"timestamp": datetime.now().isoformat()
}
headers = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json',
'User-Agent': 'LogBoard-System-Test/1.0'
}
try:
async with aiohttp.ClientSession() as session:
async with session.post(
f"{SERVER_URL}/api/logs/remote",
json=test_data,
headers=headers,
timeout=aiohttp.ClientTimeout(total=30)
) as response:
print(f"📊 Статус ответа: {response.status}")
if response.status == 200:
result = await response.json()
print("✅ Логи успешно отправлены:")
print(f" - Хост: {result.get('hostname')}")
print(f" - Контейнер: {result.get('container_name')}")
print(f" - Сообщение: {result.get('message')}")
print(f" - Файл: {result.get('log_file')}")
return True
else:
error_text = await response.text()
print(f"❌ Ошибка отправки логов: {response.status}")
print(f" Ответ сервера: {error_text}")
return False
except Exception as e:
print(f"❌ Ошибка при отправке логов: {e}")
return False
def check_docker_services():
"""Проверка статуса Docker сервисов"""
print("🐳 Проверка статуса Docker сервисов...")
try:
# Проверяем статус контейнеров
result = subprocess.run(
['docker-compose', 'ps'],
capture_output=True,
text=True,
cwd='.'
)
if result.returncode == 0:
print("✅ Docker Compose сервисы:")
print(result.stdout)
return True
else:
print(f"❌ Ошибка проверки сервисов: {result.stderr}")
return False
except Exception as e:
print(f"❌ Ошибка проверки Docker: {e}")
return False
def check_log_files():
"""Проверка создания логовых файлов"""
print("📁 Проверка логовых файлов...")
log_dir = "logs/remote"
if os.path.exists(log_dir):
files = os.listdir(log_dir)
if files:
print(f"✅ Найдены логовые файлы в {log_dir}:")
for file in files:
file_path = os.path.join(log_dir, file)
if os.path.isdir(file_path):
subfiles = os.listdir(file_path)
print(f" 📂 {file}/ ({len(subfiles)} файлов)")
for subfile in subfiles[:3]: # Показываем первые 3 файла
print(f" 📄 {subfile}")
if len(subfiles) > 3:
print(f" ... и еще {len(subfiles) - 3} файлов")
return True
else:
print(f"⚠️ Директория {log_dir} пуста")
return False
else:
print(f"❌ Директория {log_dir} не существует")
return False
async def test_client_communication():
"""Тестирование связи с клиентом"""
print("🔗 Тестирование связи с клиентом...")
try:
# Проверяем, запущен ли клиент
result = subprocess.run(
['docker-compose', 'ps', 'logboard-client'],
capture_output=True,
text=True,
cwd='.'
)
if 'Up' in result.stdout:
print("✅ LogBoard клиент запущен")
# Проверяем логи клиента
logs_result = subprocess.run(
['docker-compose', 'logs', '--tail=10', 'logboard-client'],
capture_output=True,
text=True,
cwd='.'
)
if logs_result.returncode == 0:
print("📋 Последние логи клиента:")
print(logs_result.stdout)
return True
else:
print("⚠️ Не удалось получить логи клиента")
return False
else:
print("❌ LogBoard клиент не запущен")
return False
except Exception as e:
print(f"❌ Ошибка проверки клиента: {e}")
return False
async def main():
"""Основная функция тестирования"""
print("=" * 70)
print("LogBoard Remote System - Полное тестирование")
print("=" * 70)
print(f"Сервер: {SERVER_URL}")
print(f"API ключ: {API_KEY[:10]}..." if len(API_KEY) > 10 else f"API ключ: {API_KEY}")
print(f"Хост: {HOSTNAME}")
print()
tests = []
# Тест 1: Проверка Docker сервисов
print("1⃣ Проверка Docker сервисов...")
docker_ok = check_docker_services()
tests.append(("Docker сервисы", docker_ok))
print()
# Тест 2: Проверка доступности сервера
print("2⃣ Проверка доступности сервера...")
server_ok = await test_server_availability()
tests.append(("Доступность сервера", server_ok))
print()
if server_ok:
# Тест 3: Отправка тестовых логов
print("3⃣ Отправка тестовых логов...")
logs_ok = await test_remote_logs_endpoint()
tests.append(("Отправка логов", logs_ok))
print()
# Тест 4: Проверка логовых файлов
print("4⃣ Проверка логовых файлов...")
files_ok = check_log_files()
tests.append(("Логовые файлы", files_ok))
print()
# Тест 5: Проверка клиента
print("5⃣ Проверка клиента...")
client_ok = await test_client_communication()
tests.append(("Связь с клиентом", client_ok))
print()
else:
print("⚠️ Пропуск тестов 3-5 из-за недоступности сервера")
tests.extend([
("Отправка логов", False),
("Логовые файлы", False),
("Связь с клиентом", False)
])
# Результаты тестирования
print("=" * 70)
print("РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ")
print("=" * 70)
passed = 0
total = len(tests)
for test_name, result in tests:
status = "✅ ПРОЙДЕН" if result else "НЕ ПРОЙДЕН"
print(f"{test_name:<20} {status}")
if result:
passed += 1
print()
print(f"Итого: {passed}/{total} тестов пройдено")
if passed == total:
print("🎉 Все тесты пройдены успешно!")
print(" Система удаленных клиентов работает корректно.")
elif passed >= total * 0.7:
print("⚠️ Большинство тестов пройдено.")
print(" Проверьте настройки для неудачных тестов.")
else:
print("❌ Много тестов не пройдено.")
print(" Проверьте конфигурацию и запуск сервисов.")
print()
print("Полезные команды:")
print(" make up - Запуск всех сервисов")
print(" make logs - Просмотр логов")
print(" make status - Статус сервисов")
print(" cd client && make test - Тестирование клиента")
if __name__ == "__main__":
asyncio.run(main())