⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclogparser.java

📁 测试工具
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

package org.apache.jmeter.protocol.http.util.accesslog;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.StringTokenizer;
import java.util.Vector;

import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;

// For JUnit tests, @see TestTCLogParser

/**
 * Description:<br>
 * <br>
 * Currently the parser only handles GET/POST requests. It's easy enough to add
 * support for other request methods by changing checkMethod. The is a complete
 * rewrite of a tool I wrote for myself earlier. The older algorithm was basic
 * and did not provide the same level of flexibility I want, so I wrote a new
 * one using a totally new algorithm. This implementation reads one line at a
 * time using BufferedReader. When it gets to the end of the file and the
 * sampler needs to get more requests, the parser will re-initialize the
 * BufferedReader. The implementation uses StringTokenizer to create tokens.
 * <p>
 * The parse algorithm is the following:
 * <p>
 * <ol>
 * <li> cleans the entry by looking for backslash "\"
 * <li> looks to see if GET or POST is in the line
 * <li> tokenizes using quotes "
 * <li> finds the token with the request method
 * <li> gets the string of the token and tokenizes it using space
 * <li> finds the first token beginning with slash character
 * <li> tokenizes the string using question mark "?"
 * <li> get the path from the first token
 * <li> returns the second token and checks it for parameters
 * <li> tokenizes the string using ampersand "&"
 * <li> parses each token to name/value pairs
 * </ol>
 * <p>
 * Extending this class is fairly simple. Most access logs use the same format
 * starting from the request method. Therefore, changing the implementation of
 * cleanURL(string) method should be sufficient to support new log formats.
 * Tomcat uses common log format, so any webserver that uses the format should
 * work with this parser. Servers that are known to use non standard formats are
 * IIS and Netscape.
 * <p>
 * 
 */

public class TCLogParser implements LogParser {
	static Logger log = LoggingManager.getLoggerForClass();

	public static final String GET = "GET";

	public static final String POST = "POST";

	/** protected members * */
	protected String RMETHOD = null;

	/**
	 * The path to the access log file
	 */
	protected String URL_PATH = null;

	protected boolean useFILE = true;

	protected File SOURCE = null;

	protected String FILENAME = null;

	protected BufferedReader READER = null;

	/**
	 * Handles to supporting classes
	 */
	protected Filter FILTER = null;

    /**
     * by default, we probably should decode the parameter values
     */
    protected boolean decode = true;
    
	// TODO downcase UPPER case non-final variables

	/**
	 * 
	 */
	public TCLogParser() {
		super();
	}

	/**
	 * @param source
	 */
	public TCLogParser(String source) {
		setSourceFile(source);
	}

    /**
     * by default decode is set to true. if the parameters shouldn't be
     * decoded, call the method with false
     * @param decodeparams
     */
    public void setDecodeParameterValues(boolean decodeparams) {
        this.decode = decodeparams;
    }
    
    /**
     * decode the parameter values is to true by default
     * @return  if paramter values should be decoded
     */
    public boolean decodeParameterValue() {
        return this.decode;
    }
    
	/**
	 * Calls this method to set whether or not to use the path in the log. We
	 * may want to provide the ability to filter the log file later on. By
	 * default, the parser uses the file in the log.
	 * 
	 * @param file
	 */
	public void setUseParsedFile(boolean file) {
		this.useFILE = file;
	}

	/**
	 * Use the filter to include/exclude files in the access logs. This is
	 * provided as a convienance and reduce the need to spend hours cleaning up
	 * log files.
	 * 
	 * @param filter
	 */
	public void setFilter(Filter filter) {
		FILTER = filter;
	}

	/**
	 * Sets the source file.
	 * 
	 * @param source
	 */
	public void setSourceFile(String source) {
		this.FILENAME = source;
	}

	/**
	 * Creates a new File object.
	 * 
	 * @param filename
	 */
	public File openFile(String filename) {
		return new File(filename);
	}

	/**
	 * parse the entire file.
	 * 
	 * @return boolean success/failure
	 */
	public int parse(TestElement el, int parseCount) {
		if (this.SOURCE == null) {
			this.SOURCE = this.openFile(this.FILENAME);
		}
		try {
			if (this.READER == null) {
				this.READER = new BufferedReader(new FileReader(this.SOURCE));
			}
			return parse(this.READER, el, parseCount);
		} catch (Exception exception) {
			log.error("Problem creating samples", exception);
		}
		return -1;// indicate that an error occured
	}

	/**
	 * parse a set number of lines from the access log. Keep in mind the number
	 * of lines parsed will depend the filter and number of lines in the log.
	 * The method returns the actual lines parsed.
	 * 
	 * @param count
	 * @return lines parsed
	 */
	public int parseAndConfigure(int count, TestElement el) {
		return this.parse(el, count);
	}

	/**
	 * The method is responsible for reading each line, and breaking out of the
	 * while loop if a set number of lines is given.
	 * 
	 * @param breader
	 */
	protected int parse(BufferedReader breader, TestElement el, int parseCount) {
		int actualCount = 0;
		String line = null;
		try {
			// read one line at a time using
			// BufferedReader
			line = breader.readLine();
			while (line != null) {
				if (line.length() > 0) {
					actualCount += this.parseLine(line, el);
				}
				// we check the count to see if we have exceeded
				// the number of lines to parse. There's no way
				// to know where to stop in the file. Therefore
				// we use break to escape the while loop when
				// we've reached the count.
				if (parseCount != -1 && actualCount >= parseCount) {
					break;
				}
				line = breader.readLine();
			}
			if (line == null) {
				breader.close();
				breader = null;
				this.READER = null;
				// this.READER = new BufferedReader(new
				// FileReader(this.SOURCE));
				// parse(this.READER,el);
			}
		} catch (IOException ioe) {
			log.error("Error reading log file", ioe);
		}
		return actualCount;
	}

	/**
	 * parseLine calls the other parse methods to parse the given text.
	 * 
	 * @param line
	 */
	protected int parseLine(String line, TestElement el) {
		int count = 0;
		// we clean the line to get
		// rid of extra stuff
		String cleanedLine = this.cleanURL(line);
		log.debug("parsing line: " + line);
		// now we set request method
		el.setProperty(HTTPSamplerBase.METHOD, RMETHOD);
		if (FILTER != null) {
			log.debug("filter is not null");
			if (!FILTER.isFiltered(line,el)) {
				log.debug("line was not filtered");
				// increment the current count
				count++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -