--- android/TrainInfoService/src/dk/thoerup/traininfoservice/RequestPlotter.java 2010/06/07 08:37:29 798 +++ android/TrainInfoService/src/dk/thoerup/traininfoservice/RequestPlotter.java 2011/04/19 16:19:45 1310 @@ -2,103 +2,406 @@ import java.io.BufferedReader; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileInputStream; +import java.io.FilenameFilter; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.zip.GZIPInputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import dk.thoerup.traininfoservice.banedk.TimeoutMap; + +@WebServlet(urlPatterns={"/RequestPlotter"}) public class RequestPlotter extends HttpServlet { private static final long serialVersionUID = 1L; - + static final Logger log = Logger.getLogger(RequestPlotter.class.getName()); - + static final String KML = "application/vnd.google-earth.kml"; static final String KMZ = "application/vnd.google-earth.kmz"; - protected String getKml() { - StringBuilder sb = new StringBuilder(); + Map cache = new TimeoutMap(30*60*1000); + + class RequestPosition { + public String ip; + public Date time; + public String lat; + public String lng; + } + + class PositionContainer { + List blue = new ArrayList(); + List green = new ArrayList(); + List yellow = new ArrayList(); + List red = new ArrayList(); + } + + + boolean isGz(String fileStr) { + return fileStr.substring(fileStr.length() - 3).equals(".gz"); + } + + protected File[] getFiles(int count) { + File accessLogDir = new File("/home/app/domain1/logs/access/"); + + File logFiles[] = accessLogDir.listFiles( new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.startsWith("server_access_log"); + } + }); + + if (logFiles == null) { + File[] empty = {}; + return empty; + } + + int from = logFiles.length - count; + int to = logFiles.length-1; + + return Arrays.copyOfRange(logFiles, from, to); + } + + protected PositionContainer getRequestsFromFileWorker(boolean multiple) throws IOException{ + PositionContainer positions = new PositionContainer(); + try { - FileInputStream fis = new FileInputStream("/var/log/apache2/app_access.log"); - BufferedReader in = new BufferedReader( new InputStreamReader(fis) ); - - sb.append( "\n" ); - sb.append( "\n" ); - sb.append( "\n" ); + int count; - String line; - while ( (line=in.readLine()) != null) { - if (line.indexOf("LocateStation") == -1 ){ - continue; - } + if (multiple == false) { + count = 1; + } else { + count = 4; + } + + File files[] = getFiles(count); + + SimpleDateFormat df = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss"); + + Date now = new Date(); + for (File f : files ) { + log.info("Parsing file: " + f.getName() ); - if (line.indexOf("latitude") == -1 ) { + if ( !f.exists() ) { continue; } - String toks[] = line.split(" "); - String ip = toks[0]; - String time = toks[3].replace("[", ""); - String argpart = toks[6].split("\\?")[1]; - - String args[] = argpart.split("&"); - - String lat = args[0].split("=")[1]; - String lng = args[1].split("=")[1]; + InputStream input = new FileInputStream(f); + - sb.append( " \n" ); - sb.append( " IP=" + ip + " Time=" + time + "\n" ); - sb.append( " " + lng + "," + lat + ",0\n" ); - sb.append( " \n" ); + BufferedReader in = new BufferedReader( new InputStreamReader(input) ); + + + String line; + while ( (line=in.readLine()) != null) { + if (line.indexOf("LocateStation") == -1 ){ + continue; + } + + if (line.indexOf("latitude=") == -1 ) { + continue; + } + + if (line.indexOf("longitude=") == -1) { + continue; + } + + RequestPosition pos = new RequestPosition(); + + String toks[] = line.split(" "); + pos.ip = toks[0].replaceAll("\"", ""); + + pos.time = df.parse( toks[2].replace("\"", "") ); + + String argpart = toks[5].split("\\?")[1]; + + String args[] = argpart.split("&"); + + pos.lat = args[0].split("=")[1]; + pos.lng = args[1].split("=")[1]; + + + long timediff = now.getTime() - pos.time.getTime(); + if ( timediff < (3*60*60*1000) ) { + positions.red.add(pos); //RED + } else if ( timediff < (24*60*60*1000)) { + positions.yellow.add(pos); //YELLOW + } else if ( timediff < (7*24*60*60*1000)) { + positions.green.add(pos); //GREEN + } else { + positions.blue.add(pos); //BLUE + } + + } + in.close(); + input.close(); } + } catch (ParseException pe) { + log.log(Level.SEVERE, "parseException", pe); + throw new IOException(pe); + } catch (IOException e) { + log.log(Level.SEVERE, "getKml()", e); + throw e; + } + + return positions; + } + + + /* old apache code + protected PositionContainer getRequestsFromFileWorker(boolean multiple) throws IOException{ + PositionContainer positions = new PositionContainer(); + + try { + String files_single[] = {"/var/log/apache2/app_access.log"}; + String files_multi[] = {"/var/log/apache2/app_access.log.3.gz", "/var/log/apache2/app_access.log.2.gz", "/var/log/apache2/app_access.log.1", "/var/log/apache2/app_access.log"}; - sb.append( "\n" ); - sb.append( "\n" ); + String files[]; - } catch (Exception e) { - sb.append(""); + if (multiple == false) { + files = files_single; + } else { + files = files_multi; + } + + SimpleDateFormat df = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss"); + + Date now = new Date(); + for (String fileStr : files ) { + File f = new File(fileStr); + if ( !f.exists() ) { + continue; + } + + FileInputStream fis = new FileInputStream(fileStr); + + InputStream input; + if ( isGz(fileStr)) { + input = new GZIPInputStream(fis); + } else { + input = fis; + } + + BufferedReader in = new BufferedReader( new InputStreamReader(input) ); + + + String line; + while ( (line=in.readLine()) != null) { + if (line.indexOf("LocateStation") == -1 ){ + continue; + } + + if (line.indexOf("latitude=") == -1 ) { + continue; + } + + if (line.indexOf("longitude=") == -1) { + continue; + } + + RequestPosition pos = new RequestPosition(); + + String toks[] = line.split(" "); + pos.ip = toks[0]; + + pos.time = df.parse( toks[3].replace("[", "") ); + + String argpart = toks[6].split("\\?")[1]; + + String args[] = argpart.split("&"); + + pos.lat = args[0].split("=")[1]; + pos.lng = args[1].split("=")[1]; + + + long timediff = now.getTime() - pos.time.getTime(); + if ( timediff < (3*60*60*1000) ) { + positions.red.add(pos); //RED + } else if ( timediff < (24*60*60*1000)) { + positions.yellow.add(pos); //YELLOW + } else if ( timediff < (7*24*60*60*1000)) { + positions.green.add(pos); //GREEN + } else { + positions.blue.add(pos); //BLUE + } + + } + in.close(); + input.close(); + fis.close(); + } + } catch (ParseException pe) { + log.log(Level.SEVERE, "parseException", pe); + throw new IOException(pe); + } catch (IOException e) { log.log(Level.SEVERE, "getKml()", e); + throw e; + } + + return positions; + }*/ + + protected void formatPositions(StringBuilder sb, String color, List list) { + sb.append( "\n"); + sb.append( " " ).append(color).append("\n"); + sb.append( " 0\n" ); + + int count=0; + for(RequestPosition current : list) { + String id = color + count++; + sb.append( " \n" ); + sb.append( " #").append(color).append("\n" ); + sb.append( " Time=").append(current.time).append("]]>\n" ); + sb.append( " ").append(current.lng).append(",").append(current.lat).append(",0\n" ); + sb.append( " \n" ); + } + + sb.append("\n"); + } + + protected String formatXml(PositionContainer positions) { + StringBuilder sb = new StringBuilder(1024*1024); + + sb.append( "\n" ); + sb.append( "\n" ); + sb.append( "\n" ); + sb.append( " \n"); + sb.append( " Yellow:").append(positions.yellow.size()).append(" (within 24 hours)
\n"); + sb.append( " Green:").append(positions.green.size()).append(" (within one week)
\n"); + sb.append( " Blue:").append(positions.blue.size()).append(" (older)
\n"); + sb.append( " ]]>
"); + + + sb.append( " \n"); + + sb.append( " \n" ); + + sb.append( " \n\n" ); + + sb.append( " \n\n" ); +/* + String overlay = + " " + + " Absolute Positioning: Top left" + + " Absolute Positioning: Top left" + + " 1" + + " " + + " http://code.google.com/apis/kml/documentation/top_left.jpg" + + " " + + " " + + " " + + " " + + " " + + " " ; + + sb.append(overlay); + */ + + + formatPositions(sb, "blue", positions.blue); + formatPositions(sb, "green", positions.green); + formatPositions(sb, "yellow", positions.yellow); + formatPositions(sb, "red", positions.red); + + + sb.append( "
\n" ); + sb.append( "
\n" ); + + return sb.toString(); + } + + protected String getRequestsFromFile(boolean multiple) throws IOException { + String kmlData = null; + String key; + + if (multiple == false) { + key = "kmldata"; + } else { + key = "kmldata-multi"; } + + kmlData = cache.get(key); + + if (kmlData == null) { + kmlData = formatXml( getRequestsFromFileWorker(multiple) ); + cache.put(key, kmlData); + kmlData += ""; + } else { + kmlData += ""; + } + + return kmlData; + } + + boolean enabled(String param) { + if (param == null || param.equals("")) { + return false; + } + + int p = 0; + try { + p = Integer.parseInt(param); + } catch (Exception e) {} - return sb.toString(); + return (p != 0); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - String data = getKml(); - if (req.getParameter("zip") != null) { - + boolean multiple = enabled( req.getParameter("multi") ); + + String kmlData = getRequestsFromFile(multiple); + + if ( enabled(req.getParameter("zip")) ) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); - + ZipOutputStream zip = new ZipOutputStream(baos); zip.putNextEntry( new ZipEntry("trains.kml") ); - zip.write( data.getBytes() ); + zip.write( kmlData.getBytes() ); zip.closeEntry(); zip.close(); - + byte bytes[] = baos.toByteArray(); - + resp.setContentType(KMZ); resp.setContentLength( bytes.length ); resp.getOutputStream().write(bytes); - + } else { resp.setContentType(KML); - resp.getWriter().print( getKml() ); + resp.getWriter().print( kmlData ); } } - - - }