Friday, August 2, 2019

Bash -- Reading the alert log, Writing to the syslog, awk, logger, syslogd

Today, I want to share a bash script that I wrote yesterday.
This kind of a bash script was required in a project, where we needed to read the alert log line by line, and without missing anything, writing all the Oracle alert log messages to the syslog.
(Linux -- /var/log/messages in our case)
After a long time, I found my self writing scripts again. This was fun! :)

I used awk and logger utilities for the read and write operations mainly.
I used bash functions to make the code a bit more understandable.

The things that I do with this script are;

I check my saved counter, which is stored in a file to check where I left (the last line of the Alert log that I read in my last read)
If I find a gap, then I read the gap by using a loop, increment my line counter and save it.
If I find only a single line to be read, then I read it with a single instruction, increment my line counter and save it.
If I find my saved counter and alert log line count are in sync, then I almost don't do anything.
After I read the line or lines of the alert log , I write to syslog (/var/log/messages , using the logger utility through syslogd - using the local0 as a notice)

- Note the following; 
I wrote this script in 30 minutes and I share it with you just to give you an idea.. This kind of a script can be modified to be better.
This script can be modified to include a check pattern or to include a transformation routine before writing the alert log contents to the syslog.
The script can be modified to read the paths and everyting from the variables. 
This kind of a script can be required when our customer wants to see Oracle's alert log messages almost realtime in /var/log/messages.
This kind of a script can be daemonized with a while loop or it can scheduled using crontab.

I m sharing the script below.. I hope you find it useful...

ALERT LOG CHECKER - SYSLOG WRITER

### The scripts starts here
### Function Defitinions

initialize_counters()
{
let last_line=`wc -l /u001/u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log | awk '{print $1}'`;
let saved_line=`cat /root/script_erman/counter_savepoint`;
let check_number=$saved_line+1;
}
read_multiple_lines()
{
/dev/null > /root/script_erman/output > /dev/null 2>&1
let tail_line=$last_line-$saved_line;
for (( c=$tail_line; c>0 ;c-- ))
do
let awk_line=$last_line-$c+1;
read_command=`echo awk NR==$awk_line /u001/u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log;`
$read_command >> /root/script_erman/output
if [ $? -ne 0 ]
then
exit
fi
done
cat /root/script_erman/output | write_to_syslog
}
read_single_line()
{
read_command=`echo awk NR==$last_line /u001/u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log;`
$read_command > /root/script_erman/output
if [ $? -ne 0 ]
then
exit
else
cat /root/script_erman/output | write_to_syslog
fi
}
do_almost_nothing()
{
echo "NO ERRORS found in alert log, no log recorded into the Alert log since the last check" | write_to_syslog
exit
}
write_to_syslog()
{
logger -t oracle/DATABASEALERT -p local0.notice
}
checkpoint_to_savepoint()
{
echo $last_line > /root/script_erman/counter_savepoint
exit
}

### Script's main

initialize_counters
if [ "$last_line" -eq "$check_number" ]
then
read_single_line
checkpoint_to_savepoint
elif [ "$last_line" -lt "$check_number" ]
then
do_almost_nothing
else
read_multiple_lines
checkpoint_to_savepoint
fi

### The scripts ends here

No comments :

Post a Comment

If you will ask a question, please don't comment here..

For your questions, please create an issue into my forum.

Forum Link: http://ermanarslan.blogspot.com.tr/p/forum.html

Register and create an issue in the related category.
I will support you from there.