diff options
Diffstat (limited to 'utility/logparse.c')
-rw-r--r-- | utility/logparse.c | 169 |
1 files changed, 166 insertions, 3 deletions
diff --git a/utility/logparse.c b/utility/logparse.c index 534703d..7267682 100644 --- a/utility/logparse.c +++ b/utility/logparse.c | |||
@@ -200,18 +200,180 @@ void parser_find_logs(config_t *cfg) | |||
200 | if (apr_dir_open(&dir, cfg->input_dir, tp)==APR_SUCCESS) { | 200 | if (apr_dir_open(&dir, cfg->input_dir, tp)==APR_SUCCESS) { |
201 | while (apr_dir_read(&finfo, APR_FINFO_NAME | APR_FINFO_TYPE, dir) | 201 | while (apr_dir_read(&finfo, APR_FINFO_NAME | APR_FINFO_TYPE, dir) |
202 | == APR_SUCCESS) { | 202 | == APR_SUCCESS) { |
203 | char *temp; | ||
203 | if (finfo.filetype == APR_DIR) | 204 | if (finfo.filetype == APR_DIR) |
204 | continue; | 205 | continue; |
205 | newp = (config_filestat_t *)apr_array_push(cfg->input_files); | 206 | newp = (config_filestat_t *)apr_array_push(cfg->input_files); |
206 | newp->result = "Not Parsed"; | 207 | newp->result = "Not Parsed"; |
207 | apr_filepath_merge(&(newp->fname), cfg->input_dir, finfo.name, | 208 | apr_filepath_merge(&temp, cfg->input_dir, finfo.name, |
208 | APR_FILEPATH_TRUENAME, cfg->pool); | 209 | APR_FILEPATH_TRUENAME, cfg->pool); |
210 | newp->fname = temp; | ||
209 | } | 211 | } |
210 | apr_dir_close(dir); | 212 | apr_dir_close(dir); |
211 | } | 213 | } |
212 | apr_pool_destroy(tp); | 214 | apr_pool_destroy(tp); |
213 | } | 215 | } |
214 | 216 | ||
217 | #define BUFFER_SIZE (16 * 1024) | ||
218 | |||
219 | void parser_split_logs(config_t *cfg) | ||
220 | { | ||
221 | apr_pool_t *tp, *tfp; | ||
222 | apr_array_header_t *foundfiles; | ||
223 | config_filestat_t *filelist; | ||
224 | config_filestat_t *newfile; | ||
225 | apr_file_t *infile; | ||
226 | int f, l; | ||
227 | apr_status_t rv; | ||
228 | apr_finfo_t finfo; | ||
229 | char buff[BUFFER_SIZE]; | ||
230 | int linecount; | ||
231 | int piecesize; | ||
232 | |||
233 | if (!cfg->split_enabled) return; | ||
234 | if (!cfg->split_dir) { | ||
235 | logging_log(cfg, LOGLEVEL_NOISE, "SPLITTER: Missing Split Output directory"); | ||
236 | return; | ||
237 | } | ||
238 | apr_pool_create(&tp, cfg->pool); | ||
239 | apr_pool_create(&tfp, tp); | ||
240 | |||
241 | if (APR_SUCCESS != apr_stat(&finfo, cfg->split_dir, APR_FINFO_MIN, tp)) { | ||
242 | logging_log(cfg, LOGLEVEL_NOISE, "SPLITTER: Directory %s does not exist", cfg->split_dir); | ||
243 | return; | ||
244 | } | ||
245 | foundfiles = apr_array_copy(tp, cfg->input_files); | ||
246 | apr_array_clear(cfg->input_files); | ||
247 | |||
248 | filelist = (config_filestat_t *)foundfiles->elts; | ||
249 | for (f=0, l=foundfiles->nelts; f < l; f++) { | ||
250 | apr_pool_clear(tfp); | ||
251 | logging_log(cfg, LOGLEVEL_NOTICE, "SPLITTER: Begin Splitting Log File '%s'", filelist[f].fname); | ||
252 | rv = apr_file_open(&infile, filelist[f].fname, APR_FOPEN_READ, APR_OS_DEFAULT, tfp); | ||
253 | |||
254 | if (rv != APR_SUCCESS) { | ||
255 | logging_log(cfg, LOGLEVEL_NOISE, "SPLITTER: Could not open %s", filelist[f].fname); | ||
256 | return; | ||
257 | } | ||
258 | linecount = 0; | ||
259 | while (apr_file_eof(infile) == APR_SUCCESS) { | ||
260 | apr_size_t read = BUFFER_SIZE; | ||
261 | char *p; | ||
262 | apr_file_read(infile, buff, &read); | ||
263 | p = buff; | ||
264 | while ((p = memchr(p, '\n', (buff + read) - p))) { | ||
265 | ++p; | ||
266 | ++linecount; | ||
267 | } | ||
268 | } | ||
269 | printf("Lines %'d\n",linecount); | ||
270 | // now we know how long it is. Lets split up the file | ||
271 | piecesize = linecount / cfg->split_count; | ||
272 | if (piecesize < cfg->split_minimum) | ||
273 | piecesize = cfg->split_minimum; | ||
274 | if (piecesize > cfg->split_maximum && cfg->split_maximum > 0) | ||
275 | piecesize = cfg->split_maximum; | ||
276 | printf("Piece size %'d\n", piecesize); | ||
277 | if (piecesize > linecount) { | ||
278 | // File is smaller than piece size just add it back in as is | ||
279 | newfile = (config_filestat_t *)apr_array_push(cfg->input_files); | ||
280 | newfile->result = "Not Parsed"; | ||
281 | newfile->fname = filelist[f].fname; | ||
282 | } else { | ||
283 | //split apart the files | ||
284 | int cur_line = 0; | ||
285 | int file_count = 1; | ||
286 | int out_lines = 0; | ||
287 | const char *basefile, *file; | ||
288 | apr_file_t *outfile; | ||
289 | char trail[2048]; | ||
290 | apr_size_t trail_size = 0; | ||
291 | apr_size_t write; | ||
292 | apr_off_t off = 0; | ||
293 | |||
294 | apr_file_seek(infile, APR_SET, &off); | ||
295 | |||
296 | basefile = apr_pstrdup(tfp, basename(apr_pstrdup(tfp, filelist[f].fname))); | ||
297 | |||
298 | file = apr_psprintf(tfp, "%s/%s-%d", cfg->split_dir, basefile, file_count++); | ||
299 | printf("Out file %s\n", file); | ||
300 | logging_log(cfg, LOGLEVEL_NOTICE, "SPLITTER: Creating output file %s", file); | ||
301 | rv = apr_file_open(&outfile, file, APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE, APR_OS_DEFAULT, tfp); | ||
302 | if (rv != APR_SUCCESS) { | ||
303 | logging_log(cfg, LOGLEVEL_NOISE, "SPLITTER: Could not open %s (%d)", file, rv); | ||
304 | return; | ||
305 | } | ||
306 | newfile = (config_filestat_t *)apr_array_push(cfg->input_files); | ||
307 | newfile->result = "Not Parsed"; | ||
308 | newfile->fname = apr_pstrdup(cfg->pool, file); | ||
309 | |||
310 | while (apr_file_eof(infile) == APR_SUCCESS) { | ||
311 | apr_size_t read = BUFFER_SIZE; | ||
312 | char *p, *pp, *buff_start; | ||
313 | apr_file_read(infile, buff, &read); | ||
314 | buff_start = p = pp = buff; | ||
315 | if (trail_size) { | ||
316 | p = memchr(p, '\n', (buff + read) - p); | ||
317 | if (p) { | ||
318 | //printf("Trail Line: %p, %p, %d\n", pp, p, (p - pp) + trail_size); | ||
319 | ++p; | ||
320 | pp = p; | ||
321 | ++cur_line; | ||
322 | ++out_lines; | ||
323 | // write out to file | ||
324 | apr_file_write(outfile, trail, &trail_size); | ||
325 | trail_size = 0; | ||
326 | } else { | ||
327 | if ((read + trail_size) > 2048) { | ||
328 | logging_log(cfg, LOGLEVEL_NOISE, "SPLITTER: Excessively long line %d in file %s", cur_line, filelist[f].fname); | ||
329 | exit(1); | ||
330 | } else { | ||
331 | memcpy(trail+trail_size, buff, read); | ||
332 | trail_size += read; | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | while ((p = memchr(p, '\n', (buff + read) - p))) { | ||
337 | //printf("Line: %p, %p, %d\n", pp, p, (p - pp)); | ||
338 | if (out_lines == piecesize) { | ||
339 | // Write out to file | ||
340 | write = pp - buff_start; | ||
341 | apr_file_write(outfile, buff_start, &write); | ||
342 | buff_start = pp; | ||
343 | out_lines = 0; | ||
344 | // Open new file | ||
345 | file = apr_psprintf(tfp, "%s/%s-%d", cfg->split_dir, basefile, file_count++); | ||
346 | printf("Out file %s\n", file); | ||
347 | logging_log(cfg, LOGLEVEL_NOTICE, "SPLITTER: Creating output file %s", file); | ||
348 | rv = apr_file_open(&outfile, file, APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE, APR_OS_DEFAULT, tfp); | ||
349 | if (rv != APR_SUCCESS) { | ||
350 | logging_log(cfg, LOGLEVEL_NOISE, "SPLITTER: Could not open %s (%d)", file, rv); | ||
351 | return; | ||
352 | } | ||
353 | newfile = (config_filestat_t *)apr_array_push(cfg->input_files); | ||
354 | newfile->result = "Not Parsed"; | ||
355 | newfile->fname = apr_pstrdup(cfg->pool, file); | ||
356 | } | ||
357 | ++p; | ||
358 | pp = p; | ||
359 | ++cur_line; | ||
360 | ++out_lines; | ||
361 | } | ||
362 | // Write out to file | ||
363 | write = pp - buff_start; | ||
364 | apr_file_write(outfile, buff_start, &write); | ||
365 | |||
366 | trail_size = (buff+read) - pp; | ||
367 | if (trail_size) { | ||
368 | memcpy(trail, pp, trail_size); | ||
369 | } | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | apr_pool_destroy(tfp); | ||
374 | apr_pool_destroy(tp); | ||
375 | } | ||
376 | |||
215 | apr_status_t parser_logbadline(config_t *cfg, const char *filename, | 377 | apr_status_t parser_logbadline(config_t *cfg, const char *filename, |
216 | const char *badline) | 378 | const char *badline) |
217 | { | 379 | { |
@@ -392,6 +554,7 @@ apr_status_t parser_parsefile(config_t *cfg, config_filestat_t *fstat) | |||
392 | apr_file_t *file; | 554 | apr_file_t *file; |
393 | apr_status_t rv; | 555 | apr_status_t rv; |
394 | char buff[2048]; | 556 | char buff[2048]; |
557 | char readbuff[BUFFER_SIZE]; | ||
395 | char **targv; | 558 | char **targv; |
396 | int targc; | 559 | int targc; |
397 | 560 | ||
@@ -400,8 +563,8 @@ apr_status_t parser_parsefile(config_t *cfg, config_filestat_t *fstat) | |||
400 | 563 | ||
401 | logging_log(cfg, LOGLEVEL_NOTICE, "PARSER: Begin Parsing Log File '%s'", fstat->fname); | 564 | logging_log(cfg, LOGLEVEL_NOTICE, "PARSER: Begin Parsing Log File '%s'", fstat->fname); |
402 | 565 | ||
403 | rv = apr_file_open(&file, fstat->fname, APR_FOPEN_READ | APR_BUFFERED, | 566 | rv = apr_file_open(&file, fstat->fname, APR_FOPEN_READ, APR_OS_DEFAULT, tp); |
404 | APR_OS_DEFAULT, tp); | 567 | apr_file_buffer_set(file, readbuff, BUFFER_SIZE); |
405 | if (rv != APR_SUCCESS) { | 568 | if (rv != APR_SUCCESS) { |
406 | logging_log(cfg, LOGLEVEL_NOISE, "PARSER: Could not open %s", fstat->fname); | 569 | logging_log(cfg, LOGLEVEL_NOISE, "PARSER: Could not open %s", fstat->fname); |
407 | return rv; | 570 | return rv; |