i want to tail log file with grep and sent it via mail like:
tail -f /var/log/foo.log | grep error | mail -s subject [email protected]
how can i do this?
i want to tail log file with grep and sent it via mail like:
tail -f /var/log/foo.log | grep error | mail -s subject [email protected]
how can i do this?
You want to send an email when emailing errors occur? That might fail ;)
You can however try something like this:
tail -f $log |
grep --line-buffered error |
while read line
do
echo "$line" | mail -s subject "$email"
done
Which for every line in the grep output sends an email.
Run above shell script with
nohup ./monitor.sh &
so it will keep running in the background.
&
, &&
and ||
) –
Unfetter I'll have a go at this. Perhaps I'll learn something if my icky bash code gets scrutinised. There is a chance there are already a gazillion solutions to do this, but I am not going to find out, as I am sure you have trawled the depths and widths of the cyberocean. It sounds like what you want can be separated into two bits: 1) at regular intervals obtain the 'latest tail' of the file, 2) if the latest tail actually exists, send it by e-mail. For the regular intervals in 1), use cron. For obtaining the latest tail in 2), you'll have to keep track of the file size. The bash script below does that - it's a solution to 2) that can be invoked by cron. It uses the cached file size to compute the chunk of the file it needs to mail. Note that for a file myfile another file .offset.myfile is created. Also, the script does not allow path components in the file name. Rewrite, or fix it in the invocation [e.g. (cd /foo/bar && segtail.sh zut), assuming it is called segtail.sh ].
#!/usr/local/bin/bash
file=$1
size=0
offset=0
if [[ $file =~ / ]]; then
echo "$0 does not accept path components in the file name" 2>&1
exit 1
fi
if [[ -e .offset.$file ]]; then
offset=$(<".offset.$file")
fi
if [[ -e $file ]]; then
size=$(stat -c "%s" "$file") # this assumes GNU stat, possibly present as gstat. CHECK!
# (gstat can also be Ganglias Status tool - careful).
fi
if (( $size < $offset )); then # file might have been reduced in size
echo "reset offset to zero" 2>&1
offset=0
fi
echo $size > ".offset.$file"
if [[ -e $file && $size -gt $offset ]]; then
tail -c +$(($offset+1)) "$file" | head -c $(($size - $offset)) | mail -s "tail $file" foo@bar
fi
env
. The output of stat
is highly variable between systems and versions(!). Presuming recent GNU stat, try -c to solve this and avoid the need to parse. –
Ret cat
needed: offset=$(<.offset.$file)
. The second part of if [[ -e $file && $size > $offset ]]
is an lexical comparison so it won't do what you expect if, for example, $size
== 10 and $offset
== 2. Use this instead: if [[ -e $file ]] && (($size > $offset))
. You can omit dollar signs in most cases inside (())
and $(())
. –
Rhaetia How about:
mail -s "catalina.out errors" [email protected] < grep ERROR catalina.out
I use a 1-liner in my cronjob running every 60 minutes, checking if the file has changed within the last 60 minutes. If so, the last 3 lines of the log file are sent to me.
log_file=$(find /var/log/mylog.log -mmin -60) && [[ -n "$log_file" ]] && tail -n 3 "$log_file" | mail -s "Alert mylog" [email protected]
If you want to send the last 3 lines containing the word "ERROR", like requested by the op, you can modify this as follows:
log_file=$(find /var/log/mylog.log -mmin -60) && [[ -n "$log_file" ]] && grep "ERROR" "$log_file" | tail -n 3 | mail -s "Alert mylog" [email protected]
© 2022 - 2024 — McMap. All rights reserved.
print('Foo');
and I want it to print 'Foo'. How do I do that?" What exactly is your question? – Paralleltail
-f as this will continually follow the bottom of the file.grep
doesn't tail logs, either. What is the problem that you are trying to solve? – Coalescetail -f .. | grep ...
is to output appended data as the file grow and with use of grep, it only print append lines that match only – Tardy