- Добавлена функция сворачивания/разворачивания секций локальных и удаленных контейнеров - Реализовано периодическое обновление списка контейнеров каждые 30 секунд - Добавлена автоматическая фильтрация остановленных контейнеров - Обновлены обработчики событий для корректной работы в свернутом sidebar - Добавлены функции обновления счетчиков контейнеров - Обновлена документация с описанием новых функций - Добавлены тестовые скрипты для проверки функциональности Автор: Сергей Антропов Сайт: https://devops.org.ru
13 KiB
13 KiB
🌐 Удаленные клиенты LogBoard+
Обзор
LogBoard+ поддерживает сбор логов с удаленных серверов через специальные клиенты. Это позволяет централизованно мониторить логи контейнеров с нескольких машин.
Архитектура
┌─────────────────┐ HTTP API ┌─────────────────┐
│ Удаленный │ ──────────────► │ LogBoard+ │
│ сервер │ │ Сервер │
│ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ Клиент │ │ │ │ Web UI │ │
│ │ LogBoard+ │ │ │ │ │ │
│ └─────────────┘ │ │ └─────────────┘ │
└─────────────────┘ └─────────────────┘
Компоненты
1. Серверная часть (LogBoard+ Server)
- API эндпоинты: Прием логов от удаленных клиентов
- Хранение логов: Сохранение в файловой системе
- Web интерфейс: Отображение локальных и удаленных контейнеров
- Визуальное разделение: Четкое различие между локальными и удаленными контейнерами
2. Клиентская часть (LogBoard+ Client)
- Сбор логов: Чтение логов Docker контейнеров
- Отправка данных: HTTP POST запросы на сервер
- Автоматизация: Docker Compose для простого развертывания
Установка и настройка
На сервере LogBoard+
- Убедитесь, что сервер LogBoard+ запущен и доступен
- Получите API ключ для аутентификации клиентов
На удаленном сервере
- Создайте директорию для клиента:
mkdir logboard-client
cd logboard-client
- Создайте
docker-compose.yml
:
version: '3.8'
services:
logboard-client:
build: .
container_name: logboard-client
environment:
- LOGBOARD_SERVER_URL=http://your-logboard-server:9001
- API_KEY=your-api-key
- HOSTNAME=your-server-name
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./logs:/app/logs
restart: unless-stopped
user: 0:0
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
# Тестовый контейнер для демонстрации
test-nginx:
image: nginx:alpine
container_name: test-nginx
ports:
- "8080:80"
restart: unless-stopped
- Создайте
Dockerfile
:
FROM python:3.11-slim
RUN apt-get update && apt-get install -y \
curl \
&& rm -rf /var/lib/apt/lists/*
RUN groupadd -r logboard && useradd -r -g logboard logboard
RUN mkdir -p /app /var/log
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app/ ./app/
RUN mkdir -p /var/log && \
chown -R logboard:logboard /app /var/log
USER logboard
CMD ["python", "app/main.py"]
- Создайте
requirements.txt
:
aiohttp==3.9.1
docker==6.1.3
urllib3==2.1.0
requests==2.31.0
- Создайте
app/main.py
:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
LogBoard+ Client - Клиент для отправки логов на сервер LogBoard+
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
import asyncio
import aiohttp
import docker
import os
import logging
from datetime import datetime
# Настройка логирования
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
class LogBoardClient:
def __init__(self):
self.server_url = os.getenv('LOGBOARD_SERVER_URL', 'http://localhost:9001')
self.api_key = os.getenv('API_KEY', 'default-key')
self.hostname = os.getenv('HOSTNAME', 'unknown')
# Инициализация Docker клиента
try:
self.docker_client = docker.from_env()
logger.info("Docker клиент инициализирован успешно")
except Exception as e:
logger.error(f"Ошибка инициализации Docker клиента: {e}")
self.docker_client = None
async def send_logs(self, container_name, logs_data):
"""Отправка логов на сервер LogBoard+"""
try:
async with aiohttp.ClientSession() as session:
url = f"{self.server_url}/api/logs/remote"
data = {
'container_name': container_name,
'hostname': self.hostname,
'logs': logs_data,
'api_key': self.api_key
}
async with session.post(url, json=data) as response:
if response.status == 200:
logger.info(f"Логи контейнера {container_name} отправлены успешно")
else:
logger.error(f"Ошибка отправки логов: {response.status}")
except Exception as e:
logger.error(f"Ошибка при отправке логов: {e}")
def get_container_logs(self, container_name, tail=100):
"""Получение логов контейнера"""
try:
if not self.docker_client:
return []
container = self.docker_client.containers.get(container_name)
logs = container.logs(tail=tail, timestamps=True).decode('utf-8')
return logs.split('\n')[:-1] # Убираем пустую строку в конце
except Exception as e:
logger.error(f"Ошибка получения логов контейнера {container_name}: {e}")
return []
async def collect_and_send_logs(self):
"""Сбор и отправка логов всех контейнеров"""
try:
if not self.docker_client:
logger.error("Docker клиент недоступен")
return
containers = self.docker_client.containers.list()
logger.info(f"Найдено {len(containers)} контейнеров")
for container in containers:
try:
logs = self.get_container_logs(container.name)
if logs:
await self.send_logs(container.name, logs)
except Exception as e:
logger.error(f"Ошибка обработки контейнера {container.name}: {e}")
except Exception as e:
logger.error(f"Ошибка сбора логов: {e}")
async def run(self):
"""Основной цикл работы клиента"""
logger.info(f"LogBoard+ Client запущен для хоста: {self.hostname}")
logger.info(f"Сервер: {self.server_url}")
while True:
try:
await self.collect_and_send_logs()
await asyncio.sleep(30) # Пауза 30 секунд
except Exception as e:
logger.error(f"Критическая ошибка: {e}")
await asyncio.sleep(60) # Увеличенная пауза при ошибке
async def main():
client = LogBoardClient()
await client.run()
if __name__ == "__main__":
asyncio.run(main())
- Запустите клиент:
docker-compose up -d
Использование
Web интерфейс
После настройки клиентов, в веб-интерфейсе LogBoard+ вы увидите:
📍 Локальные контейнеры
- Контейнеры с текущего сервера
- Обычное отображение без дополнительных индикаторов
🌐 Удаленные контейнеры
- Контейнеры с удаленных серверов
- Визуальное разделение по хостам
- Индикаторы удаленного доступа (глобус 🌐)
- Время последнего обновления
- Статистика по хостам
Функции интерфейса
🔽 Сворачивание секций
- Секции контейнеров: Можно сворачивать/разворачивать секции "Локальные контейнеры" и "Удаленные контейнеры"
- Секции хостов: Каждый хост в удаленных контейнерах можно сворачивать отдельно
- Кнопки управления: Стрелки для сворачивания/разворачивания
- Сохранение состояния: Состояние сворачивания сохраняется между сессиями
⚡ Периодическое обновление
- Автоматическое обновление: Список контейнеров обновляется каждые 30 секунд
- Фильтрация остановленных: Остановленные контейнеры автоматически скрываются из интерфейса
- Обновление счетчиков: Количество контейнеров в секциях обновляется в реальном времени
- Логирование изменений: В консоли браузера отображается информация об изменениях
📱 Адаптивный интерфейс
- Свернутый sidebar: Миникарточки контейнеров с иконками статуса
- Развернутый sidebar: Полная информация о контейнерах с возможностью сворачивания секций
- Мобильная поддержка: Адаптивный дизайн для мобильных устройств
API эндпоинты
Получение контейнеров
GET /api/containers/services
Authorization: Bearer <token>
Ответ:
[
{
"id": "container-id",
"name": "container-name",
"status": "running",
"is_remote": false,
"hostname": "localhost",
"project": "project-name",
"service": "service-name"
},
{
"id": "remote-hostname-container",
"name": "remote-container",
"status": "running",
"is_remote": true,
"hostname": "remote-host",
"last_modified": "2025-08-20T16:30:00",
"size": 1024
}
]
Получение логов удаленного контейнера
GET /api/logs/{container_id}
Authorization: Bearer <token>
Получение статистики логов
GET /api/logs/stats/{container_id}
Authorization: Bearer <token>
Мониторинг и отладка
Логи клиента
docker-compose logs -f logboard-client
Проверка здоровья
curl http://localhost:8080/health
Тестирование API
python3 test_interface.py
Безопасность
- API ключи: Обязательная аутентификация клиентов
- HTTPS: Рекомендуется использовать HTTPS для передачи данных
- Сетевая изоляция: Клиенты должны иметь доступ только к необходимым портам
Устранение неполадок
Клиент не подключается
- Проверьте URL сервера в переменной
LOGBOARD_SERVER_URL
- Убедитесь, что API ключ правильный
- Проверьте сетевое подключение
Логи не отображаются
- Проверьте права доступа к Docker socket
- Убедитесь, что контейнеры запущены
- Проверьте логи клиента
Интерфейс не обновляется
- Откройте консоль браузера (F12)
- Проверьте наличие ошибок JavaScript
- Убедитесь, что WebSocket соединения работают
Автор
Сергей Антропов
🌐 Сайт: https://devops.org.ru
📧 Email: contact@devops.org.ru
Документация обновлена: 2025-08-20