📄 reportgenerator.java
字号:
/* * ReportGenerator.java * * Version: $Revision: 1.3 $ * * Date: $Date: 2005/04/21 09:01:13 $ * * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts * Institute of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Hewlett-Packard Company nor the name of the * Massachusetts Institute of Technology nor the names of their * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */package org.dspace.app.statistics;import org.dspace.app.statistics.Stat;import org.dspace.app.statistics.ReportTools;import java.sql.SQLException;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Calendar;import java.util.Date;import java.util.GregorianCalendar;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.regex.Matcher;import java.util.regex.Pattern;import java.util.SortedMap;import java.util.StringTokenizer;import java.util.TreeMap;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import org.dspace.content.DCValue;import org.dspace.content.Item;import org.dspace.core.ConfigurationManager;import org.dspace.core.Context;import org.dspace.handle.HandleManager;/** * This class performs the action of coordinating a usage report being * generated using the standard internal aggregation file format as a basis. * All it's configuration information must come from that file. There is the * opportunity for different output format options such as HTML. * * Use the -help flag for more information * * @author Richard Jones */public class ReportGenerator { // set up our class globals ///////////////// // aggregators ///////////////// /** aggregator for all actions performed in the system */ private static Map actionAggregator = new HashMap(); /** aggregator for all searches performed */ private static Map searchAggregator = new HashMap(); /** aggregator for user logins */ private static Map userAggregator = new HashMap(); /** aggregator for item views */ private static Map itemAggregator = new HashMap(); /** aggregator for current archive state statistics */ private static Map archiveStats = new HashMap(); ////////////////// // statistics config data ////////////////// /** bottom limit to output for search word analysis */ private static int searchFloor; /** bottom limit to output for item view analysis */ private static int itemFloor; /** number of items from most popular to be looked up in the database */ private static int itemLookup; /** mode to use for user email display */ private static String userEmail; /** URL of the service being analysed */ private static String url; /** Name of the service being analysed */ private static String name; /** average number of views per item */ private static int avgItemViews; /** name of the server being analysed */ private static String serverName; /** start date of this report */ private static Date startDate = null; /** end date of this report */ private static Date endDate = null; /** the time taken to build the aggregation file from the log */ private static int processTime; /** the number of log lines analysed */ private static int logLines; /** the number of warnings encountered */ private static int warnings; /** the list of results to be displayed in the general summary */ private static List generalSummary = new ArrayList(); ////////////////// // regular expressions ////////////////// /** pattern that matches an unqualified aggregator property */ private static Pattern real = Pattern.compile("^(.+)=(.+)"); ////////////////////////// // Miscellaneous variables ////////////////////////// /** process timing clock */ private static Calendar startTime = null; /** a map from log file action to human readable action */ private static Map actionMap = new HashMap(); ///////////////// // report generator config data //////////////// /** the format of the report to be output */ private static String format = null; /** the input file to build the report from */ private static String input = null; /** the output file to which to write aggregation data */ private static String output = ConfigurationManager.getProperty("dspace.dir") + File.separator + "log" + File.separator + "report"; /** the log file action to human readable action map */ private static String map = ConfigurationManager.getProperty("dspace.dir") + File.separator + "config" + File.separator + "dstat.map"; /** * main method to be run from command line. See usage information for * details as to how to use the command line flags */ public static void main(String [] argv) throws Exception, SQLException { // create context as super user Context context = new Context(); context.setIgnoreAuthorization(true); String myFormat = null; String myInput = null; String myOutput = null; String myMap = null; // read in our command line options for (int i = 0; i < argv.length; i++) { if (argv[i].equals("-format")) { myFormat = argv[i+1].toLowerCase(); } if (argv[i].equals("-in")) { myInput = argv[i+1]; } if (argv[i].equals("-out")) { myOutput = argv[i+1]; } if (argv[i].equals("-map")) { myMap = argv[i+1]; } if (argv[i].equals("-help")) { usage(); System.exit(0); } } processReport(context, myFormat, myInput, myOutput, myMap); } /** * using the pre-configuration information passed here, read in the * aggregation data and output a file containing the report in the * requested format * * @param context the DSpace context in which this action is performed * @param myFormat the desired output format (currently on HTML supported) * @param myInput the aggregation file to be turned into a report * @param myOutput the file into which to write the report */ public static void processReport(Context context, String myFormat, String myInput, String myOutput, String myMap) throws Exception, SQLException { startTime = new GregorianCalendar(); // set the parameters for this analysis setParameters(myFormat, myInput, myOutput, myMap); // pre prepare our standard file readers and buffered readers FileReader fr = null; BufferedReader br = null; // read the input file readInput(input); // load the log file action to human readable action map readMap(map); // create the relevant report type // FIXME: at the moment we only support HTML report generation Report report = null; if (format.equals("html")) { report = new HTMLReport(); } report.setStartDate(startDate); report.setEndDate(endDate); report.setMainTitle(name, serverName); // define our standard variables for re-use // FIXME: we probably don't need these once we've finished re-factoring Iterator keys = null; int i = 0; String explanation = null; int value; // FIXME: All of these sections should probably be buried in their own // custom methods Statistics overview = new Statistics(); overview.setSectionHeader("General Overview"); Iterator summaryEntries = generalSummary.iterator(); while (summaryEntries.hasNext()) { String entry = (String) summaryEntries.next(); if (actionAggregator.containsKey(entry)) { int count = Integer.parseInt((String) actionAggregator.get(entry)); overview.add(new Stat(translate(entry), count)); } } report.addBlock(overview); // prepare the archive statistics package if (archiveStats.size() > 0) { Statistics archiveInfo = prepareStats(archiveStats, true, false); archiveInfo.setSectionHeader("Archive Information"); archiveInfo.setStatName("Content Type"); archiveInfo.setResultName("Number of items"); report.addBlock(archiveInfo); } // process the items in preparation to be displayed. This includes sorting // by view number, building the links, and getting further info where // necessary Statistics viewedItems = new Statistics("Item/Handle", "Number of views", itemFloor); viewedItems.setSectionHeader("Items Viewed"); Stat[] items = new Stat[itemAggregator.size()]; keys = itemAggregator.keySet().iterator(); i = 0; while (keys.hasNext()) { String key = (String) keys.next(); String link = url + "handle/" + key; value = Integer.parseInt((String) itemAggregator.get(key)); items[i] = new Stat(key, value, link); i++; } Arrays.sort(items); String info = null; for (i = 0; i < items.length; i++) { if (i < itemLookup) { info = getItemInfo(context, items[i].getKey()); } // if we get something back from the db then set it as the key, // else just use the link if (info != null) { items[i].setKey(info + " (" + items[i].getKey() + ")"); } else { items[i].setKey(items[i].getReference()); } // reset the info register info = null; } viewedItems.add(items); report.addBlock(viewedItems); // prepare a report of the full action statistics Statistics fullInfo = prepareStats(actionAggregator, true, true); fullInfo.setSectionHeader("All Actions Performed"); fullInfo.setStatName("Action"); fullInfo.setResultName("Number of times"); report.addBlock(fullInfo); // prepare the user login statistics package if (!userEmail.equals("off")) { Statistics userLogins = prepareStats(userAggregator, true, false); userLogins.setSectionHeader("User Logins"); userLogins.setStatName("User"); userLogins.setResultName("Number of logins"); if (userEmail.equals("alias")) { explanation = "(distinct addresses)"; userLogins.setExplanation(explanation); } report.addBlock(userLogins); } // prepare the search word statistics package Statistics searchWords = prepareStats(searchAggregator, true, false); searchWords.setSectionHeader("Words Searched"); searchWords.setStatName("Word"); searchWords.setResultName("Number of searches"); searchWords.setFloor(searchFloor); report.addBlock(searchWords); // FIXME: because this isn't an aggregator it can't be passed to // prepareStats; should we overload this method for use with this kind // of data? // prepare the average item views statistics if (avgItemViews > 0) { Statistics avg = new Statistics(); avg.setSectionHeader("Averaging Information"); Stat[] average = new Stat[1]; average[0] = new Stat("Average views per item", avgItemViews); avg.add(average); report.addBlock(avg); } // prepare the log line level statistics // FIXME: at the moment we only know about warnings, but future versions // should aggregate all log line levels and display here Statistics levels = new Statistics("Level", "Number of lines"); levels.setSectionHeader("Log Level Information"); Stat[] level = new Stat[1]; level[0] = new Stat("Warnings", warnings); levels.add(level); report.addBlock(levels); // get the display processing time information Calendar endTime = new GregorianCalendar(); long timeInMillis = (endTime.getTimeInMillis() - startTime.getTimeInMillis()); int outputProcessTime = (new Long(timeInMillis).intValue() / 1000); // prepare the processing information statistics Statistics process = new Statistics("Operation", ""); process.setSectionHeader("Processing Information"); Stat[] proc = new Stat[3]; proc[0] = new Stat("Log Processing Time", processTime); proc[0].setUnits("seconds");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -