Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * RHQ Management Platform
   * Copyright (C) 2005-2008 Red Hat, Inc.
   * All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation version 2 of the License.
   *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 package org.rhq.plugins.iis;
 
 import java.io.File;
 import java.util.Date;
 import java.util.Map;
 
 
 
 public class IISResponseTimeDelegate {
 
     // date time c-ip cs-method cs-uri-stem sc-status time-taken
     private enum LogFormatToken {
         DATE("date"), //
         TIME("time"), //
         C_IP("c-ip"), //
         CS_URI_STEM("cs-uri-stem"), //
         SC_STATUS("sc-status"), //
         TIME_TAKEN("time-taken");
 
         private String tokenLiteral;
 
         private LogFormatToken(String tokenLiteral) {
             this. = tokenLiteral;
         }
 
         public static LogFormatToken getViaTokenLiteral(String literal) {
             for (LogFormatToken logToken : values()) {
                 // case-sensitive comparison
                 if (logToken.tokenLiteral.equals(literal)) {
                     return logToken;
                 }
             }
             return null// this is OK, user can be using extra tokens
         }
 
         public static String getRequiredTokenString() {
             StringBuilder builder = new StringBuilder();
             for (LogFormatToken nextToken : values()) {
                 if (builder.length() > 0) {
                     builder.append(", ");
                 }
                 builder.append("'").append(nextToken.tokenLiteral).append("'");
             }
             return builder.toString();
         }
 
     }
 
     private File logDirectory;
     private File previousFile;
     private long previousOffset;
     private ResponseTimeLogParser logParser;
     private boolean isAbsoluteTime;
 
     private Log log = LogFactory.getLog(IISResponseTimeDelegate.class);
 
     private class IISResponseTimeLogFileFilter implements FileFilter {
         public boolean accept(File f) {
             String fileName = f.getName().toLowerCase();
             return fileName.startsWith("ex") && fileName.endsWith(".log");
         }
     }
 
    public IISResponseTimeDelegate(String logDirectoryString logFormat,
        ResponseTimeConfiguration responseTimeConfiguration/*, boolean isAbsoluteTime*/) {
        if (logDirectory == null) {
            throw new IllegalArgumentException("logDirectory can not be null");
        }
        this. = new File(logDirectory);
        // IIS always logs in UTC, even if the "Use local time for file naming and rollover" option is selected
        this. = true;
        this. = responseTimeConfiguration;
         = new HashMap<LogFormatTokenInteger>();
        String[] logFormatTokens = logFormat.split(" ");
        EnumSet<LogFormatTokenfoundTokens = EnumSet.noneOf(LogFormatToken.class);
        for (int i = 0; i < logFormatTokens.lengthi++) {
            String nextLiteral = logFormatTokens[i];
            LogFormatToken nextToken = LogFormatToken.getViaTokenLiteral(nextLiteral);
            if (nextToken != null) {
                if (foundTokens.contains(nextToken)) {
                    // weird, but I suppose it's possible possible
                    .warn("Token '" + nextLiteral + "' was specified more than once");
                } else {
                    .debug("Required token found '" + nextLiteral + "' at position " + i);
                    foundTokens.add(nextToken);
                    .put(nextTokeni);
                }
            } else {
                .debug("Extra token found '" + nextLiteral + "' at position " + i);
            }
        }
        if (!foundTokens.containsAll(EnumSet.allOf(LogFormatToken.class))) {
            .error("Log format '" + logFormat + "' needs to include: " + LogFormatToken.getRequiredTokenString());
        }
    }
    public void parseLogs(CallTimeData data) {
        File lastAccessedFile = getLastAccessedFile();
        if (lastAccessedFile == null) {
            // no files have been written to the logDirectory yet
            .debug("No log files exist yet");
            return;
        }
        .debug("Last accessed file = " + lastAccessedFile);
        if ( == null) {
            // first time we found a file in the logDirectory
            .debug("This is the first time we found a log file");
             = lastAccessedFile;
             = .length();
             = new IISResponseTimeLogParser();
        } else {
            // logs have been rotated
            if (!.equals(lastAccessedFile)) {
                .debug("Log files have been rotated");
                // so reset the offset to the beginnnig of the file
                 = .length();
                 = new IISResponseTimeLogParser();
            }
        }
        if ( == null) {
            .error("Unexpected error, logParser was null");
            return;
        }
        try {
            .parseLog(data);
        } catch (IOException ioe) {
            .error("Error parsing log data: " + ioe.getMessage(), ioe);
        }
    }
    private File getLastAccessedFile() {
        File[] logs = this..listFiles(new IISResponseTimeLogFileFilter());
        File lastModifiedFile = null;
        long lastModifiedTime = 0;
        for (File log : logs) {
            if (log.lastModified() > lastModifiedTime) {
                lastModifiedFile = log;
                lastModifiedTime = log.lastModified();
            }
        }
        return lastModifiedFile;
    }
    private class IISResponseTimeLogParser extends ResponseTimeLogParser {
        private DateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        public IISResponseTimeLogParser(File logFile) {
            super(logFile);
        }
        public synchronized void parseLog(CallTimeData callTimeDatathrows IOException {
            .info("Parsing response-time log file " + this. + "...");
            BufferedReader in;
            long newOffset = 0;
            try {
                in = new BufferedReader(new FileReader(this.));
                // record the length now, incase there are more log lines written while
                // we are parsing the ones in the file since the last time we checked it
                newOffset = this..length();
            } catch (FileNotFoundException e) {
                .info("Response-time log file '" + this. + "' does not exist.");
                return;
            }
            .info("Filesize " + newOffset);
            .info("Skipping " + );
            in.skip(IISResponseTimeDelegate.this.);
            IISResponseTimeDelegate.this. = newOffset;
            String currentLine;
            while ((currentLine = in.readLine()) != null) {
                LogEntry logEntry;
                .info("Parsing line: " + currentLine);
                try {
                    logEntry = parseLine(currentLine);
                } catch (Exception e) {
                    .info("Problem parsing line [" + currentLine + "] - cause: " + e);
                    continue;
                }
                String url = logEntry.getUrl();
                // The URL should always begin with a slash. If it doesn't, log an error and skip the entry,
                // so we don't end up with bogus data in the DB.
                if (url.charAt(0) != '/') {
                    String truncatedUrl = url.substring(0, Math.min(url.length(), 120));
                    if (url.length() > 120) {
                        truncatedUrl += "...";
                    }
                    .info("URL ('" + truncatedUrl
                        + "') parsed from response-time log file does not begin with '/'. " + "Line being parsed is ["
                        + currentLine + "].");
                    continue;
                }
                if (isExcluded(url)) {
                    .info("URL was excluded");
                    continue;
                }
                // Only collect stats for successful (2xx or 3xx) requests...
                if ((logEntry.getStatusCode() != null)
                    && ((logEntry.getStatusCode() < 200) || (logEntry.getStatusCode() >= 400))) {
                    .info("Status code was invalid: " + logEntry.getStatusCode());
                    continue;
                }
                String transformedUrl = applyTransforms(url);
                .info("Original URL: " + url);
                .info("Transformed: " + transformedUrl);
                try {
                    callTimeData.addCallData(transformedUrlnew Date(logEntry.getStartTime()), logEntry.getDuration());
                } catch (IllegalArgumentException iae) {
                    // if any issue with the data, log them and continue processing the rest of the report
                    .error(iae);
                }
            }
            .info("Results...");
            for (Map.Entry<StringCallTimeDataValuecallTime : callTimeData.getValues().entrySet()) {
                String url = callTime.getKey();
                CallTimeDataValue value = callTime.getValue();
                .info("Calltime URL: " + url);
                .info("Calltime Data: " + value);
            }
            in.close();
        }
        // E.g. format
        // 2008-04-18 19:56:18 127.0.0.1 GET /favicon.ico 404 0
        protected LogEntry parseLine(String linethrows Exception {
            LogEntry logEntry;
            try {
                String[] logEntryTokens = line.split(" ");
                String date = logEntryTokens[.get(.)];
                String time = logEntryTokens[.get(.)];
                String ipAddress = logEntryTokens[.get(.)];
                String url = logEntryTokens[.get(.)];
                int httpStatus = Integer.parseInt(logEntryTokens[.get(.)]);
                long duration = Long.parseLong(logEntryTokens[.get(.)]);
                long startTime = .parse(date.trim() + " " + time.trim()).getTime();
                if () {
                    /* if we determine that IIS is recording log files in UTC, we need to 
                     * translate values into agent-local times; get the local start time by 
                     * adding the DST-based local offset from the UTC parsed time
                     */
                    int tzOffset = TimeZone.getDefault().getOffset(startTime);
                    startTime += tzOffset;
                }
                logEntry = new LogEntry(urlstartTimedurationhttpStatusipAddress);
            } catch (RuntimeException e) {
                //default fields: time c-ip cs-method cs-uri-stem sc-status (also need 'date' and 'time-taken')
                throw new Exception("Failed to parse response time log file line [" + line + "]. "
                    + "Expected field format is 'date time c-ip cs-method cs-uri-stem sc-status'"e);
            }
            return logEntry;
        }
    }
New to GrepCode? Check out our FAQ X