# #bash #go #pipe #tee
Вопрос:
У меня есть приложение Go, которое вставляет данные в базу данных, а также пишет что-то для os.Stdout
использования пакета logrus
. Для каждой вставки в БД в stdout записывается журнал.
Вот команда, которую я использую goapp | tee myfile
Я обнаружил, что goapp
правильно вставлял данные в базу данных в течение нескольких часов, НО файл был пуст, и он ничего не показывал в stdout. В какой-то момент он по какой-то причине остановил вставку (я не знаю).
- Приложение застряло в ожидании буфера stdout или чего-то в этом роде
- Каким-то образом, возможно, тройник не запустился или разбился
Если tee
разбился, почему goapp
не разбился при попытке записи в stdout?! Он должен, по крайней мере, получить a SIGPIPE
.
Эта команда работала правильно в течение нескольких недель. Это первый раз, когда он так сильно проваливается, и я теряюсь в догадках о причине. Я больше не уверен в использовании stdout с tee, если он ненадежен.
Код go очень прост:
import "github.com/sirupsen/logrus" func NewLogger(outputFile *os.File) *logrus.Logger { var log = logrus.New() log.Formatter = new(logrus.JSONFormatter) log.Level = logrus.TraceLevel log.Out = outputFile return log } logger := NewLogger(os.Stdout) for { [...] err = InsertInDatabase(db, databaseArgs) logger.Traceln("inserted in the database") [...] }
Я что-то пропустил? В чем может быть причина? Тот факт, что данные были вставлены в БД, но не зарегистрированы в stdout, заставляет меня думать, что с трубой и тройником что-то не так.
Комментарии:
1. Я предполагаю, что logrus по умолчанию выводит данные в stderr вместо stdout
2. Это всегда срабатывало, но в тот раз (не стартовый вопрос) строка
log.Out = outputFile
задает значение выводаos.Stdout
.3. Одним из альтернативных способов избежать
tee
превращения в дочерний процесс оболочки, но ждать только завершения вашего приложения golang, было бы использовать замену процесса, т. Е.goapp gt; gt;(tee myfile)
. В вашей операции есть вероятность, что ваше приложение умерло иtee
не было завершено должным образом4. (оригинальное сообщение)
5. Также еще одна рекомендация — Попробуйте запустить конвейер,
set -e; set -o pipefail
чтобы одна неудачная команда вышла из всей системы