|
1 /* |
|
2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.ant; |
|
19 |
|
20 import java.io.File; |
|
21 import java.io.FileOutputStream; |
|
22 import java.io.DataOutputStream; |
|
23 import java.io.PrintStream; |
|
24 import java.text.SimpleDateFormat; |
|
25 import java.util.Date; |
|
26 import java.util.concurrent.TimeUnit; |
|
27 import java.util.Hashtable; |
|
28 import java.util.Collections; |
|
29 import java.util.Enumeration; |
|
30 import java.util.Vector; |
|
31 |
|
32 import org.apache.tools.ant.BuildEvent; |
|
33 import org.apache.tools.ant.Project; |
|
34 import org.apache.commons.logging.Log; |
|
35 import org.apache.commons.logging.LogFactory; |
|
36 import org.apache.tools.ant.DefaultLogger; |
|
37 |
|
38 /** |
|
39 * Logger class that can connect to Ant and log information regarding to build |
|
40 * times, number of errors and such. Data is sent to Diamonds server, where it |
|
41 * is processed further. |
|
42 * |
|
43 * This class is listening all build related events. It catches the build |
|
44 * start-finish, target start-finish events of Ant and gather build start-end |
|
45 * time, errors/warnings and store in BuildData class. Stored data will be |
|
46 * exported to XML and uploaded to Diamonds server after each specific target. |
|
47 * For example after target "create-bom" this class will upload all BOM data to |
|
48 * Diamonds. |
|
49 * |
|
50 * |
|
51 */ |
|
52 public class HeliumLogger extends DefaultLogger { |
|
53 |
|
54 private static boolean stopLogToConsole; |
|
55 |
|
56 private Date endOfPreviousTarget; |
|
57 |
|
58 private Project project; |
|
59 |
|
60 private Log log = LogFactory.getLog(HeliumLogger.class); |
|
61 |
|
62 private boolean isInitialized; |
|
63 |
|
64 private String directory; |
|
65 |
|
66 private SimpleDateFormat timeFormat; |
|
67 |
|
68 private Date buildStartTime; |
|
69 |
|
70 private Date buildEndTime; |
|
71 |
|
72 private Date targetStartTime; |
|
73 |
|
74 private Hashtable targetTable; |
|
75 |
|
76 private Hashtable tempStartTime; |
|
77 |
|
78 private StringBuffer allStages; |
|
79 |
|
80 /** |
|
81 * Ant call this function when bjuild start. |
|
82 */ |
|
83 public void buildStarted(BuildEvent event) { |
|
84 project = event.getProject(); |
|
85 |
|
86 // Record build start time |
|
87 endOfPreviousTarget = new Date(); |
|
88 buildStartTime = new Date(); |
|
89 endOfPreviousTarget = new Date(); |
|
90 |
|
91 targetTable = new Hashtable(); |
|
92 tempStartTime = new Hashtable(); |
|
93 |
|
94 // For Stage start time |
|
95 allStages = new StringBuffer("\t<stages>"); |
|
96 |
|
97 super.buildStarted(event); |
|
98 } |
|
99 |
|
100 /** |
|
101 * Triggered when a target starts. |
|
102 */ |
|
103 public void targetStarted(BuildEvent event) { |
|
104 String targetName = event.getTarget().getName(); |
|
105 targetStartTime = new Date(); |
|
106 |
|
107 logTargetEvent(targetName, "start"); |
|
108 |
|
109 if (!isInitialized) { |
|
110 initializeLogger(); |
|
111 } |
|
112 if (isInitialized) { |
|
113 // Record the target start time |
|
114 tempStartTime.put(targetName, new Date()); |
|
115 } |
|
116 super.targetStarted(event); |
|
117 } |
|
118 |
|
119 private void initializeLogger() { |
|
120 directory = project.getProperty("build.log.dir"); |
|
121 isInitialized = true; |
|
122 } |
|
123 |
|
124 /** |
|
125 * Log the start or end of the build as a event. |
|
126 * |
|
127 * @param targetName |
|
128 * The name of the current target. |
|
129 * @param event |
|
130 * A string description of the event. |
|
131 */ |
|
132 private void logTargetEvent(String targetName, String event) { |
|
133 String logTargetProperty = project.getProperty("log.target"); |
|
134 if ((logTargetProperty != null) && (logTargetProperty.equals("yes"))) { |
|
135 log.info("Target #### " + targetName + " ####: " + event); |
|
136 } |
|
137 } |
|
138 |
|
139 /** |
|
140 * Triggered when a target finishes. |
|
141 */ |
|
142 public void targetFinished(BuildEvent event) { |
|
143 String targetName = event.getTarget().getName(); |
|
144 |
|
145 logTargetEvent(targetName, "finish"); |
|
146 |
|
147 logTargetTime(targetName); |
|
148 |
|
149 } |
|
150 |
|
151 private void logTargetTime(String targetName) { |
|
152 Date targetFinishTime = new Date(); |
|
153 long targetLengthMSecs = targetFinishTime.getTime() |
|
154 - targetStartTime.getTime(); |
|
155 Long outputSecs = TimeUnit.MILLISECONDS.toSeconds(targetLengthMSecs); |
|
156 targetTable.put(outputSecs, targetName); |
|
157 } |
|
158 |
|
159 /** |
|
160 * Triggered when the build finishes. |
|
161 */ |
|
162 public void buildFinished(BuildEvent event) { |
|
163 if (isInitialized) { |
|
164 if (directory != null && new File(directory).exists()) { |
|
165 try { |
|
166 // Log target times to file |
|
167 String timesLogFileName = directory + File.separator |
|
168 + "targetTimesLog.csv"; |
|
169 File timesLogFile = new File(timesLogFileName); |
|
170 |
|
171 // Sort hashtable. |
|
172 Vector v = new Vector(targetTable.keySet()); |
|
173 Collections.sort(v); |
|
174 |
|
175 FileOutputStream timesLogFileStream = new FileOutputStream( |
|
176 timesLogFileName, true); |
|
177 DataOutputStream timesLogOut = new DataOutputStream( |
|
178 timesLogFileStream); |
|
179 // Display (sorted) hashtable. |
|
180 for (Enumeration e = v.elements(); e.hasMoreElements();) { |
|
181 Long key = (Long) e.nextElement(); |
|
182 String val = (String) targetTable.get(key); |
|
183 timesLogOut.writeBytes(val + "," + key.toString() |
|
184 + "\n"); |
|
185 } |
|
186 timesLogOut.close(); |
|
187 } catch (Exception ex) { |
|
188 log.fatal("Exception has occurred", ex); |
|
189 ex.printStackTrace(); |
|
190 } |
|
191 } |
|
192 cleanup(); |
|
193 } |
|
194 super.buildFinished(event); |
|
195 } |
|
196 |
|
197 /** |
|
198 * See if build needs a final cleanup target to be called. |
|
199 */ |
|
200 private void cleanup() { |
|
201 String loggingoutputfile = project.getProperty("logging.output.file"); |
|
202 if (loggingoutputfile != null) { |
|
203 File f = new File(loggingoutputfile); |
|
204 if (f.exists()) { |
|
205 f.delete(); |
|
206 } |
|
207 } |
|
208 |
|
209 if ((project.getProperty("call.cleanup") != null) |
|
210 && (project.getProperty("call.cleanup").equals("yes"))) { |
|
211 project.executeTarget("cleanup-all"); |
|
212 } |
|
213 } |
|
214 |
|
215 /** |
|
216 * Get log to console status |
|
217 */ |
|
218 public static boolean getStopLogToConsole() { |
|
219 return stopLogToConsole; |
|
220 } |
|
221 |
|
222 /** |
|
223 * Set log to console status |
|
224 */ |
|
225 public static void setStopLogToConsole(boolean stop) { |
|
226 stopLogToConsole = stop; |
|
227 } |
|
228 |
|
229 /** |
|
230 * {@inheritDoc} |
|
231 */ |
|
232 protected void printMessage(final String message, final PrintStream stream, |
|
233 final int priority) { |
|
234 if (!stopLogToConsole) { |
|
235 stream.println(message); |
|
236 } |
|
237 } |
|
238 } |