/* * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata * * Portions of this software were developed by the Unidata Program at the * University Corporation for Atmospheric Research. * * Access and use of this software shall impose the following obligations * and understandings on the user. The user is granted the right, without * any fee or cost, to use, copy, modify, alter, enhance and distribute * this software, and any derivative works thereof, and its supporting * documentation for any purpose whatsoever, provided that this entire * notice appears in all copies of the software, derivative works and * supporting documentation. Further, UCAR requests that the user credit * UCAR/Unidata in any publications that result from the use of this * software or in any product that includes this software. The names UCAR * and/or Unidata, however, may not be used in any advertising or publicity * to endorse or promote any products or commercial entity unless specific * written permission is obtained from UCAR/Unidata. The user also * understands that UCAR/Unidata is not obligated to provide the user with * any support, consulting, training or assistance of any kind with regard * to the use, operation and performance of this software nor to provide * the user with any updates, revisions, new versions or "bug fixes." * * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "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 UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. */ package thredds.logs; import java.util.regex.*; import java.util.Date; import java.io.BufferedReader; import java.io.IOException; import java.text.SimpleDateFormat; /** * Read TDS access logs * * @author caron * @since Apr 10, 2008 */ public class AccessLogParser implements LogReader.LogParser { /////////////////////////////////////////////////////// // log reading // sample // 1 2 3 4 5 6 7 8 9 // 128.117.140.75 - - [02/May/2008:00:46:26 -0600] "HEAD /thredds/dodsC/model/NCEP/DGEX/CONUS_12km/DGEX_CONUS_12km_20080501_1800.grib2.dds HTTP/1.1" 200 - "null" "Java/1.6.0_05" 21 // 24.18.236.132 - - [04/Feb/2011:17:49:03 -0700] "GET /thredds/fileServer//nexrad/level3/N0R/YUX/20110205/Level3_YUX_N0R_20110205_0011.nids " 200 10409 "-" "-" 17 // an access log without the extra fields at the end // 1 2 3 4 5 6 5 6 7 8 9 // 127.0.0.1 - - [17/Jun/2015:13:48:32 -0600] "GET /thredds/ HTTP/1.1" 302 - // 30/Sep/2009:23:50:47 -0600 private SimpleDateFormat formatFrom = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss Z"); private static Pattern regPattern = // 1 2 3 4 5 6 7 8 9 5 6 7 8 9 Pattern.compile("^(\\d+\\.\\d+\\.\\d+\\.\\d+) - (.*) \\[(.*)\\] \"(.*)\" (\\d+) ([\\-\\d]+) \"(.*)\" \"(.*)\" (\\d+)"); // pattern without the extra fields at the end 1 2 3 4 5 6 5 6 7 8 9 private static Pattern regPattern2 = Pattern.compile("^(\\d+\\.\\d+\\.\\d+\\.\\d+) - (.*) \\[(.*)\\] \"(.*)\" (\\d+) ([\\-\\d]+)"); public LogReader.Log nextLog(BufferedReader dataIS) throws IOException { String line = dataIS.readLine(); if (line == null) return null; LogReader.Log resultLog = parseLog(line); if (resultLog != null) { return resultLog; } else { // todo: FIX ME...no likey recursy. return nextLog(dataIS); } /* try { //System.out.println("\n"+line); Matcher m = regPattern.matcher(line); if (m.matches()) { LogReader.Log log = new LogReader.Log(); log.ip = m.group(1); log.date = convertDate( m.group(3)); String request = m.group(4); log.returnCode = parse(m.group(5)); log.sizeBytes = parseLong(m.group(6)); log.referrer = m.group(7); log.client = m.group(8); log.msecs = parseLong(m.group(9)); String[] reqss = request.split(" "); if (reqss.length == 3) { log.verb = reqss[0].intern(); log.path = reqss[1]; log.http = reqss[2].intern(); } return log; } } catch (Exception e) { e.printStackTrace(); System.out.println("Cant parse " + line); } return null; */ } LogReader.Log parseLog(String line) throws IOException { try { // the enhanced log Matcher m = regPattern.matcher(line); if (m.matches()) { LogReader.Log log = new LogReader.Log(); log.ip = m.group(1); log.date = convertDate( m.group(3)); String request = m.group(4); log.returnCode = parse(m.group(5)); log.sizeBytes = parseLong(m.group(6)); log.referrer = m.group(7); log.client = m.group(8); log.msecs = parseLong(m.group(9)); String[] reqss = request.split(" "); if (reqss.length == 3) { log.verb = reqss[0].intern(); log.path = reqss[1]; log.http = reqss[2].intern(); } else if (reqss.length == 2) { // no HTTP/1.x log.verb = reqss[0].intern(); log.path = reqss[1]; } return log; } else { // the non-enhanced log m = regPattern2.matcher(line); if (m.matches()) { LogReader.Log log = new LogReader.Log(); log.ip = m.group(1); log.date = convertDate(m.group(3)); String request = m.group(4); log.returnCode = parse(m.group(5)); log.sizeBytes = parseLong(m.group(6)); log.referrer = "-"; log.client = "-"; log.msecs = -1; String[] reqss = request.split(" "); if (reqss.length == 3) { log.verb = reqss[0].intern(); log.path = reqss[1]; log.http = reqss[2].intern(); } else if (reqss.length == 2) { // no HTTP/1.x log.verb = reqss[0].intern(); log.path = reqss[1]; } return log; } } } catch (Exception e) { e.printStackTrace(); System.out.println("Cant parse " + line); } return null; } private long convertDate(String accessDateFormat) { // 30/Sep/2009:23:50:47 -0600 try { Date d = formatFrom.parse(accessDateFormat); return d.getTime(); // formatTo.toDateTimeStringISO(d); } catch (Throwable t) { System.out.printf("Bad date format = %s err = %s%n", accessDateFormat, t.getMessage()); } return -1; } private int parse(String s) { if (s.equals("-")) return 0; return Integer.parseInt(s); } private long parseLong(String s) { if (s.equals("-")) return 0; return Long.parseLong(s); } // try problem logs public static void main(String[] args) throws IOException { AccessLogParser p = new AccessLogParser(); String line = "24.18.236.132 - - [04/Feb/2011:17:49:03 -0700] \"GET /thredds/fileServer//nexrad/level3/N0R/YUX/20110205/Level3_YUX_N0R_20110205_0011.nids \" 200 10409 \"-\" \"-\" 17"; Matcher m = regPattern.matcher(line); System.out.printf("%s %s%n", m.matches(), m); for (int i=0; i<m.groupCount(); i++) { System.out.println(" "+i+ " "+m.group(i)); } LogReader.Log log = p.parseLog(line); System.out.printf("%s%n", log); } }