xymon

Check-in [43b52d60d4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add debug lines in logfetch.c; warn properly on invalid regexes git-svn-id: http://svn.code.sf.net/p/xymon/code/branches/4.3.19@7606 44351d6e-118b-4698-b696-ce33095ecaa4
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | origin/4.3.19
Files: files | file ages | folders
SHA3-256: 43b52d60d4c48f00a362e495be2162d7243b068743f4f108aa0eade0cace502d
User & Date: jccleaver@users.sf.net 2015-03-21 11:29:34
Context
2015-03-21
14:41
Add LOGFETCHSCROLLBACK and 'CURRENT' marking git-svn-id: http://svn.code.sf.net/p/xymon/code/branches/4.3.19@7607 44351d6e-118b-4698-b696-ce33095ecaa4 check-in: 2c198f8f5a user: jccleaver@users.sf.net tags: trunk, origin/4.3.19
11:29
Add debug lines in logfetch.c; warn properly on invalid regexes git-svn-id: http://svn.code.sf.net/p/xymon/code/branches/4.3.19@7606 44351d6e-118b-4698-b696-ce33095ecaa4 check-in: 43b52d60d4 user: jccleaver@users.sf.net tags: trunk, origin/4.3.19
11:20
Add fgets() wrapper to safely skip NULLs embedded in log files (From Franco Gasperino) git-svn-id: http://svn.code.sf.net/p/xymon/code/branches/4.3.19@7605 44351d6e-118b-4698-b696-ce33095ecaa4 check-in: 2328238c24 user: jccleaver@users.sf.net tags: trunk, origin/4.3.19
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to client/logfetch.c.

169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
...
219
220
221
222
223
224
225
226
227
228

229




230
231
232


233
234
235
236

237




238
239


240
241
242
243
244
245
246
...
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279
280
281
282
283
284

285
286
287
288
289
290
291
...
332
333
334
335
336
337
338

339
340
341
342
343
344
345
	 */
	fstat(fileno(fd), &st);
	if ((st.st_size < logdef->lastpos[0]) || (st.st_size < logdef->lastpos[POSCOUNT-1])) {
		/*
		 * Logfile shrank - probably it was rotated.
		 * Start from beginning of file.
		 */

		for (i=0; (i < POSCOUNT); i++) logdef->lastpos[i] = 0;
	}

	/* Go to the position we were at POSCOUNT-1 times ago (corresponds to 30 minutes) */
#ifdef _LARGEFILE_SOURCE
	fseeko(fd, logdef->lastpos[POSCOUNT-1], SEEK_SET);
	bufsz = st.st_size - ftello(fd);
	if (bufsz > MAXCHECK) {
		/*
		 * Too much data for us. We have to skip some of the old data.
		 */

		logdef->lastpos[POSCOUNT-1] = st.st_size - MAXCHECK;
		fseeko(fd, logdef->lastpos[POSCOUNT-1], SEEK_SET);
		bufsz = st.st_size - ftello(fd);
	}
#else
	fseek(fd, logdef->lastpos[POSCOUNT-1], SEEK_SET);
	bufsz = st.st_size - ftell(fd);
	if (bufsz > MAXCHECK) {
		/*
		 * Too much data for us. We have to skip some of the old data.
		 */

		logdef->lastpos[POSCOUNT-1] = st.st_size - MAXCHECK;
		fseek(fd, logdef->lastpos[POSCOUNT-1], SEEK_SET);
		bufsz = st.st_size - ftell(fd);
	}
#endif

	/* Shift position markers one down for the next round */
................................................................................
	if (buf == NULL) {
		/* Couldnt allocate the buffer */
		return "Out of memory";
	}

	/* Compile the regex patterns */
	if (logdef->ignorecount) {
		int i;
		ignexpr = (regex_t *) malloc(logdef->ignorecount * sizeof(regex_t));
		for (i=0; (i < logdef->ignorecount); i++) {

			status = regcomp(&ignexpr[i], logdef->ignore[i], REG_EXTENDED|REG_ICASE|REG_NOSUB);




			if (status != 0) logdef->ignore[i] = NULL;
		}
	}


	if (logdef->triggercount) {
		int i;
		trigexpr = (regex_t *) malloc(logdef->triggercount * sizeof(regex_t));
		for (i=0; (i < logdef->triggercount); i++) {

			status = regcomp(&trigexpr[i], logdef->trigger[i], REG_EXTENDED|REG_ICASE|REG_NOSUB);




			if (status != 0) logdef->trigger[i] = NULL;
		}


	}
	triggerstartpos = triggerendpos = NULL;
	triggerlinecount = 0;
	memset(linepos, 0, sizeof(linepos)); lpidx = 0;

	/* 
	 * Read data.
................................................................................
			/*
			 * fgets() can return an empty buffer without flagging
			 * end-of-file. It should not happen anymore now that
			 * we have extended the buffer to have room for the
			 * terminating \0 byte, but if it does then we will
			 * catch it here.
			 */

			done = 1;
			continue;
		}

		/* Check ignore pattern */
		if (logdef->ignorecount) {
			int i, match = 0;

			for (i=0; ((i < logdef->ignorecount) && !match); i++) {
				match = (regexec(&ignexpr[i], fillpos, 0, NULL, 0) == 0);

			}

			if (match) continue;
		}

		linepos[lpidx] = fillpos;

		/* See if this is a trigger line */
		if (logdef->triggercount) {
			int i, match = 0;

			for (i=0; ((i < logdef->triggercount) && !match); i++) {
				match = (regexec(&trigexpr[i], fillpos, 0, NULL, 0) == 0);

			}

			if (match) {
				int sidx;
				
				sidx = lpidx - LINES_AROUND_TRIGGER; 
				if (sidx < 0) sidx += (2*LINES_AROUND_TRIGGER + 1);
................................................................................
				/* Terminate the current trigger anchor pair by aligning the end pointer */
				dbgprintf(" - trigger END position set\n");
				triggerptrs[triggerptrs_count - 1][1] = triggerendpos;
			}
		}

		bytesleft = (bufsz - (fillpos - buf));

	}

	if (triggerptrs != NULL) {
	        dbgprintf("Marked %i pairs of START and END anchors for consideration.\n", triggerptrs_count);

		/* Ensure that a premature EOF before the last trigger end postion doesn't blow up */
		if (triggerptrs[triggerptrs_count - 1][1] == NULL) triggerptrs[triggerptrs_count -1][1] = fillpos;







>











>











>







 







|


>
|
>
>
>
>
|
|
|
>
>

|


>
|
>
>
>
>
|
|
>
>







 







>










>













>







 







>







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
	 */
	fstat(fileno(fd), &st);
	if ((st.st_size < logdef->lastpos[0]) || (st.st_size < logdef->lastpos[POSCOUNT-1])) {
		/*
		 * Logfile shrank - probably it was rotated.
		 * Start from beginning of file.
		 */
		errprintf("logfetch: File %s shrank from >=%zu to %zu bytes in size. Probably rotated; clearing position state\n", filename, logdef->lastpos[POSCOUNT-1], st.st_size);
		for (i=0; (i < POSCOUNT); i++) logdef->lastpos[i] = 0;
	}

	/* Go to the position we were at POSCOUNT-1 times ago (corresponds to 30 minutes) */
#ifdef _LARGEFILE_SOURCE
	fseeko(fd, logdef->lastpos[POSCOUNT-1], SEEK_SET);
	bufsz = st.st_size - ftello(fd);
	if (bufsz > MAXCHECK) {
		/*
		 * Too much data for us. We have to skip some of the old data.
		 */
		errprintf("logfetch: %s delta %zu bytes exceeds max buffer size %zu; skipping some data\n", filename, bufsz, MAXCHECK);
		logdef->lastpos[POSCOUNT-1] = st.st_size - MAXCHECK;
		fseeko(fd, logdef->lastpos[POSCOUNT-1], SEEK_SET);
		bufsz = st.st_size - ftello(fd);
	}
#else
	fseek(fd, logdef->lastpos[POSCOUNT-1], SEEK_SET);
	bufsz = st.st_size - ftell(fd);
	if (bufsz > MAXCHECK) {
		/*
		 * Too much data for us. We have to skip some of the old data.
		 */
		errprintf("logfetch: %s delta %zu bytes exceeds max buffer size %zu; skipping some data\n", filename, bufsz, MAXCHECK);
		logdef->lastpos[POSCOUNT-1] = st.st_size - MAXCHECK;
		fseek(fd, logdef->lastpos[POSCOUNT-1], SEEK_SET);
		bufsz = st.st_size - ftell(fd);
	}
#endif

	/* Shift position markers one down for the next round */
................................................................................
	if (buf == NULL) {
		/* Couldnt allocate the buffer */
		return "Out of memory";
	}

	/* Compile the regex patterns */
	if (logdef->ignorecount) {
               int i, realcount = 0;
		ignexpr = (regex_t *) malloc(logdef->ignorecount * sizeof(regex_t));
		for (i=0; (i < logdef->ignorecount); i++) {
			dbgprintf(" - compiling IGNORE regex: %s\n", logdef->ignore[i]);
			status = regcomp(&ignexpr[realcount++], logdef->ignore[i], REG_EXTENDED|REG_ICASE|REG_NOSUB);
			if (status != 0) {
				char regbuf[1000];
				regerror(status, &ignexpr[--realcount], regbuf, sizeof(regbuf));	/* re-decrement realcount here */
				errprintf("logfetch: could not compile ignore regex '%s': %s\n", logdef->ignore[i], regbuf);
				logdef->ignore[i] = NULL;
			}
		}
		logdef->ignorecount = realcount;
	}
	if (logdef->triggercount) {
		int i, realcount = 0;
		trigexpr = (regex_t *) malloc(logdef->triggercount * sizeof(regex_t));
		for (i=0; (i < logdef->triggercount); i++) {
			dbgprintf(" - compiling TRIGGER regex: %s\n", logdef->trigger[i]);
			status = regcomp(&trigexpr[realcount++], logdef->trigger[i], REG_EXTENDED|REG_ICASE|REG_NOSUB);
			if (status != 0) {
				char regbuf[1000];
				regerror(status, &trigexpr[--realcount], regbuf, sizeof(regbuf));	/* re-decrement realcount here */
				errprintf("logfetch: could not compile trigger regex '%s': %s\n", logdef->trigger[i], regbuf);
				logdef->trigger[i] = NULL;
			}
		}
		logdef->triggercount = realcount;
	}
	triggerstartpos = triggerendpos = NULL;
	triggerlinecount = 0;
	memset(linepos, 0, sizeof(linepos)); lpidx = 0;

	/* 
	 * Read data.
................................................................................
			/*
			 * fgets() can return an empty buffer without flagging
			 * end-of-file. It should not happen anymore now that
			 * we have extended the buffer to have room for the
			 * terminating \0 byte, but if it does then we will
			 * catch it here.
			 */
			dbgprintf(" - empty buffer returned; assuming eof\n");
			done = 1;
			continue;
		}

		/* Check ignore pattern */
		if (logdef->ignorecount) {
			int i, match = 0;

			for (i=0; ((i < logdef->ignorecount) && !match); i++) {
				match = (regexec(&ignexpr[i], fillpos, 0, NULL, 0) == 0);
				if (match) dbgprintf(" - line matched ignore %d: %s", i, fillpos); // fgets stores the newline in
			}

			if (match) continue;
		}

		linepos[lpidx] = fillpos;

		/* See if this is a trigger line */
		if (logdef->triggercount) {
			int i, match = 0;

			for (i=0; ((i < logdef->triggercount) && !match); i++) {
				match = (regexec(&trigexpr[i], fillpos, 0, NULL, 0) == 0);
				if (match) dbgprintf(" - line matched trigger %d: %s", i, fillpos); // fgets stores the newline in
			}

			if (match) {
				int sidx;
				
				sidx = lpidx - LINES_AROUND_TRIGGER; 
				if (sidx < 0) sidx += (2*LINES_AROUND_TRIGGER + 1);
................................................................................
				/* Terminate the current trigger anchor pair by aligning the end pointer */
				dbgprintf(" - trigger END position set\n");
				triggerptrs[triggerptrs_count - 1][1] = triggerendpos;
			}
		}

		bytesleft = (bufsz - (fillpos - buf));
		// dbgprintf(" -- bytesleft: %zu\n", bytesleft);
	}

	if (triggerptrs != NULL) {
	        dbgprintf("Marked %i pairs of START and END anchors for consideration.\n", triggerptrs_count);

		/* Ensure that a premature EOF before the last trigger end postion doesn't blow up */
		if (triggerptrs[triggerptrs_count - 1][1] == NULL) triggerptrs[triggerptrs_count -1][1] = fillpos;