|
Added
Link Here
|
| 1 |
package upload; |
| 2 |
|
| 3 |
import java.io.File; |
| 4 |
import java.io.FileOutputStream; |
| 5 |
import java.io.IOException; |
| 6 |
import java.io.InputStream; |
| 7 |
import java.io.PrintStream; |
| 8 |
import java.io.PrintWriter; |
| 9 |
import java.util.ArrayList; |
| 10 |
import java.util.Collections; |
| 11 |
import java.util.HashMap; |
| 12 |
import java.util.List; |
| 13 |
import java.util.Map; |
| 14 |
import java.util.zip.ZipEntry; |
| 15 |
import java.util.zip.ZipFile; |
| 16 |
|
| 17 |
public class UsageAnalysis { |
| 18 |
|
| 19 |
Map<Integer, Map<String, Integer>> userToViewMap = new HashMap<Integer, Map<String, Integer>>(); |
| 20 |
|
| 21 |
Map<Integer, Integer> usersNumSelections = new HashMap<Integer, Integer>(); |
| 22 |
|
| 23 |
Map<String, Integer> totalNumSelections = new HashMap<String, Integer>(); |
| 24 |
|
| 25 |
final static String USAGE_DIRECTORY = MylarUsageUploadServlet.UPLOAD_DIRECTORY; |
| 26 |
|
| 27 |
final static String LOGGING_DIRECTORY = "home//study//logging//"; |
| 28 |
|
| 29 |
final static String ERROR_LOGGING_FILE = "MylarUsageAnalysisErrorLog.txt"; |
| 30 |
|
| 31 |
final static String USAGE_SUMMARY_FILE = "usageSummary.txt"; |
| 32 |
|
| 33 |
int MAX_NUM_VIEWS_TO_REPORT = 10; |
| 34 |
|
| 35 |
int totalSelections = 0; |
| 36 |
|
| 37 |
public static void main(String []args) { |
| 38 |
UsageAnalysis ua = new UsageAnalysis(); |
| 39 |
ua.analyzeLogs(); |
| 40 |
} |
| 41 |
public void analyzeLogs() { |
| 42 |
|
| 43 |
try { |
| 44 |
String[] files = new File(USAGE_DIRECTORY).list(); |
| 45 |
int userID = 0; |
| 46 |
|
| 47 |
for (String filename : files) { |
| 48 |
File currFile = new File(USAGE_DIRECTORY, filename); |
| 49 |
|
| 50 |
userID = this.getUserId(currFile); |
| 51 |
|
| 52 |
int numSelections = 0; |
| 53 |
if (usersNumSelections.containsKey(userID)) { |
| 54 |
numSelections = usersNumSelections.get(userID); |
| 55 |
} |
| 56 |
|
| 57 |
Map<String, Integer> viewToNumberMap = userToViewMap.get(userID); |
| 58 |
if (viewToNumberMap == null) { |
| 59 |
viewToNumberMap = new HashMap<String, Integer>(); |
| 60 |
userToViewMap.put(userID, viewToNumberMap); |
| 61 |
} |
| 62 |
|
| 63 |
int index; |
| 64 |
int endIndex; |
| 65 |
String currOriginId; |
| 66 |
String buf = ""; |
| 67 |
byte[] buffer = new byte[1000]; |
| 68 |
int bytesRead = 0; |
| 69 |
String beginningTag = "<originId>"; |
| 70 |
String endTag = "</originId>"; |
| 71 |
|
| 72 |
String kindTag = "<kind>"; |
| 73 |
String matchKind = "selection"; |
| 74 |
|
| 75 |
// they should all be zip files, ignore anything that's not |
| 76 |
if (currFile.getName().endsWith(".zip")) { |
| 77 |
ZipFile zip = new ZipFile(currFile); |
| 78 |
|
| 79 |
if (zip.entries().hasMoreElements()) { |
| 80 |
ZipEntry entry = zip.entries().nextElement(); |
| 81 |
InputStream stream = zip.getInputStream(entry); |
| 82 |
|
| 83 |
while ((bytesRead = stream.read(buffer)) != -1) { |
| 84 |
buf = buf + new String(buffer, 0, bytesRead); |
| 85 |
|
| 86 |
while ((endIndex = buf.indexOf(endTag)) != -1) { |
| 87 |
index = buf.indexOf(beginningTag); |
| 88 |
index += beginningTag.length(); |
| 89 |
|
| 90 |
int kindIndex = buf.indexOf(kindTag); |
| 91 |
kindIndex += kindTag.length(); |
| 92 |
|
| 93 |
if (buf.substring(kindIndex, kindIndex + matchKind.length()).equals(matchKind)) { |
| 94 |
|
| 95 |
numSelections++; |
| 96 |
totalSelections++; |
| 97 |
|
| 98 |
currOriginId = buf.substring(index, endIndex); |
| 99 |
|
| 100 |
if (!viewToNumberMap.containsKey(currOriginId)) { |
| 101 |
viewToNumberMap.put(currOriginId, 0); |
| 102 |
} |
| 103 |
int numViews = viewToNumberMap.get(currOriginId) + 1; |
| 104 |
viewToNumberMap.put(currOriginId, numViews); |
| 105 |
|
| 106 |
if (!totalNumSelections.containsKey(currOriginId)) { |
| 107 |
totalNumSelections.put(currOriginId, 0); |
| 108 |
} |
| 109 |
int totalNumViews = totalNumSelections.get(currOriginId) + 1; |
| 110 |
totalNumSelections.put(currOriginId, totalNumViews); |
| 111 |
|
| 112 |
} |
| 113 |
|
| 114 |
buf = buf.substring(endIndex + endTag.length(), buf.length()); |
| 115 |
|
| 116 |
} |
| 117 |
|
| 118 |
buffer = new byte[1000]; |
| 119 |
} |
| 120 |
} |
| 121 |
} |
| 122 |
usersNumSelections.put(userID, numSelections); |
| 123 |
|
| 124 |
} |
| 125 |
// print to a file. |
| 126 |
printSummaryToFile(); |
| 127 |
} catch (IOException ioe) { |
| 128 |
logError(ioe.getMessage()); |
| 129 |
} |
| 130 |
|
| 131 |
} |
| 132 |
|
| 133 |
private static void logError(String error) { |
| 134 |
File errorLogFile = new File(LOGGING_DIRECTORY, ERROR_LOGGING_FILE); |
| 135 |
try { |
| 136 |
if (!errorLogFile.exists()) { |
| 137 |
errorLogFile.createNewFile(); |
| 138 |
} |
| 139 |
|
| 140 |
PrintStream errorLogStream = new PrintStream(new FileOutputStream(errorLogFile, true)); |
| 141 |
|
| 142 |
errorLogStream.println(error); |
| 143 |
|
| 144 |
} catch (IOException e) { |
| 145 |
e.printStackTrace(); |
| 146 |
} |
| 147 |
} |
| 148 |
|
| 149 |
/** |
| 150 |
* Assuming the file naming convention of <phase>-<version>-usage-<userID>-<date |
| 151 |
* and time>.zip |
| 152 |
* |
| 153 |
* copied from: org.eclipse.mylar.monitor.usage.core.ReportGenerator author: |
| 154 |
* Mik Kersten |
| 155 |
*/ |
| 156 |
private int getUserId(File source) { |
| 157 |
String userIDText = source.getName(); |
| 158 |
int userId = -1; |
| 159 |
String prefix = "-usage-"; |
| 160 |
|
| 161 |
if (source.getName().indexOf(prefix) >= 0) { |
| 162 |
try { |
| 163 |
userIDText = userIDText.substring(userIDText.indexOf(prefix) + prefix.length(), userIDText.length()); |
| 164 |
userIDText = userIDText.substring(0, userIDText.indexOf("-")); |
| 165 |
userId = Integer.valueOf(userIDText); |
| 166 |
} catch (Throwable t) { |
| 167 |
logError(t.getMessage()); |
| 168 |
} |
| 169 |
} |
| 170 |
|
| 171 |
return userId; |
| 172 |
} |
| 173 |
|
| 174 |
private String formatAsPercentage(float viewUse) { |
| 175 |
String formattedViewUse = ("" + viewUse * 100); |
| 176 |
|
| 177 |
// sometimes the floats are so small that formattedViewUsage ends up |
| 178 |
// being |
| 179 |
// something like 7.68334E-4, which would get formatted to 7.68% without |
| 180 |
// this check |
| 181 |
if (formattedViewUse.contains("E")) { |
| 182 |
return "0.00%"; |
| 183 |
} |
| 184 |
int indexOf2ndDecimal = formattedViewUse.indexOf('.') + 3; |
| 185 |
if (indexOf2ndDecimal <= formattedViewUse.length()) { |
| 186 |
formattedViewUse = formattedViewUse.substring(0, indexOf2ndDecimal); |
| 187 |
} |
| 188 |
return formattedViewUse + "%"; |
| 189 |
} |
| 190 |
|
| 191 |
static public String getSummaryFilePath() { |
| 192 |
File summaryFile = new File(USAGE_DIRECTORY, USAGE_SUMMARY_FILE); |
| 193 |
if (!summaryFile.exists()) { |
| 194 |
try { |
| 195 |
summaryFile.createNewFile(); |
| 196 |
} catch (IOException e) { |
| 197 |
logError(e.getMessage()); |
| 198 |
} |
| 199 |
} |
| 200 |
|
| 201 |
return summaryFile.getAbsolutePath(); |
| 202 |
} |
| 203 |
|
| 204 |
public void printSummaryToFile() { |
| 205 |
|
| 206 |
File summaryFile = new File(USAGE_DIRECTORY, USAGE_SUMMARY_FILE); |
| 207 |
try { |
| 208 |
if (!summaryFile.exists()) { |
| 209 |
summaryFile.createNewFile(); |
| 210 |
} else { |
| 211 |
summaryFile.delete(); |
| 212 |
summaryFile.createNewFile(); |
| 213 |
} |
| 214 |
|
| 215 |
PrintStream summaryLogStream = new PrintStream(new FileOutputStream(summaryFile, true)); |
| 216 |
|
| 217 |
summaryLogStream.println("Total events: " + totalSelections); |
| 218 |
summaryLogStream.println("Number of unique users: " + userToViewMap.entrySet().size()); |
| 219 |
summaryLogStream.println(); |
| 220 |
|
| 221 |
summaryLogStream.println(MAX_NUM_VIEWS_TO_REPORT + " most used views:"); |
| 222 |
|
| 223 |
List<String> viewUsage = new ArrayList<String>(); |
| 224 |
for (String view : totalNumSelections.keySet()) { |
| 225 |
float numSelections = (float) (totalNumSelections.get(view)); |
| 226 |
float viewUse = numSelections / totalSelections; |
| 227 |
String formattedViewUse = formatAsPercentage(viewUse); |
| 228 |
viewUsage.add(formattedViewUse + ": " + view + " (" + totalNumSelections.get(view) + ")"); |
| 229 |
} |
| 230 |
Collections.sort(viewUsage, new PercentUsageComparator()); |
| 231 |
int numViewsToReport = 0; |
| 232 |
for (String viewUsageSummary : viewUsage) { |
| 233 |
if (MAX_NUM_VIEWS_TO_REPORT == -1 || numViewsToReport < MAX_NUM_VIEWS_TO_REPORT) { |
| 234 |
|
| 235 |
summaryLogStream.println(viewUsageSummary); |
| 236 |
numViewsToReport++; |
| 237 |
} |
| 238 |
} |
| 239 |
|
| 240 |
} catch (IOException e) { |
| 241 |
logError(e.getMessage()); |
| 242 |
} |
| 243 |
|
| 244 |
} |
| 245 |
|
| 246 |
public void printSummary(int userId, PrintWriter out) { |
| 247 |
Map<String, Integer> normalViewSelections = userToViewMap.get(userId); |
| 248 |
|
| 249 |
float numSelections = usersNumSelections.get(userId); |
| 250 |
|
| 251 |
List<String> viewUsage = new ArrayList<String>(); |
| 252 |
for (String view : normalViewSelections.keySet()) { |
| 253 |
float viewUse = ((float) (normalViewSelections.get(view))) / numSelections; |
| 254 |
String formattedViewUse = formatAsPercentage(viewUse); |
| 255 |
viewUsage.add(formattedViewUse + ": " + view + " (" + normalViewSelections.get(view) + ")" + "<br>"); |
| 256 |
} |
| 257 |
Collections.sort(viewUsage, new PercentUsageComparator()); |
| 258 |
int numViewsToReport = 0; |
| 259 |
for (String viewUsageSummary : viewUsage) { |
| 260 |
if (MAX_NUM_VIEWS_TO_REPORT == -1 || numViewsToReport < MAX_NUM_VIEWS_TO_REPORT) { |
| 261 |
out.println(viewUsageSummary); |
| 262 |
numViewsToReport++; |
| 263 |
} |
| 264 |
} |
| 265 |
} |
| 266 |
|
| 267 |
public void printReport(PrintWriter out) { |
| 268 |
for (int userId : userToViewMap.keySet()) { |
| 269 |
printSummary(userId, out); |
| 270 |
} |
| 271 |
} |
| 272 |
} |