logrotate preremove script not working - 2nd pair of eyes ?
I just want to check I'm not going bonkers.
From the logrotate man page:
--------------- preremove script endscript The script is executed once just before removal of a log file. logrotate will pass the name of file which is soon to be removed as the first argument to the script. See also firstaction and the SCRIPTS section. -------------- So it sounds reasonable to expect "script" to be invoked with one argument, the name of the to-be-removed file. Right? the logrotate config - it is a test-setup, for rotating /var/log/testfile when it exceeds 1k, without date extension. ---------------- /var/log/testfile { compress nodateext maxage 365 rotate 5 missingok notifempty size 1k sharedscripts postrotate /usr/bin/true endscript preremove /usr/local/bin/archive_logfile.sh endscript } ------------------- My script /usr/local/bin/archive_logfile.sh contains #!/bin/sh test -n "$1" || exit 75 log="$1" plus the rest When I run a logrotate (either with systemd or manually), it does invoke the preremove script, but without the filename as argument, so my script leaves with a 75. -- Per Jessen, Zürich (12.9°C) Member, openSUSE Heroes (2016 - present) We're hiring - https://en.opensuse.org/openSUSE:Heroes
On 2023-05-10 11:11, Per Jessen wrote:
I just want to check I'm not going bonkers.
From the logrotate man page:
--------------- preremove script endscript
The script is executed once just before removal of a log file. logrotate will pass the name of file which is soon to be removed as the first argument to the script. See also firstaction and the SCRIPTS section. --------------
So it sounds reasonable to expect "script" to be invoked with one argument, the name of the to-be-removed file. Right?
...
When I run a logrotate (either with systemd or manually), it does invoke the preremove script, but without the filename as argument, so my script leaves with a 75.
The man says: SCRIPTS The lines between the starting keyword (e.g. prerotate) and endscript (both of which must appear on lines by themselves) are executed (using /bin/sh). The script inherits some traits from the logrotate process, including stderr, stdout, the current directory, the environment, and the umask. Scripts are run as the invoking user and group, irrespective of any su directive. If the --log flag was specified, file descriptor 3 is the log file. So perhaps you can do: ---------------- /var/log/testfile { compress nodateext maxage 365 rotate 5 missingok notifempty size 1k sharedscripts postrotate /usr/bin/true endscript preremove /usr/local/bin/archive_logfile.sh /var/log/testfile endscript } ------------------- It is not what you wish, but would do. Even I understand you can do: ---------------- /var/log/testfile { compress nodateext maxage 365 rotate 5 missingok notifempty size 1k sharedscripts postrotate /usr/bin/true endscript preremove test -n "$1" || exit 75 log="$1" plus the rest endscript } ------------------- Looking at the existing rotate files, they actually do put scripts in there: /etc/logrotate.d/acct: var/log/account/pacct { compress dateext maxage 365 rotate 99 size=+4096k notifempty missingok create 640 root root postrotate /usr/bin/systemctl try-restart acct.service endscript } /etc/logrotate.d/chrony: var/log/chrony/*.log { su chrony chrony missingok nocreate sharedscripts postrotate /usr/bin/chronyc cyclelogs > /dev/null 2>&1 || true endscript } /etc/logrotate.d/mariadb has a long script. -- Cheers / Saludos, Carlos E. R. (from 15.4 x86_64 at Telcontar)
Carlos E. R. wrote:
preremove /usr/local/bin/archive_logfile.sh /var/log/testfile endscript } -------------------
It is not what you wish, but would do.
You are close, but no, it would not be called with the right arguments. There are two calls - 1) as above 2) with the oldest compressed archive
Even I understand you can do:
[snip]
preremove test -n "$1" || exit 75
log="$1" plus the rest endscript
Yes, that variant I hadn't thought of, but I also definitely want to avoid. -- Per Jessen, Zürich (16.5°C) Member, openSUSE Heroes (2016 - present) We're hiring - https://en.opensuse.org/openSUSE:Heroes
Per Jessen wrote:
Carlos E. R. wrote:
preremove /usr/local/bin/archive_logfile.sh /var/log/testfile endscript } -------------------
It is not what you wish, but would do.
You are close, but no, it would not be called with the right arguments. There are two calls -
1) as above 2) with the oldest compressed archive
That "preremove" option is pretty cool. Didn't exist when I set up our own log archiving almost twenty years ago :-) It makes it easy and straight forward to do log archiving. Although it is yet another situation where you wish for MAILTO to work with systemd timers :-) -- Per Jessen, Zürich (15.0°C) Member, openSUSE Heroes (2016 - present) We're hiring - https://en.opensuse.org/openSUSE:Heroes
On 2023-05-10 14:10, Per Jessen wrote:
Per Jessen wrote:
Carlos E. R. wrote:
preremove /usr/local/bin/archive_logfile.sh /var/log/testfile endscript } -------------------
It is not what you wish, but would do.
You are close, but no, it would not be called with the right arguments. There are two calls -
1) as above 2) with the oldest compressed archive
That "preremove" option is pretty cool. Didn't exist when I set up our own log archiving almost twenty years ago :-)
It makes it easy and straight forward to do log archiving. Although it is yet another situation where you wish for MAILTO to work with systemd timers :-)
preremove /usr/local/bin/archive_logfile.sh $1 send_the_email $1 endscript :-) -- Cheers / Saludos, Carlos E. R. (from 15.4 x86_64 at Telcontar)
Carlos E. R. wrote:
That "preremove" option is pretty cool. Didn't exist when I set up our own log archiving almost twenty years ago :-)
It makes it easy and straight forward to do log archiving. Although it is yet another situation where you wish for MAILTO to work with systemd timers :-)
preremove /usr/local/bin/archive_logfile.sh $1 send_the_email $1 endscript
:-)
Huh? what is that supposed to do ? The MAILTO option in a cronjob would mail the errors and any other output from the log rotation. Yours seems to mail the logfile? logrotate has a direct option for that, "mail". -- Per Jessen, Zürich (11.3°C) Member, openSUSE Heroes (2016 - present) We're hiring - https://en.opensuse.org/openSUSE:Heroes
On 2023-05-10 21:33, Per Jessen wrote:
Carlos E. R. wrote:
That "preremove" option is pretty cool. Didn't exist when I set up our own log archiving almost twenty years ago :-)
It makes it easy and straight forward to do log archiving. Although it is yet another situation where you wish for MAILTO to work with systemd timers :-)
preremove /usr/local/bin/archive_logfile.sh $1 send_the_email $1 endscript
:-)
Huh? what is that supposed to do ? The MAILTO option in a cronjob would mail the errors and any other output from the log rotation. Yours seems to mail the logfile? logrotate has a direct option for that, "mail". Sorry, that you mail whatever you need by writing a script to do it all.
-- Cheers / Saludos, Carlos E. R. (from 15.4 x86_64 at Telcontar)
On Wed, May 10, 2023 at 12:11 PM Per Jessen <per@opensuse.org> wrote: ...
preremove /usr/local/bin/archive_logfile.sh endscript } -------------------
My script /usr/local/bin/archive_logfile.sh contains
#!/bin/sh test -n "$1" || exit 75
log="$1" plus the rest
When I run a logrotate (either with systemd or manually), it does invoke the preremove script, but without the filename as argument, so my script leaves with a 75.
logrotate calls sh -c "script content" xxx log-file-name where script content is literal text between preremove'/endscript. So it ends up calling /usr/local/bin/archive_logfile.sh without parameters. You need preremove /usr/local/bin/archive_logfile.sh $1 endscript Hopefully the filename will not contain a literal double quote :)
Andrei Borzenkov wrote:
logrotate calls
sh -c "script content" xxx log-file-name
where script content is literal text between preremove'/endscript. So it ends up calling /usr/local/bin/archive_logfile.sh without parameters. You need
preremove /usr/local/bin/archive_logfile.sh $1 endscript
Thanks!!!! that did the trick. It had never occured to me that the _contents_ between preremove and endscript would be called like that. -- Per Jessen, Zürich (16.8°C) Member, openSUSE Heroes (2016 - present) We're hiring - https://en.opensuse.org/openSUSE:Heroes
On Wed, 10 May 2023 11:11:36 +0200 Per Jessen <per@opensuse.org> wrote:
I just want to check I'm not going bonkers.
From the logrotate man page:
Which logrotate man page? Which version of logrotate on which system version? I ask because when I google, some versions of the man page don't even have a premove directive.
--------------- preremove script endscript
The script is executed once just before removal of a log file. logrotate will pass the name of file which is soon to be removed as the first argument to the script. See also firstaction and the SCRIPTS section. --------------
So it sounds reasonable to expect "script" to be invoked with one argument, the name of the to-be-removed file. Right?
Kind of, but the repeated [elsewhere] mention of 'first' implies there might be more than one argument. But I can't find any trace of it. Just lots of discussion of quoting so filenames with spaces can be handled. Also, where is the SCRIPTS section? I can't find it.
the logrotate config - it is a test-setup, for rotating /var/log/testfile when it exceeds 1k, without date extension.
---------------- /var/log/testfile { compress nodateext maxage 365 rotate 5 missingok notifempty size 1k sharedscripts postrotate /usr/bin/true endscript preremove /usr/local/bin/archive_logfile.sh endscript } -------------------
What's the point of the /usr/bin/true? I don't understand what that postrotate does.
My script /usr/local/bin/archive_logfile.sh contains
#!/bin/sh test -n "$1" || exit 75
log="$1" plus the rest
When I run a logrotate (either with systemd or manually), it does invoke the preremove script, but without the filename as argument, so my script leaves with a 75.
I'd be trying to print as much as possible from the execution of archive_logfile.sh (use -x?, print any and all args etc)
Dave Howorth wrote:
On Wed, 10 May 2023 11:11:36 +0200 Per Jessen <per@opensuse.org> wrote:
I just want to check I'm not going bonkers.
From the logrotate man page:
Which logrotate man page? Which version of logrotate on which system version? I ask because when I google, some versions of the man page don't even have a premove directive.
You're right, I should have mentioned it. It is version 3.18.1, on TW and Leap 15.4 and 15.5
So it sounds reasonable to expect "script" to be invoked with one argument, the name of the to-be-removed file. Right?
Kind of, but the repeated [elsewhere] mention of 'first' implies there might be more than one argument. But I can't find any trace of it. Just lots of discussion of quoting so filenames with spaces can be handled.
I can deal with multiple arguments, it is having none that is causing a problem :-)
Also, where is the SCRIPTS section? I can't find it.
Right after the preremove section.
---------------- /var/log/testfile { compress nodateext maxage 365 rotate 5 missingok notifempty size 1k sharedscripts postrotate /usr/bin/true endscript preremove /usr/local/bin/archive_logfile.sh endscript } -------------------
What's the point of the /usr/bin/true? I don't understand what that postrotate does.
That "true" is just a placeholder - normally it would be a reload of the syslog unit.
When I run a logrotate (either with systemd or manually), it does invoke the preremove script, but without the filename as argument, so my script leaves with a 75.
I'd be trying to print as much as possible from the execution of archive_logfile.sh (use -x?, print any and all args etc)
Yeah, done that too, but when there are no arguments ..... -- Per Jessen, Zürich (16.8°C) Member, openSUSE Heroes (2016 - present) We're hiring - https://en.opensuse.org/openSUSE:Heroes
participants (4)
-
Andrei Borzenkov
-
Carlos E. R.
-
Dave Howorth
-
Per Jessen