Mercurial > stress-tester
changeset 1152:a248b4a1a32f
HttpTrafficDumperFilter
author | Devel 2 |
---|---|
date | Fri, 12 Jun 2020 13:09:36 +0200 |
parents | 65f4b7539281 |
children | 39588e98056b |
files | stress-tester/src/main/java/com/passus/st/client/http/filter/HttpTrafficDumperFilter.java stress-tester/src/main/java/com/passus/st/utils/CsvHelper.java |
diffstat | 2 files changed, 269 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpTrafficDumperFilter.java Fri Jun 12 13:09:36 2020 +0200 @@ -0,0 +1,221 @@ +package com.passus.st.client.http.filter; + +import com.passus.commons.annotations.Plugin; +import com.passus.config.Configuration; +import com.passus.config.ConfigurationContext; +import com.passus.config.annotations.NodeDefinitionCreate; +import com.passus.config.schema.NodeDefinition; +import com.passus.config.schema.NodeDefinitionCreator; +import com.passus.data.ByteString; +import com.passus.net.http.HttpHeaders; +import com.passus.net.http.HttpRequest; +import com.passus.net.http.HttpResponse; +import com.passus.net.http.HttpStatus; +import com.passus.st.client.FlowContext; +import com.passus.st.emitter.SessionInfo; +import com.passus.st.filter.FlowFilter; +import com.passus.st.plugin.PluginConstants; +import com.passus.st.utils.CsvHelper; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.*; + +import static com.passus.config.schema.ConfigurationSchemaBuilder.mapDef; +import static com.passus.config.schema.ConfigurationSchemaBuilder.tupleDef; +import static com.passus.net.http.HttpUtils.intToVersionString; +import static com.passus.st.client.http.HttpConsts.*; +import static com.passus.st.config.CommonNodeDefs.STRING_DEF; + +@NodeDefinitionCreate(HttpTrafficDumperFilter.HttpSessionCookieFilterNodeDefCreator.class) +@Plugin(name = HttpTrafficDumperFilter.TYPE, category = PluginConstants.CATEGORY_FLOW_FILTER) +public class HttpTrafficDumperFilter extends HttpFilter { + + private static final Logger LOGGER = LogManager.getLogger(HttpTrafficDumperFilter.class); + + public static final String TYPE = "httpTrafficDumper"; + + private String encoding = "UTF-8"; + + private int bufferSize = 16 * 1024; + + private String fileName; + + private File file; + + private Writer writer; + + private final CsvHelper csvHelper = new CsvHelper(); + + @Override + public FlowFilter instanceForWorker(int index) { + return this; + } + + @Override + public void configure(Configuration config, ConfigurationContext context) { + fileName = config.getString("fileName"); + } + + private void writeHeaders() throws IOException { + writeString("clientIp"); + writeString("clientPort"); + writeString("serverIp"); + writeString("serverPort"); + + writeString("reqId"); + writeString("reqMethod"); + writeString("reqVersion"); + writeString("reqUri"); + writeString("reqUserAgent"); + writeString("reqTimeStart"); + writeString("reqTimeEnd"); + writeString("reqHeaderSize"); + writeString("reqContentSize"); + + writeString("respCode"); + writeString("respReason"); + writeString("respContentType"); + writeString("respTimeStart"); + writeString("respTimeEnd"); + writeString("respHeaderSize"); + writeString("respContentSize"); + + writeString("sessionId"); + writeString("username"); + csvHelper.write("loop", writer); + csvHelper.write("\n", writer); + } + + private void createWriter(String name) throws IOException { + file = new File(name); + try { + writer = new OutputStreamWriter(new FileOutputStream(file, true), encoding); + } catch (FileNotFoundException ex) { + String parentPath = file.getParent(); + if (parentPath != null) { + File parentDir = new File(parentPath); + if (!parentDir.exists() && parentDir.mkdirs()) { + writer = new OutputStreamWriter(new FileOutputStream(file, true), encoding); + } else { + throw ex; + } + } else { + throw ex; + } + } + + if (bufferSize > 0) { + writer = new BufferedWriter(writer, bufferSize); + } + + if (file.length() == 0) { + writeHeaders(); + } + } + + private void write(Object value) throws IOException { + csvHelper.write(value, writer); + csvHelper.writeDelimiter(writer); + } + + private void writeString(ByteString value) throws IOException { + csvHelper.writeString(value, writer); + csvHelper.writeDelimiter(writer); + } + + private void writeString(String value) throws IOException { + csvHelper.writeString(value, writer); + csvHelper.writeDelimiter(writer); + } + + private void writeInt(Integer value) throws IOException { + csvHelper.write(value, writer); + csvHelper.writeDelimiter(writer); + } + + @Override + public int filterInbound(HttpRequest req, HttpResponse resp, FlowContext context) { + try { + if (fileName == null) { + return DUNNO; + } + + synchronized (this) { + if (writer == null) { + createWriter(fileName); + } + + SessionInfo sessionInfo = context.sessionInfo(); + writeString(sessionInfo.getSrcIp().toString()); + writeInt(sessionInfo.getSrcPort()); + writeString(sessionInfo.getDstIp().toString()); + writeInt(sessionInfo.getDstPort()); + + writeString(req.getId()); + writeString(req.getMethod().toString()); + writeString(intToVersionString(req.getVersion())); + writeString(req.getUri()); + + HttpHeaders reqHeaders = req.getHeaders(); + writeString(reqHeaders.get(HttpHeaders.USER_AGENT)); + + write(req.getTag(TAG_TIME_START)); + write(req.getTag(TAG_TIME_END)); + + write(req.getTag(TAG_HEADER_SIZE)); + if (req.hasContent()) { + write(req.getContent().available()); + } else { + write(0); + } + + if (resp != null) { + HttpStatus status = resp.getStatus(); + write(status.getCode()); + writeString(status.getReasonPhrase()); + + HttpHeaders respHeaders = resp.getHeaders(); + writeString(respHeaders.get(HttpHeaders.CONTENT_TYPE)); + write(resp.getTag(TAG_TIME_START)); + write(resp.getTag(TAG_TIME_END)); + + write(resp.getTag(TAG_HEADER_SIZE)); + if (resp.hasContent()) { + write(resp.getContent().available()); + } else { + write(0); + } + } else { + writeString(""); + writeString(""); + writeString(""); + writeString(""); + writeString(""); + writeString(""); + writeString(""); + } + + write(req.getTag(TAG_SESSION_ID)); + write(req.getTag(TAG_USERNAME)); + csvHelper.write(context.loop(), writer); + csvHelper.write("\n", writer); + } + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } + + return DUNNO; + } + + public static class HttpSessionCookieFilterNodeDefCreator implements NodeDefinitionCreator { + + @Override + public NodeDefinition create() { + return mapDef( + tupleDef("fileName", STRING_DEF) + ); + } + + } +}
--- a/stress-tester/src/main/java/com/passus/st/utils/CsvHelper.java Fri Jun 12 12:58:12 2020 +0200 +++ b/stress-tester/src/main/java/com/passus/st/utils/CsvHelper.java Fri Jun 12 13:09:36 2020 +0200 @@ -1,6 +1,8 @@ package com.passus.st.utils; +import com.passus.commons.Assert; import com.passus.commons.utils.FormatUtils; +import com.passus.data.ByteString; import java.io.IOException; import java.io.Writer; @@ -10,7 +12,7 @@ public static final char DEFAULT_ESCAPE_CHARACTER = '\\'; - public static final char DEFAULT_DELIMITER = ','; + public static final char DEFAULT_DELIMITER = ';'; public static final char DEFAULT_QUOTE_CHARACTER = '"'; @@ -24,6 +26,8 @@ private final StringBuilder sb = new StringBuilder(); + private String nullValue = ""; + public char getDelimiter() { return delimiter; } @@ -48,6 +52,15 @@ this.escapechar = escapechar; } + public String getNullValue() { + return nullValue; + } + + public void setNullValue(String nullValue) { + Assert.notNull(nullValue, "nullValue"); + this.nullValue = nullValue; + } + private boolean containsSpecialCharacter(String line) { return line.indexOf(quotechar) != -1 || line.indexOf(escapechar) != -1 || line.indexOf(delimiter) != -1; } @@ -57,6 +70,11 @@ return this; } + public CsvHelper appendNull(StringBuilder out) { + out.append(nullValue); + return this; + } + private void escapeChars(String value, StringBuilder out) { for (int j = 0; j < value.length(); j++) { char ch = value.charAt(j); @@ -68,6 +86,16 @@ } } + public CsvHelper appendString(ByteString value, StringBuilder out) { + if (value == null) { + appendNull(out); + } else { + appendString(value.toString(), out); + } + + return this; + } + public CsvHelper appendString(String value, StringBuilder out) { if (containsSpecialCharacter(value)) { sb.setLength(0); @@ -97,7 +125,25 @@ return this; } - private int writeString(String value, Writer writer) throws IOException { + public int writeDelimiter(Writer writer) throws IOException { + writer.write(delimiter); + return 1; + } + + public int writeNull(Writer writer) throws IOException { + writer.write(nullValue); + return 1; + } + + public int writeString(ByteString value, Writer writer) throws IOException { + if (value == null) { + return writeNull(writer); + } + + return writeString(value.toString(), writer); + } + + public int writeString(String value, Writer writer) throws IOException { if (containsSpecialCharacter(value)) { int written = 0; sb.setLength(0);