shell scripting: sweep logfile for a string but ignore certain substrings

I wish to sweep a log file and email an alert if errors are found.  Basic logic is to search the Oracle listener log for strings having a "TNS-" prefix.  If the word count is positive, throw the alert.  Certain TNS strings are benign, therefore we generate a whole lot of garbage email.

The target, then, is to exempt the benign ones -- but my Bash skills aren't up to it,  Can anyone teach me how to count "TNS-" but not include "TNS-12456", etc.?

An example:  

if [ -f $LISTENER_LOG_FILE ]; then
#  if [ `grep "TNS-" $LISTENER_LOG_FILE | wc -l` -ne 0 ]; then
  if [ `grep "TNS-12546" $LISTENER_LOG_FILE | wc -l` -ne 0 ]; then
    echo -e "\nThe $LISTENER_LOG_FILE file contains errors." > $LOG_FILE
    echo -e " " >> $LOG_FILE
    grep "TNS-12546" $LISTENER_LOG_FILE >> $LOG_FILE

Open in new window

LVL 23
DavidSenior Oracle Database AdministratorAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

johnsoneSenior Oracle DBACommented:
What I would do is this:

grep "TNS-" $LISTENER_LOG_FILE | grep -v "TNS-12546" $LISTENER_LOG_FILE | wc -l

That should give you a count ignoring TNS-12546.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Steve WalesSenior Database AdministratorCommented:
Let's say my log file looks like this:

# cat test.log
TNS-12345
TNS-23456
TNS-43215
qwerqwer
wqerwqerqwe
ZZ
ZZ

Open in new window


I only want TNS-43215, I know the other two are benign:

# grep "TNS-" test.log | egrep -v "TNS-12345|TNS-23456"
TNS-43215

Open in new window


Johnsone's answer will exclude one at a time.  Using egrep  you can put a whole bunch of them together separated by pipes.

Or just do this (for cases where there's more than one needed to exclude):

grep "TNS-" test.log | grep -v "TNS-12345" | grep -v "TNS-23456"

Open in new window

0
DavidSenior Oracle Database AdministratorAuthor Commented:
Testing, thank you both for now.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

MikeOM_DBACommented:
Actually you need the script to monitor only for the latest entries after the previous monitoring event.
You can choose one of the many scripts posted in the internet that do this.
0
Steve WalesSenior Database AdministratorCommented:
You could actually even set up your listener.log as an external table and query it from within SQLPLUS.

René Nyffenegger's site has an example of how to do it with the alert log, shouldn't be too hard to tweak it for what you need with the listener.log.

See this page for the full scripting behind it: http://www.adp-gmbh.ch/ora/admin/scripts/read_alert_log.html
0
DavidSenior Oracle Database AdministratorAuthor Commented:
Thanks all, I'll increase and award points, but I'll point out my own solution and a bit of why it works for us.  The solution was to modify two lines.  Keeping to the line numbering in my code snippet, I couldn't reason out why line 5 was commented out in favor of line 6. Then I noticed line 8 is passing the TNS-12546 string into the output file -- as if this were a one-time test or alteration that was never corrected.  I exchanged lines 4 and 5, but then removed the 12546 from line 8. As shown in the code:
if [ -f $LISTENER_LOG_FILE ]; then
 if [ `grep "TNS-" $LISTENER_LOG_FILE | wc -l` -ne 0 ]; then
#  if [ `grep "TNS-12546" $LISTENER_LOG_FILE | wc -l` -ne 0 ]; then
    echo -e "\nThe $LISTENER_LOG_FILE file contains errors." > $LOG_FILE
    echo -e " " >> $LOG_FILE
    grep "[b]TNS-[/b]" $LISTENER_LOG_FILE >> $LOG_FILE

Open in new window

.

Yes, this version displays the TNS-12546 if found, but now I also see the other TNS- errors that were previously masked.

It's a short term victory, because the tech lead expects to migrate from such scripts to the EM event management very soon.

****************
Mike, your comment is good but not relevant in my situation.  We sweep the log every 24 hours, and this error check script runs just prior to the sweep -- so the check job shows the current state of TNS errors daily.  Ideally, someone will triage the root cause and eliminate the errors, but that's another ticket.

Steve, another good idea, but:  my customer is very prohibitive about exposing log files to unnecessary risk.
0
DavidSenior Oracle Database AdministratorAuthor Commented:
I was able to find my own solution, and documented it.  Notice, however, that I distributed my points to the two fellow experts who best assisted my thought process.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Oracle Database

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.