Index: final-hacka-pcp-2.5.99/src/pmie/src/act.sk =================================================================== --- final-hacka-pcp-2.5.99.orig/src/pmie/src/act.sk 2006-11-27 10:00:42.884279500 +1100 +++ final-hacka-pcp-2.5.99/src/pmie/src/act.sk 2006-11-30 11:19:55.637939250 +1100 @@ -1,5 +1,6 @@ /* * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved. + * Portions copyright (c) 2006 Aconex. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -279,6 +280,30 @@ actPrint(Expr *x) /* + * operator: actStomp + */ +void +actStomp(Expr *x) +{ + Expr *arg1 = x->arg1; + Expr *arg2 = x->arg2; + + if ((arg2 == NULL) || + (x->smpls[0].stamp == 0) || + (now >= *(RealTime *)arg2->ring + x->smpls[0].stamp)) + { + EVALARG(arg1) + x->smpls[0].stamp = now; + if (stompSend((const char *)arg1->ring) != 0) + *(Truth *)x->ring = FALSE; + else + *(Truth *)x->ring = TRUE; + perf->actions++; + } +} + + +/* * fake actions for archive mode */ void Index: final-hacka-pcp-2.5.99/src/pmie/src/dstruct.h =================================================================== --- final-hacka-pcp-2.5.99.orig/src/pmie/src/dstruct.h 2006-11-27 10:00:42.888279750 +1100 +++ final-hacka-pcp-2.5.99/src/pmie/src/dstruct.h 2006-11-27 10:02:35.063290250 +1100 @@ -298,6 +298,7 @@ typedef int Op; #define ACT_SYSLOG 74 #define ACT_PRINT 75 #define ACT_ARG 76 +#define ACT_STOMP 77 /* no operation (extension) */ #define NOP 80 /* dereferenced variable */ Index: final-hacka-pcp-2.5.99/src/pmie/src/grammar.y =================================================================== --- final-hacka-pcp-2.5.99.orig/src/pmie/src/grammar.y 2006-11-27 10:00:42.916281500 +1100 +++ final-hacka-pcp-2.5.99/src/pmie/src/grammar.y 2006-11-30 11:20:08.806762250 +1100 @@ -3,6 +3,7 @@ *********************************************************************** * * Copyright (c) 1995 Silicon Graphics, Inc. All Rights Reserved. + * Portions copyright (c) 2006 Aconex. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -30,6 +31,7 @@ #include "lexicon.h" #include "pragmatics.h" #include "syslog.h" +#include "stomp.h" #include "show.h" /* strings for error reporting */ @@ -69,6 +71,7 @@ gramerr(char *phrase, char *pos, char *o %token ALARM %token SYSLOG %token PRINT +%token STOMP %token SOME_QUANT %token ALL_QUANT %token PCNT_QUANT @@ -137,7 +140,7 @@ gramerr(char *phrase, char *pos, char *o %left '*' '/' %left UMINUS RATE %left SUM_AGGR AVG_AGGR MAX_AGGR MIN_AGGR COUNT_AGGR -%left SHELL ALARM SYSLOG PRINT +%left SHELL ALARM SYSLOG PRINT STOMP %left ':' '#' '@' %left UNIT_SLASH INTERVAL @@ -222,6 +225,16 @@ act : '(' act ')' { $$ = actExpr(ACT_PRINT, $2, NULL); } | PRINT num actarg /* holdoff format */ { $$ = actExpr(ACT_PRINT, $3, $2); } + | STOMP actarg + { + stomping = 1; + $$ = actExpr(ACT_STOMP, $2, NULL); + } + | STOMP num actarg /* holdoff format */ + { + stomping = 1; + $$ = actExpr(ACT_STOMP, $3, $2); + } /* error reporting */ | error SEQ @@ -250,6 +263,9 @@ act : '(' act ')' | PRINT error { gramerr(tstr_str, follow, opStrings(ACT_PRINT)); $$ = NULL; } + | STOMP error + { gramerr(tstr_str, follow, opStrings(ACT_STOMP)); + $$ = NULL; } ; actarg : arglist Index: final-hacka-pcp-2.5.99/src/pmie/src/lexicon.c =================================================================== --- final-hacka-pcp-2.5.99.orig/src/pmie/src/lexicon.c 2006-11-27 10:00:42.920281750 +1100 +++ final-hacka-pcp-2.5.99/src/pmie/src/lexicon.c 2006-11-27 10:02:35.063290250 +1100 @@ -90,6 +90,7 @@ static LexEntry1 optab[] = { {"alarm", ALARM}, {"syslog", SYSLOG}, {"print", PRINT}, + {"stomp", STOMP}, {"rising", RISE}, {"falling", FALL}, {"match_inst", MATCH}, Index: final-hacka-pcp-2.5.99/src/pmie/src/show.c =================================================================== --- final-hacka-pcp-2.5.99.orig/src/pmie/src/show.c 2006-11-27 10:00:42.928282250 +1100 +++ final-hacka-pcp-2.5.99/src/pmie/src/show.c 2006-11-27 10:02:35.063290250 +1100 @@ -104,6 +104,7 @@ static struct { { ACT_ALARM, "alarm" }, { ACT_SYSLOG, "syslog" }, { ACT_PRINT, "print" }, + { ACT_STOMP, "stomp" }, { ACT_ARG, "" }, { NOP, "" }, { OP_VAR, "" }, Index: final-hacka-pcp-2.5.99/src/pmie/src/GNUmakefile =================================================================== --- final-hacka-pcp-2.5.99.orig/src/pmie/src/GNUmakefile 2006-11-27 10:00:42.932282500 +1100 +++ final-hacka-pcp-2.5.99/src/pmie/src/GNUmakefile 2006-11-27 10:02:35.063290250 +1100 @@ -35,10 +35,10 @@ include $(TOPDIR)/src/include/builddefs TARGET = pmie$(EXECSUFFIX) CFILES = pmie.c symbol.c dstruct.c lexicon.c syntax.c pragmatics.c eval.c \ - show.c match_inst.c syslog.c + show.c match_inst.c syslog.c stomp.c HFILES = fun.h dstruct.h eval.h lexicon.h pmiestats.h pragmatics.h \ - show.h symbol.h syntax.h syslog.h + show.h symbol.h syntax.h syslog.h stomp.h SKELETAL = hdr.sk fetch.sk misc.sk aggregate.sk unary.sk binary.sk \ merge.sk act.sk Index: final-hacka-pcp-2.5.99/src/pmie/src/fun.h =================================================================== --- final-hacka-pcp-2.5.99.orig/src/pmie/src/fun.h 2006-11-27 10:00:42.940283000 +1100 +++ final-hacka-pcp-2.5.99/src/pmie/src/fun.h 2006-11-27 10:02:35.063290250 +1100 @@ -128,6 +128,7 @@ void actShell(Expr *); void actAlarm(Expr *); void actSyslog(Expr *); void actPrint(Expr *); +void actStomp(Expr *); void actArg(Expr *); void actFake(Expr *); Index: final-hacka-pcp-2.5.99/src/pmie/src/stomp.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ final-hacka-pcp-2.5.99/src/pmie/src/stomp.h 2006-11-30 11:20:39.096655250 +1100 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2006 Aconex. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Streaming Text Orientated Messaging Protocol implementation + * http://stomp.codehaus.org/ + */ +extern int stomping; /* true if stomp actions present */ +extern char *stompfile; /* stomp config file */ +extern int stompInit(void); /* connect to stomp server */ +extern int stompSend(const char *); /* send to JMS server, via stomp */ Index: final-hacka-pcp-2.5.99/src/pmie/src/pmie.c =================================================================== --- final-hacka-pcp-2.5.99.orig/src/pmie/src/pmie.c 2006-11-27 10:00:42.944283250 +1100 +++ final-hacka-pcp-2.5.99/src/pmie/src/pmie.c 2006-11-27 10:43:13.907708500 +1100 @@ -44,6 +44,7 @@ #include #include #include "dstruct.h" +#include "stomp.h" #include "syntax.h" #include "pragmatics.h" #include "eval.h" @@ -73,8 +74,20 @@ static char *intro = "Performance Co-Pi static char logfile[MAXPATHLEN+1]; static char perffile[PMIE_PATHSIZE]; /* /var/tmp/ file name */ +static char menu[] = +"pmie debugger commands\n\n" +" f [file-name] - load expressions from given file or stdin\n" +" l [expr-name] - list named expression or all expressions\n" +" r [interval] - run for given or default interval\n" +" S time-spec - set start time for run\n" +" T time-spec - set default interval for run command\n" +" v [expr-name] - print subexpression used for %h, %i and\n" +" %v bindings\n" +" h or ? - print this menu of commands\n" +" q - quit\n\n"; + static char usage[] = - "Usage: pmie [options] [filename ...]\n\n" + "Usage: %s [options] [filename ...]\n\n" "Options:\n" " -A align align sample times on natural boundaries\n" " -a archive metrics source is a PCP log archive\n" @@ -85,6 +98,7 @@ static char usage[] = " -e force timestamps to be reported when used with -V, -v or -W\n" " -f run in foreground\n" " -h host metrics source is PMCD on host\n" + " -j stompfile stomp protocol (JMS) file [default %s/config/pmie/stomp]\n" " -l logfile send status and error messages to logfile\n" " -n pmnsfile use an alternative PMNS\n" " -O offset initial offset into the time window\n" @@ -98,17 +112,16 @@ static char usage[] = " -Z timezone set reporting timezone\n" " -z set reporting timezone to local time of metrics source\n"; -static char menu[] = -"pmie debugger commands\n\n" -" f [file-name] - load expressions from given file or stdin\n" -" l [expr-name] - list named expression or all expressions\n" -" r [interval] - run for given or default interval\n" -" S time-spec - set start time for run\n" -" T time-spec - set default interval for run command\n" -" v [expr-name] - print subexpression used for %h, %i and\n" -" %v bindings\n" -" h or ? - print this menu of commands\n" -" q - quit\n\n"; +/*********************************************************************** + * usage message + ***********************************************************************/ + +static void +usageMessage(void) +{ + fprintf(stderr, usage, pmProgname, pmGetConfig("PCP_VAR_DIR")); + exit(1); +} /*********************************************************************** @@ -445,7 +458,7 @@ getargs(int argc, char *argv[]) memset(&tv2, 0, sizeof(tv2)); dstructInit(); - while ((c=getopt(argc, argv, "a:A:bc:CdD:efh:l:n:O:S:t:T:vVWXxzZ:?")) != EOF) { + while ((c=getopt(argc, argv, "a:A:bc:CdD:efh:j:l:n:O:S:t:T:vVWXxzZ:?")) != EOF) { switch (c) { case 'a': /* archives */ @@ -536,6 +549,10 @@ getargs(int argc, char *argv[]) dfltHost = optarg; break; + case 'j': /* stomp protocol (JMS) config */ + stompfile = optarg; + break; + case 'l': /* alternate log file */ if (commandlog != NULL) { fprintf(stderr, "%s: at most one -l option is allowed\n", @@ -549,7 +566,7 @@ getargs(int argc, char *argv[]) case 'n': /* alternate namespace file */ pmnsfile = optarg; - break; + break; case 'O': /* position within time window */ offsetFlag = optarg; @@ -626,10 +643,8 @@ getargs(int argc, char *argv[]) pmProgname); err++; } - if (err) { - fprintf(stderr, usage); - exit(1); - } + if (err) + usageMessage(); if (foreground) isdaemon = 0; @@ -760,6 +775,9 @@ getargs(int argc, char *argv[]) setsid(); /* not process group leader, lose controlling tty */ } + if (stomping) + stompInit(); /* connect to our message server */ + if (agent) agentInit(); /* initialize secret agent stuff */ Index: final-hacka-pcp-2.5.99/src/pmie/src/stomp.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ final-hacka-pcp-2.5.99/src/pmie/src/stomp.c 2006-11-30 11:26:37.563058000 +1100 @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2006 Aconex. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +static int stomp_connect(const char *hostname, int port); +static void stomp_disconnect(void); + +int stomping; +char *stompfile; +extern int verbose; + +static int fd = -1; +static int port = -1; +static int timeout = 2; /* default 2 sec to timeout JMS server ACKs */ +static char *hostname; +static char *username; +static char *passcode; +static char *topic; /* JMS "topic" for pmie messages */ +static char pmietopic[] = "PMIE"; /* default JMS "topic" for pmie */ + +static char buffer[4096]; + +static int stomp_connect(const char *hostname, int port) +{ + int sts, nodelay = 1; + struct linger nolinger = { 1, 0 }; + struct sockaddr_in myaddr; + struct hostent *servinfo; + + if ((servinfo = gethostbyname(hostname)) == NULL) + return -1; + + /* socket setup */ + if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) + return -2; + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, /* avoid 200 ms delay */ + (char *)&nodelay, (socklen_t)sizeof(nodelay)) < 0) { + stomp_disconnect(); + return -3; + } + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, /* don't linger on close */ + (char *)&nolinger, (socklen_t)sizeof(nolinger)) < 0) { + stomp_disconnect(); + return -4; + } + + memset(&myaddr, 0, sizeof(myaddr)); + myaddr.sin_family = AF_INET; + memcpy(&myaddr.sin_addr, servinfo->h_addr, servinfo->h_length); + myaddr.sin_port = htons(port); + if ((sts = connect(fd, (struct sockaddr *)&myaddr, sizeof(myaddr))) < 0) { + stomp_disconnect(); + return -5; + } + + return fd; +} + +static int stomp_read_ack(void) +{ + struct timeval tv; + fd_set fds, readyfds; + int nready, sts; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + tv.tv_sec = timeout; + tv.tv_usec = 0; + memcpy(&readyfds, &fds, sizeof(readyfds)); + nready = select(fd + 1, &readyfds, NULL, NULL, &tv); + if (nready <= 0) { + if (nready == 0) + __pmNotifyErr(LOG_ERR, "Timed out waiting for server %s:%d - %s", + hostname, port, strerror(errno)); + else + __pmNotifyErr(LOG_ERR, "Error waiting for server %s:%d - %s", + hostname, port, strerror(errno)); + stomp_disconnect(); + return -1; + } + + do { + sts = read(fd, buffer, sizeof(buffer)); + if (sts < 0) { + __pmNotifyErr(LOG_ERR, "Error reading from server %s:%d - %s", + hostname, port, strerror(errno)); + stomp_disconnect(); + return -1; + } + /* check for anything else we need to read to clear this ACK */ + memset(&tv, 0, sizeof(tv)); + memcpy(&readyfds, &fds, sizeof(readyfds)); + } while (select(fd + 1, &readyfds, NULL, NULL, &tv) > 0); + + return 0; +} + +static int stomp_write(const char *buffer, int length) +{ + int sts; + + do { + sts = write(fd, buffer, length); + if (sts < 0) { + __pmNotifyErr(LOG_ERR, "Write error to JMS server %s:%d - %s", + hostname, port, strerror(errno)); + stomp_disconnect(); + return -1; + } + else if (sts == 0) + break; + length -= sts; + } while (length > 0); + + return 0; +} + +static int stomp_authenticate(void) +{ + int len; + + if (fd < 0) + return -1; + len = snprintf(buffer, sizeof(buffer), + "CONNECT\nlogin:%s\npasscode:%s\n\n", username, passcode); + if (stomp_write(buffer, len) < 0) + return -1; + if (stomp_write("\0\n", 2) < 0) + return -1; + return 0; +} + +static int stomp_destination(void) +{ + int len; + + if (fd < 0) + return -1; + len = snprintf(buffer, sizeof(buffer), + "SUB\ndestination:/topic/%s\n\n", topic); + if (stomp_write(buffer, len) < 0) + return -1; + if (stomp_write("\0\n", 2) < 0) + return -1; + return 0; +} + +static int stomp_hello(void) +{ + int len; + + if (fd < 0) + return -1; + len = snprintf(buffer, sizeof(buffer), "SEND\ndestination:/topic/%s\n\n" + "INFO: PMIE: Established initial connection", topic); + if (stomp_write(buffer, len) < 0) + return -1; + if (stomp_write("\0\n", 2) < 0) + return -1; + return 0; +} + +static void stomp_disconnect(void) +{ + if (fd >= 0) + close(fd); + fd = -1; +} + +static char *isspace_terminate(char *string) +{ + int i = 0; + + while (!isspace(string[i++])) /* do nothing */ ; + if (i) + string[i-1] = '\0'; + return string; +} + +/* + * Parse our stomp configuration file, simple format: + * host= # JMS server machine + * port= # server port number + * username= | user= + * passcode= | password= + * timeout= # optional + * topic= # optional + */ +static void stomp_parse(void) +{ + char config[MAXPATHLEN+1]; + FILE *f; + + if (stompfile) + strncat(config, stompfile, sizeof(config)); + else + snprintf(config, sizeof(config), "%s/config/pmie/stomp", + pmGetConfig("PCP_VAR_DIR")); + if ((f = fopen(config, "r")) == NULL) { + __pmNotifyErr(LOG_ERR, "Cannot open STOMP configuration file %s: %s", + config, strerror(errno)); + exit(1); + } + while (fgets(buffer, sizeof(buffer), f)) { + if (strncmp(buffer, "port=", 5) == 0) + port = atoi(isspace_terminate(&buffer[5])); + else if (strncmp(buffer, "host=", 5) == 0) + hostname = strdup(isspace_terminate(&buffer[5])); + else if (strncmp(buffer, "hostname=", 9) == 0) + hostname = strdup(isspace_terminate(&buffer[9])); + else if (strncmp(buffer, "user=", 5) == 0) + username = strdup(isspace_terminate(&buffer[5])); + else if (strncmp(buffer, "username=", 9) == 0) + username = strdup(isspace_terminate(&buffer[9])); + else if (strncmp(buffer, "password=", 9) == 0) + passcode = strdup(isspace_terminate(&buffer[9])); + else if (strncmp(buffer, "passcode=", 9) == 0) + passcode = strdup(isspace_terminate(&buffer[9])); + else if (strncmp(buffer, "timeout=", 8) == 0) /* optional */ + timeout = atoi(isspace_terminate(&buffer[8])); + else if (strncmp(buffer, "topic=", 6) == 0) /* optional */ + topic = strdup(isspace_terminate(&buffer[6])); + } + fclose(f); + + if (!hostname) + __pmNotifyErr(LOG_ERR, "No host in STOMP config file %s", config); + if (port == -1) + __pmNotifyErr(LOG_ERR, "No port in STOMP config file %s", config); + if (!username) + __pmNotifyErr(LOG_ERR, "No username in STOMP config file %s", config); + if (!passcode) + __pmNotifyErr(LOG_ERR, "No passcode in STOMP config file %s", config); + if (port == -1 || !hostname || !username || !passcode) + exit(1); +} + +/* + * Setup the connection to the stomp server, and handle initial protocol + * negotiations (sending user/passcode over to the server in particular). + * Stomp protocol is clear text... (we don't need no stinkin' security!). + * Note: this routine is used for both the initial connection and also for + * any subsequent reconnect attempts. + */ +void stompInit(void) +{ + time_t thistime; + static time_t lasttime; + static int firsttime = 1; + + if (firsttime) { /* initial connection attempt */ + stomp_parse(); + if (!topic) + topic = pmietopic; + atexit(stomp_disconnect); + } else { /* reconnect attempt, if not too soon */ + time(&thistime); + if (thistime < lasttime + 60) + goto disconnect; + } + + if (verbose) + __pmNotifyErr(LOG_INFO, "Connecting to %s, port %d", hostname, port); + if (stomp_connect(hostname, port) < 0) { + __pmNotifyErr(LOG_ERR, "Could not connect to the message server"); + goto disconnect; + } + + if (verbose) + __pmNotifyErr(LOG_INFO, "Connected; sending stomp connect message"); + if (stomp_authenticate() < 0) { + __pmNotifyErr(LOG_ERR, "Could not sent STOMP CONNECT frame to server"); + goto disconnect; + } + + if (verbose) + __pmNotifyErr(LOG_INFO, "Sent; waiting for server ACK"); + if (stomp_read_ack() < 0) { + __pmNotifyErr(LOG_ERR, "Could not read STOMP ACK frame."); + goto disconnect; + } + + if (verbose) + __pmNotifyErr(LOG_INFO, "ACK; sending initial PMIE topic and hello"); + if (stomp_destination() < 0) { + __pmNotifyErr(LOG_ERR, "Could not read TOPIC frame."); + goto disconnect; + } + if (stomp_hello() < 0) { + __pmNotifyErr(LOG_ERR, "Could not send HELLO frame."); + goto disconnect; + } + + if (verbose) + __pmNotifyErr(LOG_INFO, "Sent; waiting for server ACK"); + if (stomp_read_ack() < 0) { + __pmNotifyErr(LOG_ERR, "Could not read STOMP ACK frame"); + goto disconnect; + } + + if (!firsttime) + __pmNotifyErr(LOG_INFO, "Reconnected to STOMP protocol server"); + else if (verbose) + __pmNotifyErr(LOG_INFO, "Initial STOMP protocol setup complete"); + firsttime = 0; + goto finished; + +disconnect: + stomp_disconnect(); + if (firsttime) + exit(1); + /* otherwise, we attempt reconnect on next message firing (>1min) */ +finished: + lasttime = thistime; +} + +/* + * Send a message to the stomp server. + */ +int stompSend(const char *msg) +{ + int len; + + if (fd < 0) stompInit(); /* reconnect */ + if (fd < -1) return -1; + + len = snprintf(buffer, sizeof(buffer), + "SEND\ndestination:/topic/%s\n\n", topic); + if (stomp_write(buffer, len) < 0) + return -1; + if (stomp_write(msg, strlen(msg)) < 0) + return -1; + if (stomp_write("\0\n", 2) < 0) + return -1; + return 0; +} Index: final-hacka-pcp-2.5.99/src/pmie/src/hdr.sk =================================================================== --- final-hacka-pcp-2.5.99.orig/src/pmie/src/hdr.sk 2006-11-27 10:00:42.952283750 +1100 +++ final-hacka-pcp-2.5.99/src/pmie/src/hdr.sk 2006-11-30 11:20:13.303043250 +1100 @@ -41,5 +41,6 @@ #include "pragmatics.h" #include "fun.h" #include "show.h" +#include "stomp.h" Index: final-hacka-pcp-2.5.99/man/man1/pmie.1 =================================================================== --- final-hacka-pcp-2.5.99.orig/man/man1/pmie.1 2006-11-27 10:00:42.968284750 +1100 +++ final-hacka-pcp-2.5.99/man/man1/pmie.1 2006-11-30 11:19:00.098468250 +1100 @@ -2,6 +2,7 @@ '\"macro stdmacro .\" .\" Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. +.\" Portions copyright (c) 2006 Aconex. All Rights Reserved. .\" .\" This program is free software; you can redistribute it and/or modify it .\" under the terms of the GNU General Public License as published by the @@ -42,6 +43,7 @@ [\f3\-c\f1 \f2filename\f1] [\f3\-h\f1 \f2host\f1] [\f3\-l\f1 \f2logfile\f1] +[\f3\-j\f1 \f2stompfile\f1] [\f3\-n\f1 \f2pmnsfile\f1] [\f3\-O\f1 \f2offset\f1] [\f3\-S\f1 \f2starttime\f1] @@ -166,6 +168,15 @@ being evaluated. Standard error is sent to .IR logfile . .TP +.B \-j +An alternative STOMP protocol configuration is loaded from +.IR stompfile . +If this option is not used, and the +.I stomp +action is used in any rule, the default location +.I $PCP_VAR_DIR/pmie/config/stomp +will be used. +.TP .B \-n An alternative Performance Metrics Name Space (PMNS) is loaded from the file .IR pmnsfile . @@ -732,10 +743,11 @@ c | c lf(CB) | l. Operators Explanation _ +alarm Raise a visible alarm with \fBxconfirm\f1(1) print Display on standard output shell Execute with \fBsh\fR(1) -alarm Raise a visible alarm with \fBxconfirm\f1(1) -syslog Append to \fI/var/adm/SYSLOG\fR +stomp Send a STOMP message to a JMS server +syslog Append a message to system log file .TE .P Multiple actions may be separated by the \f(CW&\fR and \f(CW|\fR @@ -895,6 +907,83 @@ or shutdown, or when they have been dete Refer to .BR pmie_check (1) for details on automating this process. +.SH EVENT MONITORING +It is common for production systems to be monitored in a central +location. +Traditionally on UNIX systems this has been performed by the system +log facilities \- see +.BR logger (1), +and +.BR syslogd (1). +.P +.B pmie +fits into this model when rules use the +.I syslog +action. +Note that if the action string begins with \-p (priority) and/or -t (tag) +then these are extracted from the string and treated in the same way as in +.BR logger (1). +.P +However, it is common to have other event monitoring frameworks also, +into which you may wish to incorporate performance events from +.BR pmie . +You can often use the +.I shell +action to send events to these frameworks, as they usually provide +their a program for injecting events into the framework from external +sources. +.P +A final option is use of the +.I stomp +(Streaming Text Oriented Messaging Protocol) action, which allows +.B pmie +to connect to a central JMS (Java Messaging System) server and send +events to the PMIE topic. +Tools can be written to extract these text messages and present them +to operations people (via desktop popup windows, etc). +Use of the +.I stomp +action requires a stomp configuration file to be setup, which specifies +the location of the JMS server host, port number, and username/password. +.P +The format of this file is as follows: +.P +.ft CW +.nf +.in +0.5i +host=messages.sgi.com # this is the JMS server (required) +port=61616 # and its listening here (required) +timeout=2 # seconds to wait for server (optional) +username=joe # (required) +password=j03ST0MP # (required) +topic=PMIE # JMS topic for pmie messages (optional) +.in +.fi +.ft 1 +.P +The timeout value specifies the time (in seconds) that +.B pmie +should wait for acknowledgements from the JMS server after +sending a message (as required by the STOMP protocol). +Note that on startup, +.B pmie +will wait indefinately for a connection, and will not +begin rule evaluation until that initial connection has +been established. +Should the connection to the JMS server be lost at any +time while +.B pmie +is running, +.B pmie +will attempt to reconnect on each subsequent truthful +evaluation of a rule with a +.I stomp +action, but not more than once per minute. +This is to avoid contributing to network congestion. +In this situation, where the STOMP connection to the JMS server +has been severed, the +.I stomp +action will return a non-zero error value. .SH FILES .PD 0 .TP 10 @@ -906,7 +995,7 @@ default PMNS specification files .TP .BI $PCP_TMP_DIR/pmie .B pmie -maintains files in this directory to identify the running +maintains files in this directory to identify the running .B pmie instances and to export runtime information about each instance \- this data forms the basis of the pmcd.pmie performance metrics Index: final-hacka-pcp-2.5.99/src/pmie/GNUmakefile =================================================================== --- final-hacka-pcp-2.5.99.orig/src/pmie/GNUmakefile 2006-07-17 12:53:25.000000000 +1000 +++ final-hacka-pcp-2.5.99/src/pmie/GNUmakefile 2006-11-27 11:10:49.783194250 +1100 @@ -46,6 +46,7 @@ install:: default $(INSTALL) -m 644 crontab $(CFG_DIR)/crontab $(INSTALL) -m 644 config.default.install $(CFG_DIR)/config.default $(INSTALL) -m 644 control.install $(CFG_DIR)/control + $(INSTALL) -m 644 stomp.install $(CFG_DIR)/stomp $(INSTALL) -m 755 etc_init.d_pmie $(PCP_RC_DIR)/pmie $(INSTALL) -m 755 pmie_check.sh $(PCP_BINADM_DIR)/pmie_check $(INSTALL) -m 755 pmie2col $(PCP_BIN_DIR)/pmie2col Index: final-hacka-pcp-2.5.99/src/pmie/stomp.install =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ final-hacka-pcp-2.5.99/src/pmie/stomp.install 2006-11-30 11:20:59.513931250 +1100 @@ -0,0 +1,11 @@ +# +# Sample STOMP configuration file, parameters affecting connection +# between pmie and a JMS server for the "stomp" rule action. +# + +host=foo.bar.com # this is the JMS server (required) +port=61616 # and its listening here (required) +timeout=2 # seconds to wait for server (optional) +topic=PMIE # JMS topic for pmie messages (optional) +username=joe # required +password=j03ST0MP # required