1 /*----------------------------------------------------------------------------*/
2 /* Xymon message daemon. */
3 /* */
4 /* Client backend module for MQ collector */
5 /* */
6 /* Copyright (C) 2009-2011 Henrik Storner <henrik@hswn.dk> */
7 /* */
8 /* This program is released under the GNU General Public License (GPL), */
9 /* version 2. See the file "COPYING" for details. */
10 /* */
11 /*----------------------------------------------------------------------------*/
12
13 static char mqcollect_rcsid[] = "$Id: mqcollect.c 7060 2012-07-14 16:32:11Z storner $";
14
mqcollect_flush_status(int color,char * fromline,time_t timestamp,char * hostname,char * qmid,strbuffer_t * redsummary,strbuffer_t * yellowsummary,strbuffer_t * greensummary,char * clienttext)15 void mqcollect_flush_status(int color, char *fromline, time_t timestamp,
16 char *hostname, char *qmid,
17 strbuffer_t *redsummary, strbuffer_t *yellowsummary, strbuffer_t *greensummary,
18 char *clienttext)
19 {
20 char *groups;
21 char msgline[1024];
22
23 /* Generate the status message */
24 groups = getalertgroups();
25 init_status(color);
26 if (groups) sprintf(msgline, "status/group:%s ", groups); else strcpy(msgline, "status ");
27 addtostatus(msgline);
28 sprintf(msgline, "%s.mq %s %s\n",
29 hostname,
30 colorname(color), ctime(×tamp));
31 addtostatus(msgline);
32 if (STRBUFLEN(redsummary) > 0) {
33 addtostrstatus(redsummary);
34 addtostatus("\n");
35 }
36 if (STRBUFLEN(yellowsummary) > 0) {
37 addtostrstatus(yellowsummary);
38 addtostatus("\n");
39 }
40 if (STRBUFLEN(greensummary) > 0) {
41 addtostrstatus(greensummary);
42 addtostatus("\n");
43 }
44 addtostatus(clienttext);
45 addtostatus("\n");
46 addtostatus(fromline);
47 finish_status();
48 }
49
handle_mqcollect_client(char * hostname,char * clienttype,enum ostype_t os,void * hinfo,char * sender,time_t timestamp,char * clientdata)50 void handle_mqcollect_client(char *hostname, char *clienttype, enum ostype_t os,
51 void *hinfo, char *sender, time_t timestamp,
52 char *clientdata)
53 {
54 char *qmline = "Starting MQSC for queue manager ";
55 strbuffer_t *redsummary = newstrbuffer(0);
56 strbuffer_t *yellowsummary = newstrbuffer(0);
57 strbuffer_t *greensummary = newstrbuffer(0);
58 char *bol, *eoln, *clienttext;
59 int color = COL_GREEN;
60 char fromline[1024], msgline[1024];
61 char *qmid = NULL, *qnam = NULL; int qlen = -1, qage = -1; char *chnnam = NULL, *chnstatus = NULL;
62 enum { PARSING_QL, PARSING_QS, PARSING_CHS, PARSER_FLOAT } pstate = PARSER_FLOAT;
63 int lastline = 0;
64
65 sprintf(fromline, "\nStatus message received from %s\n", sender);
66
67 bol = strchr(clientdata, '\n'); if (bol) bol++; clienttext = bol;
68 while (bol) {
69 eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; else lastline = 1;
70 bol += strspn(bol, " \t");
71
72 if (strncmp(bol, qmline, strlen(qmline)) == 0) {
73 char *p;
74
75 if (qmid) xfree(qmid);
76 qmid = strdup(bol+strlen(qmline));
77 p = strrchr(qmid, '.'); if (p) *p = '\0';
78 }
79
80 else if ( (strncmp(bol, "AMQ8409:", 8) == 0) || /* "ql" command - Queue details, incl. depth */
81 (strncmp(bol, "AMQ8450:", 8) == 0) || /* "qs" command - Queue status */
82 (strncmp(bol, "AMQ8417:", 8) == 0) || /* "chs" command - Channel status */
83 lastline ) {
84
85 if ( ((pstate == PARSING_QL) || (pstate == PARSING_QS)) && qmid && qnam && (qlen >= 0)) {
86 /* Got a full queue depth status */
87 int warnlen, critlen, warnage, critage;
88 char *trackid;
89 get_mqqueue_thresholds(hinfo, clienttype, qmid, qnam, &warnlen, &critlen, &warnage, &critage, &trackid);
90
91 if ((critlen != -1) && (qlen >= critlen)) {
92 color = COL_RED;
93 sprintf(msgline, "&red Queue %s:%s has depth %d (critical: %d, warn: %d)\n",
94 qmid, qnam, qlen, critlen, warnlen);
95 addtobuffer(redsummary, msgline);
96 }
97 else if ((warnlen != -1) && (qlen >= warnlen)) {
98 if (color < COL_YELLOW) color = COL_YELLOW;
99 sprintf(msgline, "&yellow Queue %s:%s has depth %d (warn: %d, critical: %d)\n",
100 qmid, qnam, qlen, warnlen, critlen);
101 addtobuffer(yellowsummary, msgline);
102 }
103 else if ((warnlen != -1) || (critlen != -1)) {
104 sprintf(msgline, "&green Queue %s:%s has depth %d (warn: %d, critical: %d)\n",
105 qmid, qnam, qlen, warnlen, critlen);
106 addtobuffer(greensummary, msgline);
107 }
108
109 if ((pstate == PARSING_QS) && (qage >= 0)) {
110 if ((critage != -1) && (qage >= critage)) {
111 color = COL_RED;
112 sprintf(msgline, "&red Queue %s:%s has age %d (critical: %d, warn: %d)\n",
113 qmid, qnam, qage, critage, warnage);
114 addtobuffer(redsummary, msgline);
115 }
116 else if ((warnage != -1) && (qage >= warnage)) {
117 if (color < COL_YELLOW) color = COL_YELLOW;
118 sprintf(msgline, "&yellow Queue %s:%s has age %d (warn: %d, critical: %d)\n",
119 qmid, qnam, qage, warnage, critage);
120 addtobuffer(yellowsummary, msgline);
121 }
122 else if ((warnage != -1) || (critage != -1)) {
123 sprintf(msgline, "&green Queue %s:%s has age %d (warn: %d, critical: %d)\n",
124 qmid, qnam, qage, warnage, critage);
125 addtobuffer(greensummary, msgline);
126 }
127 }
128
129 if (trackid) {
130 /* FIXME: Send "data" message for creating queue-length RRD */
131 }
132
133 pstate = PARSER_FLOAT;
134 }
135
136 if ((pstate == PARSING_CHS) && qmid && chnnam && chnstatus) {
137 /* Got a full channel status */
138 int chncolor;
139
140 if (get_mqchannel_params(hinfo, clienttype, qmid, chnnam, chnstatus, &chncolor)) {
141 if (chncolor > color) color = chncolor;
142 switch (chncolor) {
143 case COL_RED:
144 sprintf(msgline, "&red Channel %s:%s has status %s\n", qmid, chnnam, chnstatus);
145 addtobuffer(redsummary, msgline);
146 break;
147 case COL_YELLOW:
148 sprintf(msgline, "&yellow Channel %s:%s has status %s\n", qmid, chnnam, chnstatus);
149 addtobuffer(yellowsummary, msgline);
150 break;
151 case COL_GREEN:
152 sprintf(msgline, "&green Channel %s:%s has status %s\n", qmid, chnnam, chnstatus);
153 addtobuffer(greensummary, msgline);
154 break;
155 }
156 }
157
158 pstate = PARSER_FLOAT;
159 }
160
161 if (qnam) xfree(qnam);
162 qlen = qage = -1;
163 if (chnnam) xfree(chnnam);
164 if (chnstatus) xfree(chnstatus);
165
166 if (strncmp(bol, "AMQ8409:", 8) == 0) pstate = PARSING_QL;
167 else if (strncmp(bol, "AMQ8450:", 8) == 0) pstate = PARSING_QS;
168 else if (strncmp(bol, "AMQ8417:", 8) == 0) pstate = PARSING_CHS;
169 else pstate = PARSER_FLOAT;
170 }
171 else if ((pstate == PARSING_QL) || (pstate == PARSING_QS)) {
172 char *bdup = strdup(bol);
173 char *tok = strtok(bdup, " \t");
174 while (tok) {
175 if (strncmp(tok, "QUEUE(", 6) == 0) {
176 char *p;
177
178 qnam = strdup(tok+6);
179 p = strchr(qnam, ')');
180 if (p) *p = '\0';
181 }
182 else if (strncmp(tok, "CURDEPTH(", 9) == 0) {
183 qlen = atoi(tok+9);
184 }
185 else if (strncmp(tok, "MSGAGE(", 7) == 0) {
186 if (isdigit(*(tok+7))) qage = atoi(tok+7);
187 }
188
189 tok = strtok(NULL, " \t");
190 }
191
192 xfree(bdup);
193 }
194 else if (pstate == PARSING_CHS) {
195 char *bdup = strdup(bol);
196 char *tok = strtok(bdup, " \t");
197 while (tok) {
198 if (strncmp(tok, "CHANNEL(", 8) == 0) {
199 char *p;
200
201 chnnam = strdup(tok+8);
202 p = strchr(chnnam, ')');
203 if (p) *p = '\0';
204 }
205 else if (strncmp(tok, "STATUS(", 7) == 0) {
206 char *p;
207
208 chnstatus = strdup(tok+7);
209 p = strchr(chnstatus, ')');
210 if (p) *p = '\0';
211 }
212
213 tok = strtok(NULL, " \t");
214 }
215 xfree(bdup);
216 }
217
218 if (eoln) {
219 *eoln = '\n';
220 bol = eoln+1;
221 }
222 else
223 bol = NULL;
224 }
225
226 mqcollect_flush_status(color, fromline, timestamp,
227 hostname, qmid,
228 redsummary, yellowsummary, greensummary,
229 clienttext);
230
231 if (qmid) xfree(qmid);
232 freestrbuffer(greensummary);
233 freestrbuffer(yellowsummary);
234 freestrbuffer(redsummary);
235 }
236
237