1 package net.sf.logdistiller;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import java.io.*;
18 import java.util.*;
19
20 import org.apache.commons.io.IOUtils;
21 import org.apache.commons.lang.ArrayUtils;
22
23
24
25
26
27
28
29
30 public class LogDistillation
31 implements Serializable
32 {
33 private static final long serialVersionUID = -9098523382541148543L;
34
35 public final static String LINE_SEPARATOR = System.getProperty( "line.separator" );
36
37 private final LogDistiller ld;
38
39 private final Group[] groups;
40
41 private final Category[] categories;
42
43 private final String content;
44
45 private final File destinationDirectory;
46
47 private final String version = LogDistiller.getVersion();
48
49 private transient Map<String, Group> mapGroups;
50
51 private transient Map<String, Category> mapCategories;
52
53 private long beginTime;
54
55 private long endTime;
56
57 private int eventCount = -1;
58
59 private long eventBytes = 0;
60
61 private int skippedEventCount = 0;
62
63 private long skippedEventBytes = 0;
64
65 private transient LogType.Description logtypeDescription;
66
67 public LogDistillation( LogDistiller ld )
68 {
69 this.ld = ld;
70
71
72 LogDistiller.Category[] categoryDefinitions = ld.getCategories();
73 int length = categoryDefinitions.length;
74 categories = new Category[length];
75 mapCategories = new HashMap<String, Category>();
76 for ( int i = 0; i < length; i++ )
77 {
78 categories[i] = new Category( categoryDefinitions[i] );
79 mapCategories.put( categoryDefinitions[i].getId(), categories[i] );
80 }
81
82
83 LogDistiller.Group[] groupDefinitions = ld.getGroups();
84 length = groupDefinitions.length;
85 groups = new Group[length];
86 for ( int i = 0; i < length; i++ )
87 {
88 LogDistiller.Group groupDefinition = groupDefinitions[i];
89 LogDistiller.Category categoryDefinition = groupDefinition.getCategory();
90 Category category =
91 ( categoryDefinition == null ) ? null : (Category) mapCategories.get( categoryDefinition.getId() );
92 groups[i] = new Group( groupDefinition, category );
93 }
94
95
96 content = ld.getOutput().getContent();
97 destinationDirectory = new File( ld.getOutput().getDirectory() );
98 updateRef();
99 }
100
101
102
103
104
105 private LogType.Description newLogTypeDescription()
106 {
107 LogDistiller.LogType lt = ld.getLogType();
108
109 LogType logtype = LogTypes.getLogType( lt.getId() );
110 LogType.Description logtypeDescription = logtype.newDescription( ld.getLogType().getParams() );
111 logtypeDescription.setExtensions( ld.getLogType().getExtensions() );
112 ld.checkLogtypeAttributes( logtypeDescription );
113
114 return logtypeDescription;
115 }
116
117
118
119
120 private void updateRef()
121 {
122 String skip = ld.getOutput().getSkip();
123
124
125 mapCategories = new HashMap<String, Category>();
126 Category skipCategory = null;
127 int len = categories.length;
128 for ( int i = 0; i < len; i++ )
129 {
130 Category category = categories[i];
131 mapCategories.put( category.getDefinition().getId(), category );
132 category.updateRef( this );
133
134 if ( category.getDefinition().getId().equals( skip ) )
135 {
136 skipCategory = category;
137 }
138 }
139
140
141 mapGroups = new HashMap<String, Group>();
142 len = groups.length;
143 for ( int i = 0; i < len; i++ )
144 {
145 Group group = groups[i];
146 mapGroups.put( group.getDefinition().getId(), group );
147 group.updateRef( this );
148
149 if ( group.getDefinition().getId().equals( skip ) )
150 {
151 group.setSkip( true );
152 }
153 }
154
155 if ( skipCategory != null )
156 {
157 skipCategory.setSkip( true );
158 }
159
160 logtypeDescription = newLogTypeDescription();
161 }
162
163 private void readObject( ObjectInputStream in )
164 throws IOException, ClassNotFoundException
165 {
166 in.defaultReadObject();
167 if ( ld.getOutput() != null )
168 {
169 ld.updateRef();
170 updateRef();
171 }
172 }
173
174
175
176
177
178
179 public void begin()
180 throws IOException
181 {
182 destinationDirectory.mkdirs();
183 int count = groups.length;
184 for ( int i = 0; i < count; i++ )
185 {
186 groups[i].begin( destinationDirectory );
187 }
188 eventCount = 0;
189 beginTime = System.currentTimeMillis();
190 }
191
192
193
194
195
196
197
198 public void processLogEvent( LogEvent le )
199 throws IOException
200 {
201 if ( eventCount < 0 )
202 {
203 throw new IllegalStateException( "LogDistiller not initialized: need to call begin() before processing" );
204 }
205 eventCount++;
206 int eventSize = le.getRawLog().length() + LINE_SEPARATOR.length();
207 eventBytes += eventSize;
208 int count = groups.length;
209 for ( int i = 0; i < count; i++ )
210 {
211 Group group = groups[i];
212 if ( group.accept( le ) )
213 {
214 if ( group.isSkip() )
215 {
216
217 eventCount--;
218 eventBytes -= eventSize;
219 skippedEventCount++;
220 skippedEventBytes += eventSize;
221 break;
222 }
223 if ( !group.getDefinition().continueProcessing() )
224 {
225 break;
226 }
227 }
228 }
229 }
230
231
232
233
234
235
236 public void end()
237 throws IOException
238 {
239 endTime = System.currentTimeMillis();
240 int count = groups.length;
241 for ( int i = 0; i < count; i++ )
242 {
243 Group group = groups[i];
244 group.end();
245 }
246 saveTo( newDestinationFile( "result.ser" ) );
247 }
248
249
250
251
252
253
254 public void saveTo( File file )
255 throws IOException
256 {
257 OutputStream out = null;
258 try
259 {
260 out = new FileOutputStream( file );
261 saveTo( out );
262 }
263 finally
264 {
265 IOUtils.closeQuietly( out );
266 }
267 }
268
269 public void saveTo( OutputStream out )
270 throws IOException
271 {
272 ObjectOutputStream obj = new ObjectOutputStream( out );
273 obj.writeObject( this );
274 }
275
276 public List<Category> listCategoriesToReport()
277 {
278 List<Category> reportCategories = new ArrayList<Category>();
279 int count = categories.length;
280 for ( int i = 0; i < count; i++ )
281 {
282 Category category = categories[i];
283 if ( ( !category.isSkip() ) && ( category.sumEventCount() > 0 ) )
284 {
285 reportCategories.add( category );
286 }
287 }
288 return reportCategories;
289 }
290
291 public List<Group> listGroupsToReport()
292 {
293 List<Group> reportGroups = new ArrayList<Group>();
294 int count = groups.length;
295 for ( int i = 0; i < count; i++ )
296 {
297 Group group = groups[i];
298 if ( ( !group.isSkip() ) && ( group.getEventCount() > 0 ) && ( group.getCategory() == null ) )
299 {
300 reportGroups.add( group );
301 }
302 }
303 return reportGroups;
304 }
305
306 public LogDistiller getDefinition()
307 {
308 return ld;
309 }
310
311 public Group[] getGroups()
312 {
313 return (Group[]) ArrayUtils.clone( groups );
314 }
315
316 public Group getGroup( String id )
317 {
318 return mapGroups.get( id );
319 }
320
321 public Category[] getCategories()
322 {
323 return (Category[]) ArrayUtils.clone( categories );
324 }
325
326 public Category getCategory( String id )
327 {
328 return mapCategories.get( id );
329 }
330
331 public String getContent()
332 {
333 return content;
334 }
335
336 public int getEventCount()
337 {
338 return eventCount;
339 }
340
341 public long getEventBytes()
342 {
343 return eventBytes;
344 }
345
346 public long getBeginTime()
347 {
348 return beginTime;
349 }
350
351 public long getEndTime()
352 {
353 return endTime;
354 }
355
356 public int getSkippedEventCount()
357 {
358 return skippedEventCount;
359 }
360
361 public long getSkippedEventBytes()
362 {
363 return skippedEventBytes;
364 }
365
366 public File newDestinationFile( String filename )
367 {
368 return new File( destinationDirectory, filename );
369 }
370
371 public LogType.Description getLogTypeDescription()
372 {
373 return logtypeDescription;
374 }
375
376
377
378
379
380
381 public String getVersion()
382 {
383 return ( version == null ) ? "unknown" : version;
384 }
385
386 public class Group
387 implements Serializable
388 {
389 private static final long serialVersionUID = 5788707827350407084L;
390
391 private final LogDistiller.Group definition;
392
393 private final Category category;
394
395 private transient LogDistillation logdistillation;
396
397 private boolean skip = false;
398
399
400
401
402
403
404 private final int maxSaveCount;
405
406
407
408
409
410
411 private final long maxSaveBytes;
412
413 private final Plugin[] plugins;
414
415 private File logFile;
416
417 private transient PrintStream logStream;
418
419 private int eventCount = 0;
420
421 private int savedEventCount = 0;
422
423 private long bytes = 0;
424
425 public Group( LogDistiller.Group definition, Category category )
426 {
427 this.definition = definition;
428 this.category = category;
429 maxSaveCount = Integer.parseInt( definition.getParam( "maxSave.count", "-1" ) );
430 maxSaveBytes = Long.parseLong( definition.getParam( "maxSave.size", "-1" ) ) * 1024;
431 LogDistiller.Plugin[] pluginDefs = definition.getPlugins();
432 plugins = new Plugin[pluginDefs.length];
433 for ( int i = 0; i < pluginDefs.length; i++ )
434 {
435 plugins[i] = Plugins.newInstance( pluginDefs[i] );
436 }
437 }
438
439 private void updateRef( LogDistillation logdistillation )
440 {
441 this.logdistillation = logdistillation;
442 if ( category != null )
443 {
444 category.addGroup( this );
445 }
446 int len = plugins.length;
447 for ( int i = 0; i < len; i++ )
448 {
449 plugins[i].updateRef( this );
450 }
451 }
452
453 public LogDistillation getLogdistillation()
454 {
455 return logdistillation;
456 }
457
458 public Category getCategory()
459 {
460 return category;
461 }
462
463 public void setSkip( boolean skip )
464 {
465 this.skip = skip;
466 }
467
468 public boolean isSkip()
469 {
470 return skip;
471 }
472
473
474
475
476
477
478
479
480 public boolean accept( LogEvent le )
481 throws IOException
482 {
483 Condition condition = definition.accept( le );
484 if ( condition != null )
485 {
486 addLogEvent( le, condition );
487 return true;
488 }
489 return false;
490 }
491
492
493
494
495
496
497
498
499 protected void addLogEvent( LogEvent le, Condition condition )
500 throws IOException
501 {
502 eventCount++;
503 bytes += le.getRawLog().length() + LINE_SEPARATOR.length();
504 if ( definition.getSave() && ( ( maxSaveCount < 0 ) || ( eventCount <= maxSaveCount ) )
505 && ( ( maxSaveBytes < 0 ) || ( bytes <= maxSaveBytes ) ) )
506 {
507 if ( logStream == null )
508 {
509 logStream = new PrintStream( new FileOutputStream( logFile ) );
510 }
511 logStream.println( le.getRawLog() );
512 savedEventCount++;
513 }
514 int len = plugins.length;
515 for ( int i = 0; i < len; i++ )
516 {
517 plugins[i].addLogEvent( le, condition );
518 }
519 }
520
521 void begin( File destinationDirectory )
522 throws IOException
523 {
524 logFile = newDestinationFile( definition.getId() + ".log" );
525 int len = plugins.length;
526 for ( int i = 0; i < len; i++ )
527 {
528 plugins[i].begin( destinationDirectory );
529 }
530 }
531
532 void end()
533 throws IOException
534 {
535 if ( logStream != null )
536 {
537 logStream.close();
538 }
539 int len = plugins.length;
540 for ( int i = 0; i < len; i++ )
541 {
542 plugins[i].end();
543 }
544 }
545
546 public LogDistiller.Group getDefinition()
547 {
548 return definition;
549 }
550
551 public int getEventCount()
552 {
553 return eventCount;
554 }
555
556 public int getSavedEventCount()
557 {
558 return savedEventCount;
559 }
560
561 public long getBytes()
562 {
563 return bytes;
564 }
565
566 public File getLogFile()
567 {
568 return logFile;
569 }
570
571 public int getMaxSaveCount()
572 {
573 return maxSaveCount;
574 }
575
576 public long getMaxSaveBytes()
577 {
578 return maxSaveBytes;
579 }
580
581 public Plugin[] getPlugins()
582 {
583 return (Plugin[]) ArrayUtils.clone( plugins );
584 }
585 }
586
587 public static class Category
588 implements Serializable
589 {
590 private static final long serialVersionUID = 7098883103191641753L;
591
592 private final LogDistiller.Category definition;
593
594 private transient LogDistillation logdistillation;
595
596 private transient List<Group> groups;
597
598 private boolean skip = false;
599
600 public Category( LogDistiller.Category definition )
601 {
602 this.definition = definition;
603 }
604
605 private void updateRef( LogDistillation logdistillation )
606 {
607 this.logdistillation = logdistillation;
608 groups = new ArrayList<Group>();
609 }
610
611 public LogDistillation getLogdistillation()
612 {
613 return logdistillation;
614 }
615
616 public LogDistiller.Category getDefinition()
617 {
618 return definition;
619 }
620
621 private void addGroup( Group group )
622 {
623 groups.add( group );
624 }
625
626 public List<Group> getGroups()
627 {
628 return groups;
629 }
630
631 public void setSkip( boolean skip )
632 {
633 this.skip = skip;
634 for ( Group group : groups )
635 {
636 group.setSkip( skip );
637 }
638 }
639
640 public boolean isSkip()
641 {
642 return skip;
643 }
644
645 public int sumEventCount()
646 {
647 int sum = 0;
648 for ( Group group : groups )
649 {
650 sum += group.getEventCount();
651 }
652 return sum;
653 }
654
655 public long sumBytes()
656 {
657 long sum = 0;
658 for ( Group group : groups )
659 {
660 sum += group.getBytes();
661 }
662 return sum;
663 }
664
665 public List<Group> listGroupsToReport()
666 {
667 List<Group> reportGroups = new ArrayList<Group>();
668 for ( Group group : groups )
669 {
670 if ( group.getEventCount() > 0 )
671 {
672 reportGroups.add( group );
673 }
674 }
675 return reportGroups;
676 }
677 }
678
679 public static abstract class Plugin
680 implements Serializable
681 {
682 private static final long serialVersionUID = -722318023109374109L;
683
684 protected final LogDistiller.Plugin definition;
685
686 protected transient Group group;
687
688 public Plugin( LogDistiller.Plugin definition )
689 {
690 this.definition = definition;
691 }
692
693 private void updateRef( Group group )
694 {
695 this.group = group;
696 }
697
698 public Group getGroup()
699 {
700 return group;
701 }
702
703 public LogDistiller.Plugin getDefinition()
704 {
705 return definition;
706 }
707
708 public String getId()
709 {
710 return getDefinition().getType();
711 }
712
713
714
715
716
717
718
719 abstract public void begin( File destinationDirectory )
720 throws IOException;
721
722
723
724
725
726
727
728 abstract public void addLogEvent( LogEvent le )
729 throws IOException;
730
731
732
733
734
735
736
737
738 public void addLogEvent( LogEvent le, Condition condition )
739 throws IOException
740 {
741 addLogEvent( le );
742 }
743
744
745
746
747
748
749 abstract public void end()
750 throws IOException;
751
752
753
754
755
756
757 abstract public void appendGroupReport( ReportFormat.PluginReport report );
758
759
760
761
762
763
764 abstract public void appendGlobalReport( ReportFormat.PluginReport report );
765 }
766 }