Сценарий Logrotate не работает - PullRequest
3 голосов
/ 24 апреля 2019

У меня есть следующий скрипт logrotate

/path/to/folder {
   daily
   rotate 30
   notifempty
   sharedscripts
   copytruncate
   compress
   dateext


   preremove
     if file --mime-type "$1" | grep -q gzip$; then
          mkdir -p /path/to/archive/folder && cp $1 $_
     fi
   endscript
}

  • Чего я пытаюсь достичь: -

    Перед удалением файла журнала после хранения в течение 30 дней скопируйте в другую папку.

Я запускаю эту конфигурацию logstash в режиме отладки

logrotate -d $CONFIG_FILE

Судя по журналам, вращение работает нормально, но он даже не запускает скрипт preremove. Я еще не запускал этот конфиг в прямом эфире, так как я хотел протестировать его перед этим.

logrotate версия 3.8.6

Ответы [ 3 ]

1 голос
/ 03 мая 2019

Я не уверен, спрашиваете ли вы, почему preremove не работает, или ваш сценарий выглядит нормально.

Preremove, и как проверить

Я не верю, что logrotate когда-либо будет запускать скрипт preremove, если он не удаляет файлы (за -d). Я создал тестовый пример и запустил его под strace logrotate -d нашел файлы, которые нужно было удалить, и написал, что удалил их, но не запустил код preremove. Честно говоря, для меня это имеет смысл, и именно этого я и ожидаю, поскольку preremove может нанести такой же вред, как и само удаление.

Для выполнения теста, я думаю, вам нужно воспроизвести вашу живую среду в другом каталоге и просто запустить ее. Не используйте полноразмерные файлы, просто используйте фиктивные файлы с несколькими строками. Создайте сценарий для создания тестовой папки, чтобы вы могли легко воспроизвести тест. Используйте touch для установки меток времени. Например:

for n in $(seq 1 30); do
    cp test.log test.log.$n
    gzip test.log.$n
    touch -d "now - $n day" test.log.$n.gz
done

Сам скрипт

  • grep -q gzip$ неверно. $ исчезнет при разборе оболочки. Вы должны заключить это в одинарные кавычки.
  • Как кто-то еще написал, я бы не ожидал, что $_ будет работать. Повторите имя каталога или используйте переменную в сценарии.
  • Я не думаю, что вам нужны \ побеги в EOL, как предложено.
  • Вы, вероятно, хотите cp -p, как кто-то предложил.
  • Если ваши файлы большие, cp будет медленным. Если ваш архив находится в той же файловой системе, рассмотрите возможность использования ln (не ln -s!) Вместо этого. Это будет мгновенно.
  • Использование file --mime-type, вероятно, работает нормально, но, честно говоря, я бы просто основал его на имени файла в этом случае, поскольку logrotate надежно добавит .gz к любому файлу, для которого file вернет gzip. expr "$1" : '.*gz$' выдаст ненулевое число в качестве стандартного вывода для любого $1, который заканчивается .gz. Это даст ровно число 0 в качестве стандартного вывода для имени файла, которое не заканчивается на .gz.
0 голосов
/ 03 мая 2019

Я думаю, что ваше состояние само по себе не наступает true можете ли вы поставить эхо перед предварительным удалением для отладки.Попробуйте выполнить условие if вручную и посмотрите.

# file --mime-type * | grep -i *.1
audit.log.1: text/plain
# file --mime-type * | grep -i *.1$
# file --mime-type * | grep -q *.1$
# file --mime-type * | grep -q *.1
0 голосов
/ 02 мая 2019

Возможно, вам не хватает выхода из продолжения строки, как показано в некоторых примерах

preremove
    # debug line
    systemd-cat -t "rot-pre-rm" echo "preremove block, file: $1"
    if file --mime-type "$1" | grep -q gzip$; then \
        cp -p "$1" /path/to/archive/syslog/; \
    fi; \
endscript
...