Hello,
On Solaris 10, here are entries for logs in httpd.conf
ErrorLog "|/export/apache/apache-2.2.17/bin/rotatelogs -l -f /var/log/apache/error_log.%Y%m%d 86400"
It keeps creating daily logs with below names -
-rw-r--r-- 1 root root 1016747232 Apr 5 23:59 /var/log/apache/error_log.20190405
-rw-r--r-- 1 root root 946721391 Apr 6 23:59 /var/log/apache/error_log.20190406
-rw-r--r-- 1 root root 1092546540 Apr 7 23:59 /var/log/apache/error_log.20190407
-rw-r--r-- 1 root root 1172486303 Apr 8 23:59 /var/log/apache/error_log.20190408
-rw-r--r-- 1 root root 909466871 Apr 9 23:59 /var/log/apache/error_log.20190409
-rw-r--r-- 1 root root 916731172 Apr 10 23:59 /var/log/apache/error_log.20190410
-rw-r--r-- 1 root root 785326845 Apr 11 23:59 /var/log/apache/error_log.20190411
-rw-r--r-- 1 root root 463003111 Apr 12 13:38 /var/log/apache/error_log.20190412
I want to create a symlink 'error_log' and that should point to latest log file. One idea is, to create two cronjobs for 00:00 midnight, something like this
00 00 * * * ln -s /var/log/apache/error_log.20190412 /var/log/apache/error_log
59 00 * * * unlink /var/log/apache/error_log
But how will I tell cron, to pick only latest error_log.xxxxxx ? Is it possible ?
Thanks
1 Like
RudiC
April 12, 2019, 5:10pm
2
Fortunately, your file names are "sort friendly". Try
ls *log.* | sort | tail -1
1 Like
Yes, that can help. How can I pass that name to cronjob ?
Alternatively I thought of passing same syntax as mentioned in logrotate, but that fails
bash-3.2# ls -l /var/log/apache/error_log.%Y%m%d
/var/log/apache/error_log.%Y%m%d: No such file or directory
bash-3.2#
If this can work, I can pass that in cron in similar way
00 00 * * * ln -s /var/log/apache/error_log.%Y%m%d /var/log/apache/error_log
59 00 * * * unlink /var/log/apache/error_log
1 Like
shell uses backticks and $( ) to turn program output into strings.
cd /var/log ; ln -s $(ls *error_log.* | sort | tail -1) error_log
2 Likes
This worked well. Thanks much
1 Like
I'd not bother with the sort. The output should be lexically ordered anyway, so it's redundant.
In some OS, you might need to add a -f
to get it to replace the sym-link, and of course you need permission to write to the directory (which root will have, naturally)
Robin
1 Like
I would also be inclined to use the reverse-sort option to ls
, and head
instead of tail
, thus:
cd /var/log ; ln -s $(ls -r *error_log.* | head -1) error_log
Andrew
Yes, and ensure a successful cd
:
cd /var/log && ln -s "$(ls -r *error_log.* | head -1)" error_log
BTW ls -r
is good here; ls -t
would really sort by mtime.
madeingermany:
Yes, and ensure a successful cd
:
cd /var/log && ln -s "$(ls -r *error_log.* | head -1)" error_log
BTW ls -r
is good here; ls -t
would really sort by mtime.
I gave below command in crontab, it executes, but failed with rc-2
13 16 * * * cd /var/log/apache && ln -s $(ls -r *error_log.* | head -1) error_log
14 16 * * * unlink /var/log/apache/error_log
From /var/cron/log -->
> CMD: cd /var/log/apache && ln -s $(ls -r *error_log.* | head -1) error_log
> root 16954 c Thu Apr 18 16:09:00 2019
< root 16954 c Thu Apr 18 16:09:00 2019 rc=2
That is not very surprising. You try to create a symlink at 4:13 pm (which fails because a symlink by that name already exists) and then you remove the symlink at 4:14 pm.
Furthermore, due to occasionally heavy load conditions, there is no guarantee that one cron job scheduled to start at a given time will complete before another job scheduled to run one minute later.
Why not do both in one step (assuming that you aren't really trying to create a symbolic link that has a one minute lifetime):
13 16 * * * cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
2 Likes
RudiC
April 19, 2019, 2:57am
11
I'm a bit surprised that both the log entries are at 16:09h when the crontab entries are for 16:13h and 16:14h? Sure they belong together?
May be I missed to copy correct content. Here I tried it again. I made two attemps. One job created for 23:58 and another time at 00:01
-bash-3.2# crontab -l | tail -2
58 23 * * * cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
01 00 * * * cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
-bash-3.2#
-bash-3.2# tail -f /var/cron/log
< root 28826 c Thu Apr 18 16:13:00 2019 rc=2
> CMD: unlink /var/log/apache/error_log
> root 29897 c Thu Apr 18 16:14:00 2019
< root 29897 c Thu Apr 18 16:14:00 2019 rc=255
> CMD: cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
> root 26545 c Thu Apr 18 23:58:00 2019
< root 26545 c Thu Apr 18 23:58:00 2019 rc=2
> CMD: cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
> root 3093 c Fri Apr 19 00:01:00 2019
< root 3093 c Fri Apr 19 00:01:00 2019 rc=2
^C
-bash-3.2# ls -l /var/log/apache/error_log
/var/log/apache/error_log: No such file or directory
-bash-3.2#
But if I run command manually, it is able to create
-bash-3.2# cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
-bash-3.2# ls -l /var/log/apache/error_log
lrwxrwxrwx 1 root root 18 Apr 19 00:03 /var/log/apache/error_log -> error_log.20190419
-bash-3.2# rm -f error_log
-bash-3.2#
To test, if cron is working with root, I made another entry of date command
32 00 * * * date>/tmp/date.out
-bash-3.2# tail -f /var/cron/log
< root 20623 c Fri Apr 19 00:20:22 2019
> CMD: date > /tmp/date.out
> root 10651 c Fri Apr 19 00:26:00 2019
< root 10651 c Fri Apr 19 00:26:00 2019
> CMD: cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
> root 12318 c Fri Apr 19 00:27:00 2019
< root 12318 c Fri Apr 19 00:27:00 2019 rc=2
> CMD: cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
> root 13871 c Fri Apr 19 00:28:00 2019
< root 13871 c Fri Apr 19 00:28:00 2019 rc=2
> CMD: cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
> root 23263 c Fri Apr 19 00:31:00 2019
< root 23263 c Fri Apr 19 00:31:00 2019 rc=2
> CMD: date>/tmp/date.out
> root 25056 c Fri Apr 19 00:32:00 2019
< root 25056 c Fri Apr 19 00:32:00 2019
^C
You have new mail in /var/mail/root
-bash-3.2# ls -l /tmp/date.out
-rw-r--r-- 1 root root 29 Apr 19 00:32 /tmp/date.out
-bash-3.2#
Not sure if "rc=2" is giving some indication
RudiC
April 19, 2019, 5:16am
13
It certainly does and might be listed in the Solaris documentation, to which I have no access. cron
jobs send their output - if any - by mail. You seem to have received mail(s). What do they say? You might want to add some debug info to your commands - intersperse some echo
es.
rc=2 means exit status 2.
Look at root's mail with
Here it says in /var/mail/root
Your "cron" job on v911a-proxy1-prod
cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
produced the following output:
sh: syntax error at line 1: `(' unexpected
solaris_1977:
Here it says in /var/mail/root
Your "cron" job on v911a-proxy1-prod
cd /var/log/apache && rm -f error_log && ln -s $(ls -r *error_log.* | head -1) error_log
produced the following output:
sh: syntax error at line 1: `(' unexpected
I am sorry about that. I made the mistake of copying the code from post #10 that you said you were using:
13 16 * * * cd /var/log/apache && ln -s $(ls -r *error_log.* | head -1) error_log
14 16 * * * unlink /var/log/apache/error_log
which used that same construct. But, with a pure Bourne shell from the 1980s being used by cron
on Solaris 10, see what happens if you try:
13 16 * * * cd /var/log/apache && rm -f error_log && ln -s `ls -r *error_log.* | head -1` error_log
Note that this assumes that your error log file names do not contain any IFS characters (usually <space>, <tab>, and <newline>). If they could contain IFS characters you'll need to add double-quotes immediately before the opening back-quote and immediately after the closing back-quote.
1 Like
This worked very well.
Thanks for help and explanation