1 package org.apache.maven.cli.event;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Date;
23
24 import org.apache.maven.execution.AbstractExecutionListener;
25 import org.apache.maven.execution.BuildFailure;
26 import org.apache.maven.execution.BuildSuccess;
27 import org.apache.maven.execution.BuildSummary;
28 import org.apache.maven.execution.ExecutionEvent;
29 import org.apache.maven.execution.MavenExecutionResult;
30 import org.apache.maven.execution.MavenSession;
31 import org.apache.maven.plugin.MojoExecution;
32 import org.apache.maven.project.MavenProject;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36
37
38
39
40
41 public class ExecutionEventLogger
42 extends AbstractExecutionListener
43 {
44 private final Logger logger;
45
46 private static final int LINE_LENGTH = 72;
47
48 public ExecutionEventLogger()
49 {
50 logger = LoggerFactory.getLogger( ExecutionEventLogger.class );
51 }
52
53
54 public ExecutionEventLogger( Logger logger )
55 {
56 if ( logger == null )
57 {
58 throw new IllegalArgumentException( "logger missing" );
59 }
60
61 this.logger = logger;
62 }
63
64 private static String chars( char c, int count )
65 {
66 StringBuilder buffer = new StringBuilder( count );
67
68 for ( int i = count; i > 0; i-- )
69 {
70 buffer.append( c );
71 }
72
73 return buffer.toString();
74 }
75
76 private static String getFormattedTime( long time )
77 {
78
79
80 long h = time / ( 60 * 60 * 1000 );
81 long m = ( time - h * 60 * 60 * 1000 ) / ( 60 * 1000 );
82 long s = ( time - h * 60 * 60 * 1000 - m * 60 * 1000 ) / 1000;
83 long ms = time % 1000;
84
85 String format;
86 if ( h > 0 )
87 {
88 format = "%1$d:%2$02d:%3$02d.%4$03ds";
89 }
90 else if ( m > 0 )
91 {
92 format = "%2$d:%3$02d.%4$03ds";
93 }
94 else
95 {
96 format = "%3$d.%4$03ds";
97 }
98
99 return String.format( format, h, m, s, ms );
100 }
101
102 @Override
103 public void projectDiscoveryStarted( ExecutionEvent event )
104 {
105 if ( logger.isInfoEnabled() )
106 {
107 logger.info( "Scanning for projects..." );
108 }
109 }
110
111 @Override
112 public void sessionStarted( ExecutionEvent event )
113 {
114 if ( logger.isInfoEnabled() && event.getSession().getProjects().size() > 1 )
115 {
116 logger.info( chars( '-', LINE_LENGTH ) );
117
118 logger.info( "Reactor Build Order:" );
119
120 logger.info( "" );
121
122 for ( MavenProject project : event.getSession().getProjects() )
123 {
124 logger.info( project.getName() );
125 }
126 }
127 }
128
129 @Override
130 public void sessionEnded( ExecutionEvent event )
131 {
132 if ( logger.isInfoEnabled() )
133 {
134 if ( event.getSession().getProjects().size() > 1 )
135 {
136 logReactorSummary( event.getSession() );
137 }
138
139 logResult( event.getSession() );
140
141 logStats( event.getSession() );
142
143 logger.info( chars( '-', LINE_LENGTH ) );
144 }
145 }
146
147 private void logReactorSummary( MavenSession session )
148 {
149 logger.info( chars( '-', LINE_LENGTH ) );
150
151 logger.info( "Reactor Summary:" );
152
153 logger.info( "" );
154
155 MavenExecutionResult result = session.getResult();
156
157 for ( MavenProject project : session.getProjects() )
158 {
159 StringBuilder buffer = new StringBuilder( 128 );
160
161 buffer.append( project.getName() );
162
163 buffer.append( ' ' );
164 while ( buffer.length() < LINE_LENGTH - 21 )
165 {
166 buffer.append( '.' );
167 }
168 buffer.append( ' ' );
169
170 BuildSummary buildSummary = result.getBuildSummary( project );
171
172 if ( buildSummary == null )
173 {
174 buffer.append( "SKIPPED" );
175 }
176 else if ( buildSummary instanceof BuildSuccess )
177 {
178 buffer.append( "SUCCESS [" );
179 buffer.append( getFormattedTime( buildSummary.getTime() ) );
180 buffer.append( "]" );
181 }
182 else if ( buildSummary instanceof BuildFailure )
183 {
184 buffer.append( "FAILURE [" );
185 buffer.append( getFormattedTime( buildSummary.getTime() ) );
186 buffer.append( "]" );
187 }
188
189 logger.info( buffer.toString() );
190 }
191 }
192
193 private void logResult( MavenSession session )
194 {
195 logger.info( chars( '-', LINE_LENGTH ) );
196
197 if ( session.getResult().hasExceptions() )
198 {
199 logger.info( "BUILD FAILURE" );
200 }
201 else
202 {
203 logger.info( "BUILD SUCCESS" );
204 }
205 }
206
207 private void logStats( MavenSession session )
208 {
209 logger.info( chars( '-', LINE_LENGTH ) );
210
211 Date finish = new Date();
212
213 long time = finish.getTime() - session.getRequest().getStartTime().getTime();
214
215 String wallClock = session.getRequest().isThreadConfigurationPresent() ? " (Wall Clock)" : "";
216
217 logger.info( "Total time: " + getFormattedTime( time ) + wallClock );
218
219 logger.info( "Finished at: " + finish );
220
221 System.gc();
222
223 Runtime r = Runtime.getRuntime();
224
225 long MB = 1024 * 1024;
226
227 logger.info( "Final Memory: " + ( r.totalMemory() - r.freeMemory() ) / MB + "M/" + r.totalMemory() / MB + "M" );
228 }
229
230 @Override
231 public void projectSkipped( ExecutionEvent event )
232 {
233 if ( logger.isInfoEnabled() )
234 {
235 logger.info( chars( ' ', LINE_LENGTH ) );
236 logger.info( chars( '-', LINE_LENGTH ) );
237
238 logger.info( "Skipping " + event.getProject().getName() );
239 logger.info( "This project has been banned from the build due to previous failures." );
240
241 logger.info( chars( '-', LINE_LENGTH ) );
242 }
243 }
244
245 @Override
246 public void projectStarted( ExecutionEvent event )
247 {
248 if ( logger.isInfoEnabled() )
249 {
250 logger.info( chars( ' ', LINE_LENGTH ) );
251 logger.info( chars( '-', LINE_LENGTH ) );
252
253 logger.info( "Building " + event.getProject().getName() + " " + event.getProject().getVersion() );
254
255 logger.info( chars( '-', LINE_LENGTH ) );
256 }
257 }
258
259 @Override
260 public void mojoSkipped( ExecutionEvent event )
261 {
262 if ( logger.isWarnEnabled() )
263 {
264 logger.warn( "Goal " + event.getMojoExecution().getGoal()
265 + " requires online mode for execution but Maven is currently offline, skipping" );
266 }
267 }
268
269
270
271
272 @Override
273 public void mojoStarted( ExecutionEvent event )
274 {
275 if ( logger.isInfoEnabled() )
276 {
277 StringBuilder buffer = new StringBuilder( 128 );
278
279 buffer.append( "--- " );
280 append( buffer, event.getMojoExecution() );
281 append( buffer, event.getProject() );
282 buffer.append( " ---" );
283
284 logger.info( "" );
285 logger.info( buffer.toString() );
286 }
287 }
288
289
290
291
292 @Override
293 public void forkStarted( ExecutionEvent event )
294 {
295 if ( logger.isInfoEnabled() )
296 {
297 StringBuilder buffer = new StringBuilder( 128 );
298
299 buffer.append( ">>> " );
300 append( buffer, event.getMojoExecution() );
301 append( buffer, event.getProject() );
302 buffer.append( " >>>" );
303
304 logger.info( "" );
305 logger.info( buffer.toString() );
306 }
307 }
308
309
310
311
312 @Override
313 public void forkSucceeded( ExecutionEvent event )
314 {
315 if ( logger.isInfoEnabled() )
316 {
317 StringBuilder buffer = new StringBuilder( 128 );
318
319 buffer.append( "<<< " );
320 append( buffer, event.getMojoExecution() );
321 append( buffer, event.getProject() );
322 buffer.append( " <<<" );
323
324 logger.info( "" );
325 logger.info( buffer.toString() );
326 }
327 }
328
329 private void append( StringBuilder buffer, MojoExecution me )
330 {
331 buffer.append( me.getArtifactId() ).append( ':' ).append( me.getVersion() );
332 buffer.append( ':' ).append( me.getGoal() );
333 if ( me.getExecutionId() != null )
334 {
335 buffer.append( " (" ).append( me.getExecutionId() ).append( ')' );
336 }
337 }
338
339 private void append( StringBuilder buffer, MavenProject project )
340 {
341 buffer.append( " @ " ).append( project.getArtifactId() );
342 }
343
344 @Override
345 public void forkedProjectStarted( ExecutionEvent event )
346 {
347 if ( logger.isInfoEnabled() && event.getMojoExecution().getForkedExecutions().size() > 1 )
348 {
349 logger.info( chars( ' ', LINE_LENGTH ) );
350 logger.info( chars( '>', LINE_LENGTH ) );
351
352 logger.info( "Forking " + event.getProject().getName() + " " + event.getProject().getVersion() );
353
354 logger.info( chars( '>', LINE_LENGTH ) );
355 }
356 }
357
358 }