Ответ
Для мониторинга логов в реальном времени я в основном использую утилиту tail с флагом -f.
Основные инструменты командной строки:
tail -f /path/to/app.log: Основная команда для отслеживания новых записей в лог-файле в реальном времени.tail -n 200 -f app.log: Показывает последние 200 строк и продолжает отслеживать новые.tail -f app.log | grep 'ERROR': Очень полезная комбинация для фильтрации только строк с ошибками.
Помимо tail, я также использую:
less +F /path/to/app.log: Похоже наtail -f, но позволяет легко переключаться в режим поиска и навигации (нажавCtrl+C) и обратно (нажавShift+F).journalctl -u my-app.service -f: Если приложение управляется черезsystemd, это стандартный способ просмотра его логов.
Программная реализация в Go
В Go можно реализовать подобную логику для чтения конца файла. Это может быть полезно для создания собственных инструментов мониторинга. Вот упрощенный пример:
// Внимание: это упрощенный пример. В реальном коде нужно
// аккуратно обрабатывать границы строк, чтобы не выводить 'обрывки'.
file, err := os.Open("app.log")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// Перемещаемся в конец файла
stat, _ := file.Stat()
offset := stat.Size()
// В цикле проверяем, не увеличился ли размер файла
for {
time.Sleep(time.Second)
newStat, _ := file.Stat()
if newStat.Size() > offset {
// Читаем новые данные
buf := make([]byte, newStat.Size()-offset)
_, err := file.ReadAt(buf, offset)
if err == nil {
fmt.Print(string(buf))
}
offset = newStat.Size()
}
} Ответ 18+ 🔞
Ах ты ж, ёпта, ну и тема! Мониторинг логов, да? Это ж святое, блядь. Ну слушай сюда, я тебе сейчас так расскажу, что у тебя волосы завьются, если они ещё есть.
Для этого дела, чтобы в реальном времени смотреть, как твоё приложение пиздит в лог, есть старый добрый инструмент — tail. Но не просто tail, а с волшебным флагом -f. Это как подглядывать в замочную скважину, только легально.
Основные палочки-выручалочки в консоли:
tail -f /путь/до/файла/app.log: Это классика, блядь. Включил — и понеслась. Все новые строчки прямо тебе в терминал, как из пожарного шланга.tail -n 200 -f app.log: А это для параноиков. Сначала покажет последние 200 строк, чтобы ты въехал в контекст, а потом уже начнёт следить за новыми. Типа "а что тут вообще происходило до того, как я пришёл?"tail -f app.log | grep 'ERROR': А вот это, сука, самое охуенное! Ты же не хочешь читать весь этот информационный понос? Ты хочешь только крики боли и отчаяния — строки с 'ERROR'. Эта команда отфильтрует всё лишнее. Жизнь сразу становится проще.
Ну и кроме tail, есть ещё парочка трюков в рукаве:
less +F /путь/до/файла/app.log: Почти какtail -f, но с возможностью нажатьCtrl+C, чтобы остановиться и пошариться по файлу в поисках чего-нибудь, а потомShift+F— чтобы снова в реальный режим нырнуть. Удобная штука, если ты не просто овощ, а овощ с амбициями.journalctl -u my-app.service -f: А это если твоё приложение — это какой-нибудь сервис, которым командуетsystemd. Тогда его логи живут в специальном журнале, и смотреть их надо вот так. Стандартно, блядь.
А если на Go написать?
Ну а если тебе, хитрожопому, мало готовых утилит и захотелось свою велосипедную тележку собрать, то на Go это можно сделать. Смотри, вот тебе пример, упрощённый до безобразия, конечно:
// Внимание: это упрощенный пример. В реальном коде нужно
// аккуратно обрабатывать границы строк, чтобы не выводить 'обрывки'.
file, err := os.Open("app.log")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// Перемещаемся в конец файла
stat, _ := file.Stat()
offset := stat.Size()
// В цикле проверяем, не увеличился ли размер файла
for {
time.Sleep(time.Second)
newStat, _ := file.Stat()
if newStat.Size() > offset {
// Читаем новые данные
buf := make([]byte, newStat.Size()-offset)
_, err := file.ReadAt(buf, offset)
if err == nil {
fmt.Print(string(buf))
}
offset = newStat.Size()
}
}
Вот эта штука будет каждую секунду проверять, не подрос ли файл, и если да — выводить новенькое. Прям как tail -f, только самопальный. Но, ёпта, честно? Чаще всего проще использовать готовое. Зачем изобретать хуй в пальто, когда есть отличные инструменты?