Hi SaurabhSri
It looks like you are working towards a viable solution here. You haven't mentioned where you are stuck, which makes it a hard to determine what advice to give.
The one problem I see is that your grep command is wrong. Grep is supposed to find lines in a file. So in your case, grep is assuming that $out is a filename, not a
string to match on. The easiest change to this would be:
You will notice that I removed the -l switch from your grep statement. The -l switch tells grep to list the filename the string was found in. But we don't have a filename - we are looking at the $out variable, so -l makes no sense.
That should get your script working, however since we are looking at the grep command, some other suggestions for you:
The -w option specifies to match whole words only. Given that you are already looking for complex strings I doubt this is necessary. If you were searching for the
word "the", you would probably want to use -w so that you don't match on "ano
ther" or "
theme". But it is highly unlikely that "weblogic.jms.common.LostServerException" is a part of a larger word. So although the -w switch only adds a little bit of extra work, why not save yourself that effort? The script should run the same without it.
Since you are ignoring the output of the grep statement, why not specify the -q switch (quiet mode)? That way you will not get any standard output and can therefore remove the "> /dev/null" redirect of standard output.
Other than that, your script does appear to do what it is designed to do. There is one bit that I find questionable - you are only looking at the very last line of the log file to see if the error occurs. Personally I find that it is rare for me to be so lucky as to find the message I need on the last line (perhaps you have written your application such that this is the last line that ever gets logged, in which case this doesn't matter). Normally though, I work on the assumption that there are always 100 good lines in a log file, and just look for the error in the last 100 lines - if necessary, I might add some backoff capability (for example, track what time I saw the error, and don't report new errors until I see good log messages after the bad log messages). Anyway, this is getting a bit away from your problem.
As I said at the start, your script looks fine (except for the grep issue). It is not the way I would write it, but the old adage is correct: give a problem to 2 programmers and you will get at least 3 different ways to solve it.
So I assume that you are stuck working out how to email something out.
Assuming you have sendmail set up correctly on your system, you can simply use the
mail command to send out details. Something as simple as:
That should send a message to the person that will look something like:
Now, as I've said twice before, your script is reasonable. But some things I think might be better (feel free to ignore them):
Personally I prefer any changeable variables to all be at the top of the script. So I would start my script as: <pre>err1="weblogic.jms.common.LostServerException"
err2="java.io.EOFException"
echo "ERRORS :- $err1 $err2"
LOG_PREFIX="IMSA-"
LOG_DATE_FORMAT="%Y-%m-%d"
LOG_SUFFIX=".log"
</pre> I personally prefer to put curly braces around all variables that are to be expanded. So: myDate=`date "+${LOG_DATE_FORMAT}"` In most cases it is not needed. So $LOG_DATE_FORMAT will work just as well as ${LOG_DATE_FORMAT}. But in some cases the shell won't be able to determine where your variable name ends, and it can be a pain to try and debug. Putting the braces in makes it explicit.
You do not need to echo each variable that you want to concatenate into another variable. If I were building the "myFile" variable I would use: myFile="${LOG_PREFIX}${myDate}${LOG_SUFFIX}" This, by the way, is one place where there are (at least) three ways of building the string, and my way only has one set of quotes, but this requires the curly braces. A similar concept without the curly braces would be:
myFile="$LOG_PREFIX""$myDate""$LOG_SUFFIX" So now we have 3 ways of building the string: your way, my preferred way, and an alternate way. See what I mean about ask 2 programmers how to do something and you will get at least 3 solutions?
None of them are necessarily wrong, so just choose which one you like best.
As a general rule, it is generally considered undesirable to spawn more processes than necessary. In your version, you had: myFile="`echo "IMSA-"``echo $myDate``echo ".log"`" This, in theory, would have spawned 3 instances of the "echo" command. In practice this is probably not a problem as you are not doing any heavy processing with the processes you are spawning. I am not entirely sure if extra processes would be spawned in this particular instance anyway, as most shells have "echo" as a built in command.
You are going to have 2 identical blocks to search for each of the errors. One alternative is to use extended regular expressions in grep so you can search for both at once. Something like: echo $out | egrep -q "${err1}|${err2}" So now we are searching for both in a single pass. Since we are only looking at a single line, this is not a big deal, but if you were looking for the error in the last 100 lines of the log file, then it will save you going through those lines twice (plus it means there is only block of code looking for the error).
An alternative would be to add a function that could be called to look for each error. That is a larger subject, so I'll not go into that here. The email command I gave had very little information in the body of the email - just the error. Assuming that the error in your log file may be preceded by some contextual information that could be useful in diagnosing the problem, you could try including that in the email. Something like: egrep -B 10 "${err1}|${err2}" ${myFile} | mail -s "Error in ${myFile}" abc@domain.com The email will look ugly
but it may be more useful for diagnostic purposes.
So - does any of this help? Or were you having some other problem that I haven't even noticed?
Regards, Andrew