Легковесная альтернатива lnav с упором на UX, авто-парсинг JSON и мгновенную фильтрацию.
- Мульти-source tailing — Слежение за несколькими файлами по шаблону (
./logs/*.log) - Ring Buffer — Хранит последние 5000 строк в памяти (настраивается)
- Stdin Support —
cat 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# Простой 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# Простой 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# Простой 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# Создаём разные файлы
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
- Гексагональная архитектура — Домен-ориентированный дизайн с чёткими границами
- Channel-based Concurrency — Безопасные обновления UI через Go каналы
- Throttling — UI обновляется максимум 20 раз/сек для предотвращения CPU spike
- Без внешней 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/*.logLOGT_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": "..."} - Logfmt —
level=error msg="..." - Plain —
2024-01-01 10:00:00 ERROR message
Без учёта регистра:
FATAL,ERROR,WARN,INFO,DEBUG,TRACE
- File watching: inotify (Linux), FSEvents (macOS), polling (Windows)
- Нет удалённой поддержки логов (в планах: HTTP forwarding)
- Fork
- Создайте feature branch
- Запустите тесты:
go test ./... - Отправьте PR
MIT License - см. LICENSE