As I recall, Informix provided a default ALARMPROG script with 7.13 which=
executed when an ALARM condition occurred which is easy to modify to perf=
orm operation(s) you want to occur. - like e-mail or text paging or writin=
g messages to syslog, etc.
I googled and found an example of an event handler written by ALan Chang=
and Art Kagl.
Ken Moskowitz=C2=A0
#! /bin/sh
# This is a shell archive. Type 'sh <file>' to unpack.
echo x - log_full.sh
cat >log_full.sh <<'MKSHAR_EOF'
#!/usr/bin/ksh
(
PROG=3D`basename $0`
USER_LIST=3Dinformix
# BACKUP_CMD=3D"onbar -l"
BACKUP_CMD=3D"ontape -a"
EXIT_STATUS=3D0
EVENT_SEVERITY=3D$1
EVENT_CLASS=3D$2
EVENT_MSG=3D"$3"
EVENT_ADD_TEXT=3D"$4"
EVENT_FILE=3D"$5"
case "$EVENT_CLASS" in
23)=20
# onbar assumes no operator is present,
# so all messages are written to the activity
# log and there shouldn't be any output, but
echo $*=20
# send everything to /dev/null just in case
c=3D1
for b in $3; do
if [[ $c -eq 3 ]]; then logno=3D$b; fi
c=3D$(( c + 1 ))
done
$BACKUP_CMD <<EOF 2>&1 >> /dev/null
n
EOF
EXIT_STATUS=3D$?
mv $INFORMIXDIR/archives/logfile $INFORMIXDIR/archives/logfile.$lo=
gno
touch $INFORMIXDIR/archives/logfile
chmod 660 $INFORMIXDIR/archives/logfile
compress $INFORMIXDIR/archives/logfile.$logno &
;;
# One program is shared by all event alarms. If this ever gets expanded=
to
# handle more than just archive events, uncomment the following:
*)
# EXIT_STATUS=3D1
;;
esac
) >>$INFORMIXDI
R/archives/log_sh.log 2>&1
exit $EXIT_STATUS
MKSHAR_EOF
echo x - README.1st
cat >README.1st <<'MKSHAR_EOF'
=20
Contents of shell archive utils3_ak, submitted by Art S. Kagel:
=20
Version dated: July 1, 1998
=20
------------------------------------------------------------------------=
----
=20
Utility: log_full.sh
Synopsis: Version of Informix log_full.sh sample event script to backup=20
automatically logical logs to disk using ontape -a triggered by the=20
log completed event.
=20
Author(s): Informix and Art S. Kagel
Revision: 1.0
Features Version: 1.0
Version(s) supported: 7.xx
File(s): log_full.sh
Comments:=20
Be sure to adjust the directory and file name of the log archive file
to match the value of the ONCONFIG parameter LTAPEDEV. If the IDS en=
gine=20
is running you will have to use onmonitor to change LTAPEDEV for the=
=20
running instance. You will have to bounce the engine to install this=
=20
script as the event handler (modify the ONCONFIG parameter ALARMPROGR=
AM).
Release Notes:
------------------------------------------------------------------------=
----
=20
Utility: eventalarm
Synopsis: General purpose event alarm handler executable. This currently=
=20
handles several common events which need service or watching. It will=
=20
send email to any number of administrators and if your pager company=
=20
has email support (usually you just have to ask them to enable it) it=
=20
can even email your text pager. This version added support for event
#23 Logical Log Completed. It laun
ches an ontape -a command, assuming=20
the logs will be archive to a disk file, renames the file, and prepare=
s
for the next log backup. Using a simple lock file technique it does=
=20
not attempt to run if it is already running, which can happen during=
=20
heavy activity, allowing the currently running ontape (or the next log=
=20
complete event) to back up the newest log. It uses a configuration=20
file to know where to write it's own log file, how frequently to notif=
y=20
of repeated events (like lock table overflow), to whom to email=20
notices and the command to use to compress logfiles after they are=20
backed up. It reads the log archive file location from the ONCONFIG=
=20
file permitting it to be easily installed on multiple sites without=20
recompiling and permitting the DBA to change the location of the=20
log archive files with onmonitor on the fly. Revision 1.19 added=20
direct support for systems which dump log files to /dev/null. A=20
sample config file is included (eventalarm.cfg).
=20
Author(s): Alan Chang and Art S. Kagel
Revision: 1.22
Features Version: 3.0
Version(s) supported: 7.xx
File(s): eventalarm.c, eventalarm.cfg, readn.c, gservlog.c
Comments: Logs all events. The template of the code treats events differe=
ntly
by severity level (1-5). The code layout makes it easy to add support=
=20
for new events.
If the IDS engine is running you will have to use onmonitor to change
LTAPEDEV for the running instance. You will have to bounce the engine
to install this program as the event handler the first time after
modifying the ONCONFIG parameter ALARMPROGRAM. The program looks for
its configurations file, eventalarm.cfg, in $INFORMIXDIR.
Release Notes: Note that for severities 4 & 5 banners are written to a fi=
le=20
named /tmp/echo.fifo. In our environment this is a system FIFO which=
=20
is constantly being read by a process that echos everything it reads=
=20
from that FIFO to the operators central monitor. I have left this in=
=20
as a suggestion of one way to notify operations of a problem as it is=
=20
occurring. You may want to adjust or remove this mechanism.
Eventalarm.cfg is a sample configuration file.
Readn.c is a function that reads characters until it timesout or reads=
=20
a newline or specified string. It is used to parse the dialog with=20
ontape.
Gservlog is a function that writes a flushed message, preceded by date=
=20
and time, to a log file.
NB: It is not clear, and has not been fully tested, whether the progra=
m
will properly handle being reprompted for an additional tape. The=20
basic state machine loop that reads and parses the output from ontape=
=20
should handle this, but testing was minimal as it is not expected to=
=20
happen since our log files are 100-500MB, the LTAPESIZE is 2GB, and
this program should be executed to archive at most two or three log
files.
Link with readn.c and gservlog.c and -lgen (or whereever your OS/C=20
compiler puts the basename function
):
gcc -O3 -o eventalarm eventalarm.c gservlog.c readn.c -lgen
=20
------------------------------------------------------------------------=
----
Utility: cleanlogs
Synopsis: Use along with eventalarm. Script and crontab entry to clean up=
the=20
LTAPEDEV directory of older logfiles. As configured the crontab entry
runs the program daily at 9AM and the script deletes any logfiles olde=
r
than 7 days. It parses the ONCONFIG file for the location of logfiles=
=20
so it is immune to configuration changes and can be used on multiple=
=20
instances on the same system.
Author: Art S. Kagel
Revision: 1.00
Files: cleanlogs crontab
------------------------------------------------------------------------=
----
MKSHAR_EOF
echo x - eventalarm.c
cat >eventalarm.c <<'MKSHAR_EOF'
/* eventalarm.c - Alarm event program for Informix 7.13+ systems to report
Informix events to operators and Administrators.
*/
/*
RCS Header:
-----------
$Header: /home/kagel/utils/RCS/eventalarm.c,v 1.22 1999/05/12 13:45:52=
kagel Exp $
RCS Log:
--------
$Log: eventalarm.c,v $
* Revision 1.22 1999/05/12 13:45:52 kagel
* Fixed bug causing a core dump if no af file is specified on the command=
line
* in an evergency or fatal event.
*
* Revision 1.21 1999/02/10 15:44:04 kagel
* Changed the execlp() call to launch ontape to use a full path of
* $INFORMIXDIR/bin/ontape. This solves some problem with 7.24UC7 that
* sometimes caused the execlp to fail with errno 2 (no such file or devic=
e).
*=3D2
0Since getenv() returns INFORMIXDIR correctly it is unlikely that the PATH
* is not properly set. Very odd. Anyway this works now.
*
* Revision 1.20 1998/12/22 17:25:23 kagel
* Adjusted initial timeout to 20 seconds to allow for slow ontape startup=
and
* added code to close the pipes and signal ontape to exit on timeout erro=
r
* or when backing up to /dev/null.
*
* Revision 1.19 1998/12/16 16:34:48 kagel
* Added an exit to log archiving if LTAPEDEV =3D=3D '/dev/null.
*
* Revision 1.18 1998/08/14 14:52:06 kagel
* *** empty log message ***
*
* Revision 1.17 1998/08/13 16:12:37 kagel
* Removed dependency on Bloomberg's uid/gid for Informix using getpwnam()=
.
* Updated some comments for IIUG users.
*
* Revision 1.16 1998/07/21 13:54:18 alanc
* adding more information for a gservlog statement.
*
* Revision 1.15 1998/07/20 16:29:38 kagel
* Fixed bug in renaming of a single log archive file.
*
* Revision 1.14 1998/07/17 17:18:04 kagel
* Added configurable compressor and cleaned up configuration defaults.
*
* Revision 1.13 1998/07/17 16:49:30 kagel
* Added support for multiple output archive files for very large logs and
* to handle the case when logs have not been backed up for a while.
* Removed timeout during actual log file archiving to better support larg=
e
* log files and slow systems. Event lock file now removed before gzippin=
g
* the files so another instance of the program c
an backup subsequent logs if
* the compression takes time.
*
* Revision 1.12 1998/07/01 19:53:10 kagel
* emacs eventalarm.c
* Saveing Alan's last changes.
*
* Revision 1.11 1998/06/30 22:26:08 alanc
* fixes something.
*
* Revision 1.10 1998/06/25 18:56:07 kagel
* Last changes. Alan enhanced to handle Logical Log complete by
* archiving log files with ontape -a.
*
* Revision 1.9 1998/06/12 16:25:08 alanc
* *** empty log message ***
*
* Revision 1.8 1997/11/17 15:01:45 kagel
* typeo.
*
* Revision 1.7 1997/11/17 14:57:56 kagel
* Fixed temp string size in attention() and fflush() fclose()/pclose()
* in all message handler routines. These were called even if the output
* file/pipe was not opened successfully.
*
* Revision 1.6 1997/07/14 16:55:58 kagel
* Fixed Class two messages to prevent them from mailing. These are
* informational only (though subclass 23 log completed can be trapped to
* trigger an manual backup of the log).
* Added errno printout if cannot open af (assertion failure) file.
*
* Revision 1.5 1997/07/11 15:21:57 kagel
* Added config file parameters. Fixed core dump problems. Added feature=
s.
* Cleaned up messages logging.
*
* Revision 1.4 1996/10/02 16:46:51 kagel
* Fixes.
*
* Revision 1.3 1996/09/24 18:04:55 kagel
* Fixed situation where no special message is passed. Also removed extra=
neous
* free()/malloc() pairs for temp which only20needs to be allocated once.=
Also
* initialized the argument pointers to NULL.
*
* Revision 1.2 1996/09/24 17:56:54 kagel
* Fixed handling of situation where no af file is passed.
*
*/
static char RCSHeader[] =3D "$Header: /home/kagel/utils/RCS/eventalarm.c,v=
1.22 1999/05/12 13:45:52 kagel Exp $";
static char RCSWhat[] =3D "$What: <@(#) eventalarm.c,v 1.22> $ $Date:=
1999/05/12 13:45:52 $";
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <limits.h>
#include <strings.h>
#include <wait.h>
#include <libgen.h>
#include <pwd.h>
static char *errormsg[] =3D {
"Dummy",
"1. Table failure",
"2. Index failure",
"3. Blob failure",
"4. Chunk is off-line, mirror is active",
"5. DBSpace is off-line",
"6. Internal Subsystem failure",
"7. OnLine Initialization failure",
"8. Physical Restore failed",
"9. Physical Recovery failed",
"10. Logical Recovery failed",
"11. Cannot open Chunk",
"12. Cannot open Dbspace",
"13. Performance Improvement possible",
"14. Database failure.",
"15. Data Replication failure.",
"16. Archive completed.",
"17. Archive aborted.",
"18. Log Backup completed.",
"19. Log Backup aborted.",
"20. Logical Logs are full - Backup is needed.",
"21. OnLine resource overflow",
"22. Long Transaction dete
cted",
"23. Logical Log Complete",
"24. Unable to Allocate Memory"
};
char recipients[2049];
void attention(int eveid, int classid, char *msg, char *spemsg);
void emergency(int eveid, int classid, char *msg, char *spemsg, char *af);
void fatalerror(int eveid, int classid, char *msg, char *spemsg, char *af)=
;
int readn( int fd, char buf[1025], int len, int flag );
int set_timeout( int secs, int usecs );
void gservlog(char *fmt, ...);
extern FILE *GSERVLOG;
extern char *GSPARG;
int main (int argc, char *argv[])
{
int eveseve, eveclassid, i;
char *eveclassmsg =3D NULL, *evespemsg =3D NULL, *afname =3D NULL, *in=
formixdir;
FILE *fil, *cfg, *ef, *f23;
time_t t, ltime;
char config[2049], logfile[2049], tapeprog[1025],
tmpstr[2049], tmpstr2[2049], tmpstr3[2049];
int delay =3D 60, fil2, fds1[2], fds2[2], ret;
char *tok, *tok23;
static char buff[1025], logfile23[1025], old_logfile[1025];
static char logfiles[100][1025], lognum[30], compressor[1025];
char buff23[1024], prompt[20];
struct stat stbuf;=20
int nr, ld, rfd, wfd, nlfiles =3D 0;
pid_t cpid, cpid2, opid;
int oldnum =3D 0;
struct passwd *pwd;
sprintf( config, "%s/eventalarm.cfg", getenv( "INFORMIXDIR" ) );
/* Get configuration file. */
cfg =3D fopen( config, "r" );
/* One day change this from positional to tagged data format. */
if (cfg) {
/* Line 1: Read list of mail recipients. */
=3D2
0 if (fgets( recipients, 2049, cfg ) !=3D (char *)NULL)
recipients[strlen(recipients)-1] =3D (char)0;
else /* Empty file? Default to no email. */
recipients[0] =3D (char)0;
/* Line 2: Read logfile path. This path is for eventalarm to log its
activity */
if (fgets( logfile, 2049, cfg ) !=3D (char *)NULL)
logfile[strlen(logfile)-1] =3D (char)0;
else /* No second line? Default to current directory. */
logfile[0] =3D (char)0;
/* Line3: Read delay between multiple identical event reports
(secs). */
if (fgets( tmpstr, 2049, cfg ) !=3D (char *)NULL) {
tmpstr[strlen(tmpstr)-1] =3D (char)0;
delay =3D atoi( tmpstr );
} else { /* No third line? Default to once a minute. */
delay =3D 60;
}
/* Line4: Read compressor program command line. */
if (fgets( compressor, 2049, cfg ) !=3D (char *)NULL)
compressor[strlen(compressor)-1] =3D (char)0;
else /* No fourth line? Default to gzip. */
strcpy( compressor, "gzip" );
} else {
/* No config file? Set defaults as above. */
recipients[0] =3D (char)0;
logfile[0] =3D (char)0;
delay =3D 60;
strcpy( compressor, "gzip" );
}
if (strlen( recipients ) =3D=3D 0) /* Always send mail to informix.=
*/
strcpy( recipients, "informix" );
if (strlen( logfile ) =3D=3D 0) /* Default path to IDS startup directo=
ry. */
sprintf( logfile, "./%s.log", basename(argv[0]) );
20 if (logfile[strlen(logfile)-1] =3D=3D '/') /* Path only. Default na=
me. */
strcat( logfile, basename(argv[0]) );
fil =3D fopen( logfile, "a" );
GSERVLOG =3D fil;
GSPARG =3D "";
t =3D time( NULL );
/* gservlog( "%s", asctime( localtime( &t ) ) ); */
if ( argc >=3D 6 && *argv[5] )
{
eveseve =3D atoi(argv[1]);
eveclassid =3D atoi(argv[2]);
eveclassmsg =3D (char *) malloc(strlen(argv[3])+1);
evespemsg =3D (char *) malloc(strlen(argv[4])+1);
strcpy(eveclassmsg, argv[3]);
strcpy(evespemsg, argv[4]);
afname =3D (char *) malloc(strlen(argv[5])+1);
strcpy(afname, argv[5]);
} else if (argc >=3D 5)
{
eveseve =3D atoi(argv[1]);
eveclassid =3D atoi(argv[2]);
eveclassmsg =3D (char *) malloc(strlen(argv[3])+1);
evespemsg =3D (char *) malloc(strlen(argv[4])+1);
strcpy(eveclassmsg, argv[3]);
strcpy(evespemsg, argv[4]);
} else if (argc >=3D 4)
{
eveseve =3D atoi(argv[1]);
eveclassid =3D atoi(argv[2]);
eveclassmsg =3D (char *) malloc(strlen(argv[3])+1);
strcpy(eveclassmsg, argv[3]);
}
=20
switch(eveseve){
case 1:
gservlog( "Not noteworthy event: Severity=3D%d, Class=3D%d.\n",
eveseve,
eveclassid );
break;
case 2:
gservlog("NonFatal Event: Severity=3D%d, Class=3D%d.\n",
eveseve,
eveclassid );
break;
case 3:
gservlog("Attention Event: Severity=3D%d, Class=3D%d.\n",
eveseve,
eveclassid );
break;
case 4:
gservlog("Emergency Event: Severity=3D%d, Class=3D%d.\n
",
eveseve,
eveclassid );
system("banner INFORMIX 'MAY BE' DOWN >> /tmp/echo.fifo");
break;
case 5:
gservlog("Fatal Event: Severity=3D%d, Class=3D%d.\n",
eveseve,
eveclassid );
system("banner INFORMIX IS DOWN >> /tmp/echo.fifo");
system("/usr/bin/echo INFORMIX IS DOWN >> /tmp/echo.fifo");
break;
default:
gservlog("Unknown Severity ID %d, Class Id %d\n", eveseve,
eveclassid);
break;
}
gservlog( "%d args passed\n", argc );
for (i=3D0;i<argc;i++)
gservlog( "Arg %d: \"%s\".\n", i, argv[i] );
fflush( fil );
switch(eveclassid) {
case 1: /* Table Failure. */
case 2: /* Index Failure. */
case 3: /* Blob Failure. */
case 4: /* Chunk is offline. */
case 5: /* DBspace is offline. */
case 6: /* Internal Subsystem Failure. */
case 7: /* Online initialization Failure. */
case 8: /* Physical Restore failed. */
case 9: /* Physical Recovery failed. */
case 10: /* Logical Recovery failed. */
case 11: /* Cannot open chunk. */
case 12: /* Cannot open DBspace. */
case 13: /* Performance Improvement possible! */
case 14: /* Database failure. */
case 15: /* Data Replication failure. */
case 16: /* Archive Completed. */
case 17: /* Archive Aborted. */
case 20: /* Logical Logs are full. Backup required. */
case 22
: /* Long Transaction detected. */
case 24: /* Unable to allocate memory. */
if (eveseve > 4)
fatalerror( eveseve, eveclassid, eveclassmsg, evespemsg, afname );
else if (eveseve > 3)
emergency( eveseve, eveclassid, eveclassmsg, evespemsg, afname );
else if (eveseve > 2)
attention( eveseve, eveclassid, eveclassmsg, evespemsg );
break;
case 21: /* Online resource overflow. */
sprintf( tmpstr, "event.S%d.C%d", eveseve, eveclassid );
ef =3D fopen( tmpstr, "r+" );
if (!ef) {
ltime =3D 0;
ef =3D fopen( tmpstr, "w" );
if (!ef) {
gservlog( "Cannot open timer file for this event!\n" );
}
} else
fread( <ime, sizeof ltime, 1, ef );
if (!ef || (ltime + delay) < t) { /* Only message once for each period=
. */
if (eveseve > 4)
fatalerror(eveseve,
eveclassid,
eveclassmsg,
evespemsg,
afname );
else if (eveseve > 3)
emergency( eveseve,
eveclassid,
eveclassmsg,
evespemsg,
afname );
else if (eveseve > 2)
attention( eveseve, eveclassid, eveclassmsg, evespemsg );
fseek( ef, 0, SEEK_SET );
fwrite( &t, sizeof t, 1, ef );
sprintf( tmpstr,
"'(onstat -k -g ses; nps -e -o uname,pid,ppid,pgid,"
"sid,nlwp,cpu,dglstate,stime,time,args)>>onstat.k.ses.%s'",
getpid() );
tmpstr[st
rlen(tmpstr)] =3D '\0';
system( tmpstr ); /* Let's catch the culprit. */
}
fflush( ef );
fclose( ef );
break;
case 23: /* Logical Log Completed. */
sprintf( tmpstr2, "event.S%d.C%d", eveseve, eveclassid );
strcpy(tmpstr3, tmpstr2);
opid =3D getpid();
fil2 =3D open( tmpstr2, O_CREAT|O_EXCL|O_RDWR, 0600);
if (fil2 =3D=3D -1) {
/* There may be an old lockfile left around. Cleanup. */
if (errno =3D=3D EEXIST) {
errno =3D 0;
fil2 =3D open( tmpstr2, O_RDWR, 0600);
}
if (errno && errno !=3D EPERM) {
gservlog( "Removing old lock file.\n" );
unlink( tmpstr2 );
fil2 =3D open( tmpstr2, O_RDWR|O_CREAT, 0600);
if (errno) {
gservlog( "Could not recreate lock file. /n " );
return 6;
}
pwrite(fil2, &opid, 4, 0 );
} else if (errno =3D=3D EPERM) {
gservlog( "No permissions on lockfile: %s.\n", tmpstr2 );
return 7;
} else if (pread( fil2, &opid, 4, 0 ) =3D=3D 0 ||
(ret =3D kill(opid,0)) =3D=3D 0 || /* Is this pid still there? */
(ret =3D=3D -1 && errno =3D=3D EPERM))
{
gservlog("ontape is already running.\n");
close( fil2 );
break;
}
}
strncpy(buff, eveclassmsg, 1024); =20
buff[1023] =3D (char)0;
tok =3D strtok(buff, " ");
tok =3D strtok(NULL, " ");
tok =3D strtok
(NULL, " ");
strcpy( lognum, tok );
/* Open two uni-directional pipes for communication between parent and
child. */
if (pipe(fds1) < 0) {
fprintf(stderr, "Pipe 1 open failed! Errno=3D%d.\n", errno );
exit(9);
}
if (pipe(fds2) < 0) {
fprintf(stderr, "Pipe 2 open failed! Errno=3D%d.\n", errno );
exit(9);
}
if ((cpid =3D fork()) =3D=3D 0) {
/* Child code. */
/* Make our two uni-directional pipes into a bi-directional pipe,=
=20
hook it into stdin/stdout and launch ontape -a */
close(0); /* Close stdin */
dup( fds1[0] ); /* Make pipe file 0 stdin */
close(1); /* Close stdout */
dup( fds2[1] ); /* Make pipe file 1 stdout */
close(2); /* Close stderr */
dup( fds2[1] ); /* Make pipe file 1 stderr also */
/* Exec ontape */
informixdir =3D getenv( "INFORMIXDIR" );
sprintf( tapeprog, "%s/bin/ontape", informixdir );
execlp( tapeprog, "ontape", "-a", (char *)NULL );
gservlog( "Exec of ontape failed! Errno=3D%d.\n", errno );
exit(8);
} else {
/* Parent code. */
opid =3D getpid();
pwrite( fil2, &opid, 4, 0 );
gservlog( "Ontape -a started as pid: %d\n", cpid );
/* Hook parent into pipe and create a stream from the output fd fo=
r
20 ease of use. The parent uses the opposite side of each pi=
pe
from that used by the child. */
rfd =3D fds2[0]; /* File descriptor for reading */
wfd =3D fds1[1]; /* File descriptor for writing */
f23 =3D fdopen( wfd, "w" ); /* Stream for writing */
/* Get the Informix uid and gid, in case the engine is running as=
root. */
pwd =3D getpwnam( "informix" );
set_timeout( 20, 0 );
strcpy(prompt, " ... ");
while (1){
strcpy( buff23, prompt );
nr =3D readn( rfd, buff23, 1024, 3);
if (nr =3D=3D LONG_MIN) {
gservlog("Time out\n");
close( 0 );
close( 1 );
close( 2 );
close( fds1[0] );
close( fds1[1] );
close( fds2[0] );
close( fds2[1] );
kill( cpid, SIGPIPE );
kill( cpid, SIGTERM );
return 5;
}
else if (nr < 0) {
nr =3D nr * -1;
gservlog("Time out after %d read\n", nr);
}
buff23[nr] =3D (char)0;
gservlog( buff23 );
if (buff23[nr-1] !=3D '\n') {
fputs( "\n", GSERVLOG );
fflush( GSERVLOG );
}
tok23 =3D strtok(buff23, " ");
if (strcmp(tok23, "Please")=3D=3D0) {
tok23 =3D strtok(NULL, " ");
if (strcmp(tok23, "mount" )=3D=3D0) {
tok23 =3D strtok(NULL, " " );
tok23 =3D strtok(NUL
L, " " );
tok23 =3D strtok(NULL, " " );
tok23 =3D strtok(NULL, " " );
strcpy( logfile23, tok23 );
if (strcmp( logfile23, "/dev/null" ) =3D=3D 0)
{
gservlog( " Logging being dumped to "
"/dev/null. Logfile %d "
"discarded.\n",
lognum );
close( 0 );
close( 1 );
close( 2 );
close( fds1[0] );
close( fds1[1] );
close( fds2[0] );
close( fds2[1] );
kill( cpid, SIGPIPE );
kill( cpid, SIGTERM );
exit( 0 );
} =20
gservlog( " Archiving logfile %s to: %s\n",
lognum,
logfile23 );
ld=3Dopen(logfile23, O_CREAT);
close(ld);
if ((stat(logfile23, &stbuf)=3D=3D0)
&&(stbuf.st_size))
{
oldnum =3D oldnum + 1;
sprintf( old_logfile,
"%s.old%d",
logfile23,
oldnum);
errno =3D 0;
while ((link(logfile23, old_logfile)) =3D=3D -1
&& ( errno =3D=3D EEXIST ))
{
oldnum =3D oldnum + 1;
sprintf( old_logfile,
"%s.old%d",
logfile23,
oldnum);
errno =3D 0;
}
if (errno) {
gservlog("file %s can't be renamed"
", errno =3D %d\n",
09 logfile23,
errno);
errno =3D 0;
}
unlink(logfile23);
ld=3Dopen(logfile23, O_CREAT);
close(ld);
}
chmod(logfile23, 0660 ); /* chmod 660 */
/* chown/chgrp file to informix in case */
/* engine started as root. */
chown(logfile23,pwd->pw_uid,pwd->pw_gid);
fputs( "\n", f23);
fflush(f23);
strcpy(prompt, "? (y/n) " );
/* Disable timeout until logs are backed
up. */
set_timeout( 0, 0 );
}
}
else if (strcmp(tok23, "Tape" )=3D=3D0){
/* Archive file is full, rename and create a new one. */
sprintf( logfiles[nlfiles],
"%s.%s.%d",
logfile23,
lognum,
nlfiles+1 );
link( logfile23, logfiles[nlfiles] );
unlink( logfile23 );
gservlog( "Renamed %s to %s.\n",
logfile23,
logfiles[nlfiles] );
close( open( logfile23, O_CREAT ) );
chmod( logfile23, 0660 );
strcpy(prompt, " ... ");
nlfiles++;
}
else if (strcmp(tok23, "Do")=3D=3D0){
fputs( "n\n", f23);
fflush(f23);
gservlog("n\n");
strcpy( prompt, "Program over.\n" );
}
else if (strcmp( tok23, "Program" )=3D=3D0) {
break;
}
}
/* Rename the last log archive file. */
=3D2
0 if (nlfiles) /* If more than one file, give this the next gen # */
sprintf( logfiles[nlfiles],
"%s.%s.%d",
logfile23,
lognum,
nlfiles+1 );
else /* Otherwise just append the log number. */
sprintf( logfiles[nlfiles], "%s.%s", logfile23, lognum );
link( logfile23, logfiles[nlfiles] );
unlink( logfile23 );
gservlog( "Renamed %s to %s.\n", logfile23, logfiles[nlfiles] );
/* Set up log archive file for the next run. */
close( open( logfile23, O_CREAT ) );
chmod( logfile23, 0660 );
/* Release the lock file so another log event can startup. */
unlink(tmpstr3);
/* Compress all logfiles. */
for (; nlfiles>=3D0;nlfiles--) {
sprintf( tmpstr2, "%s %s &", compressor, logfiles[nlfiles] );
gservlog("%s\n",tmpstr2);
system( tmpstr2 );
}
}
close( fil2 );
break;
default:
if (eveclassid > 24 && eveseve > 2)
attention( eveseve, eveclassid, eveclassmsg, evespemsg );
break;
}
gservlog( "\n" ); /* Force an empty line to the log. */
errno =3D 0;
if ((cpid2 =3D waitpid(cpid, NULL, 0)) > 0)
gservlog( "Child status! Errno=3D%d.\n", errno );
fflush( fil );
fclose( fil );
exit(0);
}
void attention(int eveid, int classid, char *msg, char *spemsg)
{
FILE *f;
int sz, sz1, sz2;
static char *temp;
=3D2
0 sz =3D 256 + ((sz1 =3D strlen(msg)) > (sz2 =3D strlen(spemsg)) ? sz1=
: sz2);
temp =3D (char *) malloc(sz);
sprintf( temp, "mailx -s \"%s\" %s", msg, recipients );
temp[strlen(temp)] =3D '\0';
f =3D popen(temp, "w");=20
if (f) {
sprintf(temp, "severity id =3D %d, classid =3D %d, msg =3D %s\n", evei=
d,=20
classid, msg);
temp[strlen(temp)] =3D '\0';
fputs(temp, f);
if (spemsg) {
sprintf(temp, "special msg =3D %s\n", spemsg);
temp[strlen(temp)] =3D '\0';
fputs(temp, f);
}
fflush( f );
pclose(f);
}
free(temp);
}
void emergency(int eveid, int classid, char *msg, char *spemsg, char* afna=
me)
{
FILE *f, *ofp;
char c;
static char temp[1025];
=20
sprintf( temp, "mailx -s \"%s\" %s", msg, recipients );
f =3D popen(temp, "w");=20
if (f) {
fprintf( f, "severity id =3D %d\n classid =3D %d\n", eveid, classid=
);
if (msg)
fprintf( f, "msg =3D %s\n", msg);
if (spemsg) {
fprintf( f, "special msg =3D %s\n", spemsg );
}
if (afname) {
fprintf( f, "See Also File %s's Contents are:\n", afname );
fprintf( f, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n\n");
if ((ofp =3D fopen(afname, "r")) =3D=3D NULL) {
gservlog( "See Also File mode error, See Also File name =3D %s(%d)=
\n",
afname,
errno );
fprintf( f,
"See Also File mode20error, See Also File name =3D %s(%d)\n",
afname,
errno );
} else
while ((c =3D getc(ofp)) !=3D EOF)
putc(c, f);
} else {
gservlog( "No See Also File\n" );
fprintf( f, "No See Also File\n" );
}
fflush( f );
pclose(f);
}
}
void fatalerror(int eveid, int classid, char *msg, char *spemsg, char* afn=
ame)
{
FILE *f, *ofp;
char c;
static char temp[1025];
sprintf( temp, "mailx -s \"%s\" %s", msg, recipients );
f =3D popen(temp, "w");=20
if (f) {
fprintf( f, "severity id =3D %d\n classid =3D %d\n", eveid, classid=
);
if (msg)
fprintf( f, "msg =3D %s\n", msg);
if (spemsg) {
fprintf( f, "special msg =3D %s\n", spemsg );
}
if (afname) {
fprintf( f, "See Also File %s's Contents are:\n", afname );
fprintf( f, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n\n");
if ((ofp =3D fopen(afname, "r")) =3D=3D NULL) {
gservlog( "See Also File mode error, See Also File name =3D %s(%d)=
\n",
afname,
errno );
fprintf( f,
"See Also File mode error, See Also File name =3D %s(%d)\n",
afname,
errno );
} else
while ((c =3D getc(ofp)) !=3D EOF)
putc(c, f);
} else {
gservlog( "No See Also File\n" );
fprintf( f, "No See Also File\n" );
}
fflush( f );
pclose(f);
=3D2
0}
}
MKSHAR_EOF
echo x - eventalarm.cfg
cat >eventalarm.cfg <<'MKSHAR_EOF'
informix infadminstrator@workstation 123456@skypage.com
/tmp/eventalarm.echo
1800
gzip -1
MKSHAR_EOF
echo x - gservlog.c
cat >gservlog.c <<'MKSHAR_EOF'
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
FILE *GSERVLOG =3D stderr;
char *GSPARG =3D "Unknown";
void gservlog(char *fmt, ...)
{
va_list args;
static char *mon[] =3D {"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"};
long x =3D time(NULL);
struct tm *tml;
=20
tml =3D localtime(&x);
lockf(fileno(GSERVLOG),F_LOCK,0);
fprintf(GSERVLOG,"%s %.2d %.2d:%.2d:%.2d %s:",mon[tml->tm_mon],
tml->tm_mday,tml->tm_hour,tml->tm_min,tml->tm_sec,GSPARG);
va_start(args,fmt);
vfprintf(GSERVLOG,fmt,args);
va_end(args);
rewind(GSERVLOG);
lockf(fileno(GSERVLOG),F_ULOCK,0);
}
MKSHAR_EOF
echo x - readn.c
cat >readn.c <<'MKSHAR_EOF'
/* readn.c - Non-blocking read function. Options, depending on the value=
of
* flag to behave like fgets, similarly with an arbritrary EOR string, or=
after
* a fixed length. Timeouts are supported. =20
*/
/*
RCS Header:
-----------
$Header: /bb/source/db/mstrserv/RCS/readn.c,v 1.1 1998/07/17 14:55:10=
kagel Exp $
RCS Log:
--------
$Log: readn.c,v $
* Revision 1.1 1998/07/17 14:55:10 kagel
* Initial revision
*
*/
static char RCSHeader[] =3D "$Header: /bb/source/db/mstrserv/RCS/readn.c,v=
1.1 1998/07/17 14:55:10 ka
gel Exp $";
static char RCSWhat[] =3D "$What: <@(#) readn.c,v 1.1> $ $Date: 1998/=
07/17 14:55:10 $";
static char RCSCompile[] =3D "$cc: " __FILE__ " " __DATE__ " " __TIME__ "=
$";
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/errno.h>
#include <limits.h>
#define FEXPNL 1
#define FEXPST 2
#define FREQRD 4
extern int errno;
int readn_errno =3D 0;
static int timeout_secs =3D 10;
static int timeout_usec =3D 0;
void set_timeout( int secs, int usec ) {
timeout_secs =3D secs >=3D 0 ? secs : timeout_secs;
timeout_usec =3D usec >=3D 0 ? usec : timeout_usec;
if (timeout_usec > 1000000) {
timeout_secs +=3D (timeout_usec / 1000000);
timeout_usec %=3D 1000000;
}
}
int readn( int fd, char *buf, int len, int flag )
{
char *ptr =3D buf, EndOfRec[1024];
long nread =3D 0, nready=3D0, nleft =3D len, tread =3D 0, nl=3D0, str=
=3D0, reqd=3D0, adj;
fd_set readfds;
long maxfd =3D fd + 1;
struct timeval starttime, currtime, maxtime;
=20
readn_errno =3D 0;
if (flag & FEXPNL) {
nl=3D1;
}
if (flag & FEXPST) {
str=3D1;
strcpy( EndOfRec, buf );
adj =3D strlen( EndOfRec );
}
if (flag & FREQRD)
reqd=3D1;
errno =3D 0;
signal( SIGPIPE, SIG_IGN );
FD_ZERO( &readfds );
FD_SET( fd, &readfds );
if (timeout_secs || timeout
_usec) {
maxtime.tv_sec =3D timeout_secs;
maxtime.tv_usec =3D timeout_usec;
gettimeofday( &starttime, NULL );
currtime.tv_sec =3D starttime.tv_sec;
currtime.tv_usec =3D starttime.tv_usec;
}
=20
while (1) {
if (nready && FD_ISSET( fd, &readfds )) {
nread =3D read(fd, ptr, 1);
if ((ssize_t)nread < 0
&& (errno !=3D EAGAIN && errno !=3D EWOULDBLOCK))
{
return (ssize_t)LONG_MIN; /* error, return HUGE negative=
*/
} else if ((ssize_t)nread < 0)
nread =3D 0;
nleft -=3D nread;
tread +=3D nread;
ptr +=3D nread;
*ptr =3D (char)0;
if (nleft =3D=3D 0)
break;
if (nl && *(ptr-nread) =3D=3D '\n')
break;
if (str && strncmp( EndOfRec, (ptr-adj), adj ) =3D=3D 0)
break;
}
if (timeout_secs || timeout_usec) {
maxtime.tv_sec -=3D (currtime.tv_sec - starttime.tv_sec);
maxtime.tv_usec -=3D (currtime.tv_usec - starttime.tv_usec);
if (maxtime.tv_usec < 0) {
maxtime.tv_sec--;
maxtime.tv_usec +=3D 100000
0;
}
if (maxtime.tv_sec < 0
|| (maxtime.tv_sec =3D=3D 0 && maxtime.tv_usec <=3D 0)) {
readn_errno =3D -6;
if (tread) {
return (-1 * (ssize_t)tread);
} else
return LONG_MIN;
}
starttime.tv_sec =3D currtime.tv_sec;
starttime.tv_usec =3D currtime.tv_usec;
}
FD_ZERO( &readfds );
FD_SET( fd, &readfds );
nready =3D select( fd + 1, &readfds, NULL, NULL, &maxtime );
if (timeout_secs || timeout_usec)
gettimeofday( &currtime, NULL );
}
return tread;
}
MKSHAR_EOF
echo x - crontab
cat >crontab <<'MKSHAR_EOF'
#########################################
# Clean up old logfile archive files #
#########################################
#
0 9 * * * /bb/bin/informix/bin/cleanlogs
MKSHAR_EOF
echo x - cleanlogs
cat >cleanlogs <<'MKSHAR_EOF'
#! /usr/bin/ksh
. /usr/bin/informix.7.0 # Script to set up Informix environment.
# Really just need INFORMIXDIR and ONCONFIG here.
cd `awk '/LTAPEDEV/{nf=3Dsplit($2,a,"/");for (i=3D1;i<nf;i++) printf "/%s"=
, a[i];}' $INFORMIXDIR/etc/$ONCONFIG`
touch -t `date +'%Y|%m|%d|%H|%M|%S'|
awk 'BEGIN{FS=3D"|";}{y=3D$1;m=3D$2;d=3D$3;d-=3D7;if (d<=3D0) {m-=3D1;d+=
=3D30;}if (m<=3D0) {y-=3D1;m=3D12;} printf "%4.4d%02.2d%02.2d%02.2d%02.2d.=
%02.2d", y, m, d,$4,$5,$6;}'` tagfile
find . -name 'logfile.*' ! -newer tagfile -exec rm -f {} \;
MKSHAR_EOF
Ken
-----Original Message-----
From: Doug Lawry <lawry@nildram.co.uk>
To: admin-tools@iiug.org
Sent: Thu, Sep 17, 2009 12:47 pm
Subject: Re: IDS 7.13 Monitoring tool [3318]
See video demos at www.serverstudio.co.uk=20
Regards,=20
Doug Lawry=20
--------------------------------------------------=20
From: "DEEPAK JOSHI" <djoshih@hotmail.com>=20
Sent: Thursday, September 17, 2009 3:29 PM=20
To: <admin-tools@iiug.org>=20
Subject: IDS 7.13 Monitoring tool [3317]=20
Is there any event ALARM program comes with informix 7.13 for monitoring=
=20
Database server.=20
What are the software/application that I can use to monitor our Database=
=20
server health which is running on HP-UX 10.01. Please help me.=20
**************************************************************************=
*****=20
Forum Note: Use "Reply" to post a response in the discussion forum.=20
**************************************************************************=
*****=20
Forum Note: Use "Reply" to post a response in the discussion forum.=20
=20