Skip to content

turkprogrammer/logt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LogT — Современный Explorer логов (TUI)

Легковесная альтернатива lnav с упором на UX, авто-парсинг JSON и мгновенную фильтрацию.

Go License Tests Version

🚀 Возможности

Основные

  • Мульти-source tailing — Слежение за несколькими файлами по шаблону (./logs/*.log)
  • Ring Buffer — Хранит последние 5000 строк в памяти (настраивается)
  • Stdin Supportcat app.log | logt
  • Log Forwarding — Экспорт отфильтрованных логов в файл (--forward) или stdout (--forward -)
  • Time Filtering — Фильтрация по времени (--since 1h, --until 2024-01-15)
  • JSON Path Filtering — Мощная фильтрация JSON (--json '.level == "error"')
  • Headless Mode — CLI режим без TUI (--headless --stats)
  • Bookmarks — Сохранение важных строк (m, M, e)
  • Shell Completions — Автодополнение для bash/zsh/fish (logt completion bash)
  • Color Mode — Управление цветами (--color always|never|auto)
  • Rate Calculator — Отображение скорости поступления логов в status bar

Просмотр

  • Live Tail — Автопрокрутка при поступлении новых строк
  • Подсветка синтаксиса — Цветовая кодировка уровней (INFO=синий, WARN=желтый, ERROR=красный)
  • JSON Expand — Нажмите Enter на JSON строке для разворачивания в полноэкранное дерево

Интерактивность

  • Fuzzy Filter — Нажмите / для мгновенной фильтрации
  • Regex Filter — Нажмите r для режима регулярных выражений
  • Pause/Resume — Нажмите Space для паузы автопрокрутки
  • Source Toggle — Нажмите Tab для показа/скрытия панели источников
  • JSON Explorer — Нажмите Enter на JSON строке для просмотра ключей

🚀 Тесты производительности

Протестировано на Intel Core i3-10100 @ 3.6 GHz:

Операция Скорость Примечания
RingBuffer Add ~27M ops/sec Потокобезопасный, блокировка-free чтение
JSON Парсинг ~314K строк/sec Авто-детект + парсинг
Fuzzy Фильтр ~3.7M совпадений/sec Без учёта регистра
Определение уровня ~394K строк/sec На основе регулярных выражений
IsValidJSON ~1.3M проверок/sec Быстрая валидация

Память: Ring buffer ограничен ~2MB для 5000 строк (настраивается)

LogT разработан для высоконагруженных окружений с минимальным потреблением CPU/RAM.

📦 Установка

Из исходников

# Клонировать репозиторий
git clone https://github.com/turkprogrammer/logt.git
cd logt

# Собрать бинарник
go build -o logt ./cmd/logt

# Или установить в GOPATH
go install ./cmd/logt

🛠️ Использование

Базовое

# Следить за одним файлом
logt ./app.log

# Следить за несколькими файлами по шаблону
logt ./logs/*.log

# Фильтр по уровню
logt --level error ./app.log

# Stdin pipe
cat app.log | logt

Тестовые логи

Windows (PowerShell)

# Простой JSON (с кавычками)
echo '{"level":"info","msg":"Server started"}' | Out-File -FilePath app.log -Encoding utf8

# JSON с доп. полями
echo '{"level":"error","msg":"Connection failed","host":"db1","port":5432}' | Out-File app.log -Encoding utf8

# Несколько строк
@'
{"level":"info","msg":"Starting"}
{"level":"warn","msg":"Low memory"}
{"level":"error","msg":"OOM killed"}
{"level":"debug","msg":"GC done"}
'@ | Out-File app.log -Encoding utf8

# Запуск
.\logt.exe app.log

# Pipe
Get-Content app.log | .\logt.exe

Windows (CMD)

# Простой JSON
echo {"level":"info","msg":"Server started"} > app.log

# JSON с доп. полями - используем printf для кавычек
printf "{\"level\":\"error\",\"msg\":\"Connection failed\",\"host\":\"db1\",\"port\":5432}\n" > app.log

# Несколько строк (CMD)
(
  echo {"level":"info","msg":"Starting"}
  echo {"level":"warn","msg":"Low memory"}
  echo {"level":"error","msg":"OOM killed"}
  echo {"level":"debug","msg":"GC done"}
) > app.log

# Запуск
logt.exe app.log

# Pipe
type app.log | logt.exe

Linux / macOS

# Простой JSON
echo '{"level":"info","msg":"Server started"}' > app.log

# JSON с доп. полями
echo '{"level":"error","msg":"Connection failed","host":"db1","port":5432}' > app.log

# Logfmt
echo 'level=info msg="Server started"' > app.log
echo 'level=error msg="Connection failed" host=db1 port=5432' > app.log

# Plain text с уровнем
echo '2024-01-15 10:30:00 INFO Server started' > app.log
echo '2024-01-15 10:30:01 ERROR Connection failed' > app.log

# Несколько строк
cat > app.log << 'EOF'
{"level":"info","msg":"Starting application"}
{"level":"info","msg":"Loading config from /etc/app.conf"}
{"level":"warn","msg":"Config key 'debug' not found, using default"}
{"level":"debug","msg":"Initializing database connection pool"}
{"level":"info","msg":"Connected to postgres://localhost:5432/db"}
{"level":"error","msg":"Query failed: relation 'users' does not exist"}
{"level":"info","msg":"Running migrations..."}
{"level":"info","msg":"Migration v001_create_users completed"}
{"level":"info","msg":"Server listening on :8080"}
{"level":"error","msg":"Unhandled panic: index out of range"}
{"level":"warn","msg":"Retry attempt 1/3 for external API"}
{"level":"error","msg":"External API still unavailable after 3 retries"}
EOF

# Запуск
./logt app.log

# Pipe
cat app.log | ./logt

# С другими командами
kubectl logs deployment/myapp | ./logt
journalctl -f | ./logt
docker logs -f mycontainer | ./logt

Мульти-формат (mixed sources)

# Создаём разные файлы
echo '{"level":"info","msg":"API log"}' > api.log
echo 'level=warn msg="Auth warning"' > auth.log
echo '2024-01-15 ERROR Database connection lost' > db.log

# Следим за всеми сразу
logt api.log auth.log db.log
# или
logt ./*.log

Примеры

# Следить за всеми логами сервисов
logt /var/log/services/*.log

# Найти только ошибки
logt --level error ./app.log

# Фильтрация по времени (последний час)
logt --since 1h ./app.log

# Фильтрация по времени (с 30 минут назад до 10 минут назад)
logt --since 30m --until 10m ./app.log

# Фильтрация по абсолютному времени
logt --since "2024-01-15 10:00" ./app.log

# Комбинация фильтров
logt --since 1h --level error ./app.log

# JSON Path фильтрация (только ошибки)
logt --json '.level == "error"' ./app.log

# JSON Path фильтрация (startswith)
logt --json '.message | startswith("Error")' ./app.log

# JSON Path фильтрация (contains)
logt --json '.error | contains("timeout")' ./app.log

# JSON Path + время
logt --json '.level == "error"' --since 1h ./app.log

# JSON Path + вложенные поля
logt --json '.user.role == "admin"' ./app.log

# С настроенным буфером
logt --buffer 10000 --max-buffer 20000 ./app.log

# Экспорт отфильтрованных логов в файл
logt --forward filtered.log ./app.log

# Экспорт в stdout (pipe)
logt --forward - ./app.log | grep ERROR

# С источниками из конфига
logt

# Stdin от другой команды
kubectl logs deployment/app | logt

# Headless режим + статистика
logt --headless --stats ./app.log

# Headless режим + последние N строк
logt --headless --tail 100 ./app.log

# Headless + stats + time filter
logt --headless --stats --tail 50 --since 1h ./app.log

# Shell completions
logt completion bash > /etc/bash_completion.d/logt
logt completion zsh > /usr/local/share/zsh/site-functions/_logt
logt completion fish > ~/.config/fish/completions/logt.fish

# Color mode
logt --color always ./app.log    # Всегда использовать цвета
logt --color never ./app.log     # Отключить цвета
logt --color auto ./app.log      # Авто-определение (по умолчанию)

⌨️ Горячие клавиши

Клавиша Действие
Space Пауза/Продолжить автопрокрутку
/ Открыть Fuzzy фильтр
r Переключить Fuzzy/Regex фильтр
Enter Применить фильтр / Открыть JSON
Backspace Удалить символ из фильтра
Esc Очистить фильтр / Закрыть JSON просмотр
↑ / ↓ Прокрутка вверх/вниз
PgUp / PgDn Прокрутка по страницам
Home / End Перейти в начало/конец
g Перейти в начало (less-style)
G Перейти в конец (less-style)
n Следующее совпадение
N Предыдущее совпадение
Tab Переключить панель источников
m Bookmark текущую строку
M Показать bookmarks
e Export bookmarks в YAML
q Выход

🏗️ Архитектура

logt/
├── cmd/logt/main.go           # Точка входа, CLI
├── internal/
│   ├── config/config.go      # Загрузка конфигурации (yaml, env)
│   ├── domain/domain.go      # Модели, Парсеры, RingBuffer
│   ├── provider/provider.go  # Провайдеры файлов и stdin
│   └── ui/
│       ├── model.go          # Состояние Bubble Tea
│       ├── update.go         # Обработчики сообщений
│       └── view.go           # Рендеринг через Lip Gloss
├── config.example.yaml       # Пример конфигурации
└── README.md

Проектные решения

  1. Гексагональная архитектура — Домен-ориентированный дизайн с чёткими границами
  2. Channel-based Concurrency — Безопасные обновления UI через Go каналы
  3. Throttling — UI обновляется максимум 20 раз/сек для предотвращения CPU spike
  4. Без внешней tail библиотеки — Собственная реализация через polling

🧪 Тестирование

# Запустить все тесты
go test ./...

# С бенчмарками
go test -bench=. ./...

# Конкретный тест
go test -v -run TestRingBuffer ./...

Покрытие тестами

  • RingBuffer overflow (100k → 5k limit)
  • Конкурентный доступ (thread-safety)
  • JSON/Logfmt/Plain парсеры с fallback
  • Fuzzy filter matching
  • Определение уровня (case-insensitive)
  • Конфигурация (yaml, env, flags)

📊 Сравнение

Возможность LogT lnav
Размер бинарника ~6MB ~15MB
Время старта <100ms ~200ms
JSON поддержка Нативная Ограниченная
Fuzzy Filter
Regex Filter
YAML конфиг
Требует конфиг

🔧 Конфигурация

LogT работает без конфига из коробки. Для кастомизации создайте файл:

# ~/.config/logt/config.yaml или ./logt.yaml
buffer-size: 5000     # Размер буфера
buffer-max: 10000     # Максимальный размер
theme: dark           # Тема (dark)
forward: filtered.log # Файл для экспорта
sources:              # Источники по умолчанию
  - /var/log/*.log

Переменные окружения

LOGT_BUFFER_SIZE=10000
LOGT_LEVEL=error
LOGT_FORWARD=filtered.log
LOGT_THEME=dark

Флаги командной строки

-p, --path string        Пути к файлам или шаблоны
-l, --level string       Фильтр по уровню (debug,info,warn,error)
-b, --buffer int         Размер буфера (по умолчанию: 5000)
-m, --max-buffer int     Максимальный размер буфера
-f, --forward string     Экспорт логов (файл или stdout)
-t, --theme string       Тема (dark)
-S, --since string       Фильтр с времени (1h, 30m, 2024-01-15)
-U, --until string       Фильтр по время (1h, 30m, 2024-01-15)
-j, --json string        JSON Path фильтр (.level == "error")
-c, --color string       Цветовой режим (always, never, auto)
-H, --headless           Режим без TUI (CLI)
-n, --tail int           Последние N строк (0 = все)
-s, --stats              Вывод статистики
-e, --export string      Экспорт bookmarks в файл
-v, --version            Версия
-h, --help               Помощь

📝 Поддерживаемые форматы логов

Авто-определение

  • JSON{"level": "error", "message": "..."}
  • Logfmtlevel=error msg="..."
  • Plain2024-01-01 10:00:00 ERROR message

Определение уровня

Без учёта регистра:

  • FATAL, ERROR, WARN, INFO, DEBUG, TRACE

🐛 Известные ограничения

  • File watching: inotify (Linux), FSEvents (macOS), polling (Windows)
  • Нет удалённой поддержки логов (в планах: HTTP forwarding)

🤝 Вклад

  1. Fork
  2. Создайте feature branch
  3. Запустите тесты: go test ./...
  4. Отправьте PR

📄 Лицензия

MIT License - см. LICENSE

About

A modern, lightweight log explorer TUI written in Go. Fast, fuzzy search, JSON parsing, and instant filtering. Lightweight alternative to lnav. The Swiss Army Knife for Logs!

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages