001    package net.sf.logdistiller.reports;
002    
003    /*
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    import java.io.IOException;
018    import java.io.PrintWriter;
019    import java.io.Writer;
020    import java.text.DateFormat;
021    import java.util.Date;
022    import java.util.Iterator;
023    
024    import org.apache.commons.lang.StringUtils;
025    import org.apache.commons.lang.SystemUtils;
026    import org.jdom.Element;
027    import org.jdom.output.Format;
028    import org.jdom.output.XMLOutputter;
029    
030    import net.sf.logdistiller.LogDistillation;
031    import net.sf.logdistiller.LogDistiller;
032    import net.sf.logdistiller.ReportFormat;
033    import net.sf.logdistiller.util.FormatUtil;
034    
035    /**
036     * Pure text report format.
037     */
038    public class TextReport
039        extends ReportFormat
040    {
041        private final static DateFormat DF = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.LONG );
042    
043        public TextReport()
044        {
045            super( "txt" );
046        }
047    
048        public String getContentType()
049        {
050            return "text/plain";
051        }
052    
053        public String getFileExtension()
054        {
055            return "txt";
056        }
057    
058        public void report( LogDistillation ld, Writer output )
059            throws IOException
060        {
061            LogDistiller definition = ld.getDefinition();
062            PrintWriter out = new PrintWriter( output );
063            out.println( "LogDistillation result (LogDistiller " + ld.getVersion() + ")" );
064            out.println();
065            out.println( "LogDistiller used: " + definition.getOutput().getId() + " - " + definition.getDescription() );
066            out.println( "log content processed: " + ( ( ld.getContent() == null ) ? "not specified" : ld.getContent() ) );
067            out.println( "distillation started on " + DF.format( new Date( ld.getBeginTime() ) ) + ", finished on "
068                + DF.format( new Date( ld.getEndTime() ) ) + ": "
069                + FormatUtil.formatPeriod( ld.getEndTime() - ld.getBeginTime() ) );
070            if ( ld.getSkippedEventCount() > 0 )
071            {
072                out.println( "skipped " + ld.getSkippedEventCount() + " events ("
073                    + FormatUtil.formatSize( ld.getSkippedEventBytes() ) + ")" );
074            }
075            String logsUrl = definition.getOutput().getUrl();
076            if ( logsUrl != null )
077            {
078                out.println( "reports and logs url: " + logsUrl );
079            }
080            Iterator iter = definition.getWarnings().iterator();
081            while ( iter.hasNext() )
082            {
083                out.println( "WARNING: " + iter.next() );
084            }
085            out.println();
086            if ( ld.getEventCount() == 0 )
087            {
088                out.println( "found 0 event to classify." );
089            }
090            else
091            {
092                out.println( "found " + ld.getEventCount() + " events (" + FormatUtil.formatSize( ld.getEventBytes() )
093                    + ") classified as follow:" );
094                // report for categories, and corresponding groups
095                Iterator categoriesIterator = ld.listCategoriesToReport().iterator();
096                while ( categoriesIterator.hasNext() )
097                {
098                    LogDistillation.Category category = (LogDistillation.Category) categoriesIterator.next();
099                    int categoryEventCount = category.sumEventCount();
100                    LogDistiller.Category categoryDefinition = category.getDefinition();
101                    out.println( "*** " + categoryEventCount + " " + categoryDefinition.getId() + " ("
102                        + FormatUtil.formatFraction( categoryEventCount, ld.getEventCount() ) + "): "
103                        + categoryDefinition.getDescription() );
104                    int countLength = String.valueOf( categoryEventCount ).length();
105                    iter = category.listGroupsToReport().iterator();
106                    while ( iter.hasNext() )
107                    {
108                        LogDistillation.Group group = (LogDistillation.Group) iter.next();
109                        String fraction = formatFraction( group.getEventCount(), categoryEventCount );
110                        out.println( "*" + fraction + ' ' + formatGroup( group, countLength, ld.getEventCount() ) );
111                        addPluginsGlobalReport( group, new TextPluginReport( out, "*       ", group.getEventCount() ) );
112                    }
113                    out.println();
114                }
115    
116                // report for groups without category
117                int countLength = String.valueOf( ld.getEventCount() ).length();
118                Iterator groupsIterator = ld.listGroupsToReport().iterator();
119                while ( groupsIterator.hasNext() )
120                {
121                    LogDistillation.Group group = (LogDistillation.Group) groupsIterator.next();
122                    out.println( formatGroup( group, countLength, ld.getEventCount() ) );
123                    addPluginsGlobalReport( group, new TextPluginReport( out, "   ", group.getEventCount() ) );
124                }
125            }
126            out.flush();
127        }
128    
129        private String formatGroup( LogDistillation.Group group, int countLength, int eventCount )
130        {
131            int groupEventCount = group.getEventCount();
132            LogDistiller.Group groupDefinition = group.getDefinition();
133            String sep = groupDefinition.continueProcessing() ? "+ " : "- ";
134            return sep + StringUtils.leftPad( String.valueOf( groupEventCount ), countLength ) + " ("
135                + formatFraction( groupEventCount, eventCount ) + ") " + groupDefinition.getId() + ": "
136                + groupDefinition.getDescription();
137        }
138    
139        private String formatFraction( long fraction, long total )
140        {
141            return StringUtils.leftPad( FormatUtil.formatFraction( fraction, total ), 6 );
142        }
143    
144        public void report( LogDistillation.Group group, Writer output )
145            throws IOException
146        {
147            LogDistiller.Group definition = group.getDefinition();
148            PrintWriter out = new PrintWriter( output );
149            out.println( "LogDistillation group result (LogDistiller " + LogDistiller.getVersion() + ")" );
150            out.println();
151            out.println( "LogDistiller group: " + definition.getId() + " - " + definition.getDescription() );
152            out.println( "for LogDistiller: " + definition.getLogdistiller().getOutput().getId() + " - "
153                + definition.getLogdistiller().getDescription() );
154            out.println( "log content processed: "
155                + ( ( group.getLogdistillation().getContent() == null ) ? "not specified"
156                                : group.getLogdistillation().getContent() ) );
157            out.println( "found " + group.getEventCount() + " events (" + FormatUtil.formatSize( group.getBytes() )
158                + ") matching following definition:" );
159            Element elmt = new Element( "conditions" );
160            definition.dumpConditions( elmt );
161            if ( elmt.getContentSize() > 0 )
162            {
163                out.print( "  " );
164                new XMLOutputter( Format.getPrettyFormat().setLineSeparator( SystemUtils.LINE_SEPARATOR + "  " ) ).outputElementContent(
165                                                                                                                                         elmt,
166                                                                                                                                         output );
167                out.println();
168            }
169            else
170            {
171                out.println( "  no condition specified: every log event accepted" );
172            }
173    
174            String logsUrl = definition.getLogdistiller().getOutput().getUrl();
175            if ( definition.getSave() )
176            {
177                out.println( "log events saved in file: " + group.getLogFile().getAbsolutePath() );
178                out.print( "max save count: " );
179                if ( group.getMaxSaveCount() < 0 )
180                {
181                    out.println( "none" );
182                }
183                else
184                {
185                    out.println( String.valueOf( group.getMaxSaveCount() ) );
186                }
187                out.print( "max save size: " );
188                if ( group.getMaxSaveBytes() < 0 )
189                {
190                    out.println( "none" );
191                }
192                else
193                {
194                    out.println( String.valueOf( group.getMaxSaveBytes() / 1024 ) + " kb" );
195                }
196                if ( group.getSavedEventCount() < group.getEventCount() )
197                {
198                    out.println( "save limit reached: " + group.getSavedEventCount() + " events" );
199                }
200                if ( logsUrl != null )
201                {
202                    out.println( "log events url: "
203                        + definition.getLogdistiller().getOutput().getUrl( group.getLogFile().getName() ) );
204                }
205            }
206            else
207            {
208                out.println( "log events not saved" );
209            }
210            if ( logsUrl != null )
211            {
212                out.println( "reports and logs url: " + logsUrl );
213            }
214            if ( definition.continueProcessing() )
215            {
216                out.println( "continueProcessing: true" );
217            }
218            out.println();
219            addPluginsGroupReport( group, new TextPluginReport( out, "", group.getEventCount() ) );
220            out.flush();
221        }
222    
223        private static class TextPluginReport
224            extends PluginReport
225        {
226            private final PrintWriter out;
227    
228            private final String prefix;
229    
230            private final int groupEventCount;
231    
232            private final int countLength;
233    
234            public TextPluginReport( PrintWriter out, String prefix, int groupEventCount )
235            {
236                this.out = out;
237                this.prefix = prefix;
238                this.groupEventCount = groupEventCount;
239                countLength = String.valueOf( groupEventCount ).length();
240            }
241    
242            public void beginPluginReport( LogDistillation.Plugin plugin, String description )
243            {
244                out.println( prefix + plugin.getDefinition().getType() + ": " + description );
245            }
246    
247            public void addLink( String filename, String description )
248            {
249                out.println( prefix + "file " + filename + ": " + description );
250            }
251    
252            public void addParam( String param, String value )
253            {
254                out.println( prefix + param + ": " + value );
255            }
256    
257            public void addItem( int count, String description )
258            {
259                out.println( prefix + "  # " + StringUtils.leftPad( String.valueOf( count ), countLength ) + " ("
260                    + StringUtils.leftPad( FormatUtil.formatFraction( count, groupEventCount ), 6 ) + ") " + description );
261            }
262    
263            public void endPluginReport()
264            {
265                out.println( prefix.trim() );
266            }
267        }
268    }