package dk.thoerup.traininfoservice; 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.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.genericjavautils.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"; 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 accessLogDir = new File("/home/torben/inst/glassfishv3/glassfish/domains/domain1/logs/access/"); File logFiles[] = accessLogDir.listFiles( new FilenameFilter() { @Override public boolean accept(File dir, String name) { //log.info("name:" + name); return name.startsWith("server_access_log"); } }); Arrays.sort(logFiles); if (logFiles == null) { File[] empty = {}; log.info("file array was empty"); return empty; } int from = (count>logFiles.length) ? 0 : logFiles.length - (count); int to = logFiles.length; return Arrays.copyOfRange(logFiles, from, to); } protected PositionContainer getRequestsFromFileWorker(int count) throws IOException{ PositionContainer positions = new PositionContainer(); try { 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 ( !f.exists() ) { continue; } InputStream input = new FileInputStream(f); 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"}; String files[]; 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(current.time).append("\n" ); sb.append( " #").append(color).append("\n" ); sb.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(int count) throws IOException { String kmlData = null; String key; key = "kmldata-" + count; kmlData = cache.get(key); if (kmlData == null) { kmlData = formatXml( getRequestsFromFileWorker(count) ); 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 (p != 0); } int getCount(String param) { if (param == null || param.equals("")) { return 1; } return Integer.parseInt(param); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { int count = getCount( req.getParameter("count") ); if (count > 30) //limit to 30 days count = 30; if (count < 0) //negative count is not allowed count = 0; String kmlData = getRequestsFromFile(count); if ( enabled(req.getParameter("zip")) ) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(baos); zip.putNextEntry( new ZipEntry("trains.kml") ); zip.write( kmlData.getBytes() ); zip.closeEntry(); zip.close(); byte bytes[] = baos.toByteArray(); resp.setContentType(KMZ); resp.setHeader("Content-disposition", "attachment; filename=Traininfo-requestplotter.kmz"); resp.setContentLength( bytes.length ); resp.getOutputStream().write(bytes); } else { resp.setContentType(KML); resp.getWriter().print( kmlData ); } } }