Mercurial > stress-tester
changeset 1233:3cbe1f2437b0
Http2Metric
author | Devel 2 |
---|---|
date | Mon, 29 Jun 2020 11:25:32 +0200 |
parents | 0ca4d4cc31ef |
children | e0985c791eae |
files | stress-tester/src/main/java/com/passus/st/client/http/Http2FlowHandler.java stress-tester/src/main/java/com/passus/st/client/http/Http2FlowHandlerDataDecoder.java stress-tester/src/main/java/com/passus/st/client/http/Http2FlowHandlerDataEncoder.java stress-tester/src/main/java/com/passus/st/client/http/Http2Metric.java stress-tester/src/main/java/com/passus/st/client/http/HttpMetric.java |
diffstat | 5 files changed, 117 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/stress-tester/src/main/java/com/passus/st/client/http/Http2FlowHandler.java Mon Jun 29 10:53:53 2020 +0200 +++ b/stress-tester/src/main/java/com/passus/st/client/http/Http2FlowHandler.java Mon Jun 29 11:25:32 2020 +0200 @@ -1,8 +1,9 @@ package com.passus.st.client.http; +import com.passus.commons.Assert; import com.passus.commons.time.TimeAware; import com.passus.commons.time.TimeGenerator; -import com.passus.net.http2.Http2Utils; +import com.passus.net.http.HttpRequest; import com.passus.st.client.FlowContext; import com.passus.st.client.FlowHandler; import com.passus.st.client.FlowHandlerDataDecoder; @@ -10,33 +11,41 @@ import com.passus.st.metric.MetricsContainer; import static com.passus.st.Protocols.HTTP2; -import static com.passus.st.client.FlowUtils.queueFirstRequestSessionPayload; -import static com.passus.st.client.SessionPayloadEvent.FLAG_RAW; +import static com.passus.st.client.http.HttpConsts.TAG_TIME_END; +import static com.passus.st.client.http.HttpConsts.TAG_TIME_START; public class Http2FlowHandler implements FlowHandler, TimeAware { + HttpMetric metric; + boolean collectMetrics = false; + HttpScopes scopes; + private final Http2FlowContext context; private final Http2FlowHandlerDataDecoder decoder; private final Http2FlowHandlerDataEncoder encoder; + TimeGenerator timeGenerator = TimeGenerator.getDefaultGenerator(); + public Http2FlowHandler() { context = new Http2FlowContext(); - decoder = new Http2FlowHandlerDataDecoder(context); - encoder = new Http2FlowHandlerDataEncoder(context); + decoder = new Http2FlowHandlerDataDecoder(this, context); + encoder = new Http2FlowHandlerDataEncoder(this, context); + scopes = new HttpScopes(); } @Override public TimeGenerator getTimeGenerator() { - return null; + return timeGenerator; } @Override public void setTimeGenerator(TimeGenerator generator) { - + Assert.notNull(timeGenerator, "timeGenerator"); + this.timeGenerator = generator; } @Override @@ -62,21 +71,44 @@ @Override public void setCollectMetrics(boolean collectMetrics) { this.collectMetrics = collectMetrics; + if (collectMetrics) { + metric = new Http2Metric(); + synchronized (metric) { + metric.activate(); + } + } else if (metric != null) { + synchronized (metric) { + metric.deactivate(); + } + metric = null; + } } @Override public void writeMetrics(MetricsContainer container) { - + if (collectMetrics) { + synchronized (metric) { + container.update(metric); + metric.reset(); + } + } } @Override public void init(FlowContext flowContext) { - + flowContext.setParam(HttpFlowConst.PARAM_HTTP_CONTEXT, new HttpFlowContext(flowContext, scopes)); } @Override - public void onConnected(FlowContext flowContext) { + public void onDataWriteStart(FlowContext flowContext) { + long now = timeGenerator.currentTimeMillis(); + ((HttpRequest) flowContext.sentEvent().getRequest()).setTag(TAG_TIME_START, now); + } + @Override + public void onDataWriteEnd(FlowContext flowContext) { + long now = timeGenerator.currentTimeMillis(); + ((HttpRequest) (flowContext.sentEvent().getRequest())).setTag(TAG_TIME_END, now); }
--- a/stress-tester/src/main/java/com/passus/st/client/http/Http2FlowHandlerDataDecoder.java Mon Jun 29 10:53:53 2020 +0200 +++ b/stress-tester/src/main/java/com/passus/st/client/http/Http2FlowHandlerDataDecoder.java Mon Jun 29 11:25:32 2020 +0200 @@ -4,6 +4,7 @@ import com.passus.net.FixedSizeLengthPduX; import com.passus.net.FixedSizeLengthPduXHandler; import com.passus.net.http.HttpHeadersImpl; +import com.passus.net.http.HttpRequest; import com.passus.net.http.HttpResponse; import com.passus.net.http.HttpStatus; import com.passus.net.http2.*; @@ -19,11 +20,14 @@ import static com.passus.data.DataDecoder.STATE_DATA_NEEDED; import static com.passus.data.DataDecoder.STATE_FINISHED; import static com.passus.net.http2.Http2Utils.*; +import static com.passus.st.client.http.HttpConsts.*; public class Http2FlowHandlerDataDecoder implements FlowHandlerDataDecoder<HttpResponse> { private final Logger LOGGER = LogManager.getLogger(Http2FlowHandlerDataDecoder.class); + private final Http2FlowHandler handler; + private final Http2FrameDecoder decoder = new Http2FrameDecoder(); private HttpResponse resp; @@ -36,11 +40,13 @@ private final FixedSizeLengthPduX pdu; - private List<Http2Frame> streamFrames; + private final PduHandler pduHandler; - public Http2FlowHandlerDataDecoder(Http2FlowContext context) { + public Http2FlowHandlerDataDecoder(Http2FlowHandler handler, Http2FlowContext context) { + this.handler = handler; this.context = context; - pdu = new FixedSizeLengthPduX(new PduHandler(), 3, 6); + pduHandler = new PduHandler(); + pdu = new FixedSizeLengthPduX(pduHandler, 3, 6); } @Override @@ -58,6 +64,7 @@ state = STATE_DATA_NEEDED; error = null; pdu.clear(); + pduHandler.clear(); resp = null; } @@ -68,12 +75,32 @@ @Override public int decode(ByteBuff buffer, FlowContext flowContext) { + pduHandler.flowContext = flowContext; pdu.handle(buffer.buffer(), buffer.startIndex(), buffer.length()); return buffer.length(); } private class PduHandler implements FixedSizeLengthPduXHandler { + FlowContext flowContext; + + private int headerSize; + + private int contentSize; + + private HttpRequest lastRequest(FlowContext flowContext) { + if (flowContext.sentEvent() != null) { + return (HttpRequest) flowContext.sentEvent().getRequest(); + } + + return null; + } + + private void clear() { + headerSize = 0; + contentSize = 0; + } + @Override public void decodeBlockLength(byte[] data, int offset, MutableInt value) { value.setValue(DataUtils.getInt3(data, offset)); @@ -158,7 +185,6 @@ if ((frame.getFlags() & FLAG_END_STREAM) == FLAG_END_STREAM) { context.streams.remove(streamId); resp = assemble(stream.frames); - streamFrames = stream.frames; state = STATE_FINISHED; } } @@ -171,6 +197,8 @@ if (frame.getType() == FRAME_HEADERS) { Http2HeadersFrame headersFrame = (Http2HeadersFrame) frame; headers.addAll(headersFrame.getHeaders()); + + headerSize = headersFrame.getLength() + 9; } else if (frame.getType() == FRAME_DATA) { if (dataFrames == null) { dataFrames = new ArrayList<>(); @@ -179,6 +207,7 @@ dataFrames.add(dataFrame); byte[] data = dataFrame.getData(); contentLength += data.length; + contentSize += contentLength; } } @@ -217,6 +246,25 @@ } else if (decoder.state() == STATE_FINISHED) { processFrame(decoder.getResult()); decoder.clear(); + + if (resp != null) { + long now = handler.timeGenerator.currentTimeMillis(); + if (handler.isCollectMetrics()) { + HttpRequest lastRequest = lastRequest(flowContext); + synchronized (handler.metric) { + handler.metric.addResponseStatusCode(resp.getStatus().getCode()); + handler.metric.addResponseSize(headerSize + contentSize); + if (lastRequest != null) { + handler.metric.addResponseTime(now - (long) lastRequest.getTag(TAG_TIME_START)); + } + } + } + + resp.setTag(TAG_HEADER_SIZE, headerSize); + resp.setTag(TAG_CONTENT_SIZE, contentSize); + resp.setTag(TAG_TIME_START, flowContext.receivedStartTimestamp()); + resp.setTag(TAG_TIME_END, now); + } } } }
--- a/stress-tester/src/main/java/com/passus/st/client/http/Http2FlowHandlerDataEncoder.java Mon Jun 29 10:53:53 2020 +0200 +++ b/stress-tester/src/main/java/com/passus/st/client/http/Http2FlowHandlerDataEncoder.java Mon Jun 29 11:25:32 2020 +0200 @@ -2,7 +2,6 @@ import com.passus.data.ByteBuff; import com.passus.data.HeapByteBuff; -import com.passus.net.http.HttpHeaders; import com.passus.net.http.HttpMessage; import com.passus.net.http.HttpRequest; import com.passus.net.http2.Http2FrameEncoder; @@ -13,11 +12,15 @@ import com.passus.st.client.FlowHandlerDataEncoder; import static com.passus.net.http2.Http2Utils.*; +import static com.passus.st.client.http.HttpConsts.TAG_CONTENT_SIZE; +import static com.passus.st.client.http.HttpConsts.TAG_HEADER_SIZE; public class Http2FlowHandlerDataEncoder implements FlowHandlerDataEncoder<HttpRequest> { private static final int DEFAULT_BUFFER_CAPACITY = 1024; + private final Http2FlowHandler handler; + private final Http2FlowContext context; private final Http2FrameEncoder encoder = new Http2FrameEncoder(); @@ -28,11 +31,12 @@ private int windowSize = 1; - public Http2FlowHandlerDataEncoder(Http2FlowContext context) { + public Http2FlowHandlerDataEncoder(Http2FlowHandler handler, Http2FlowContext context) { + this.handler = handler; this.context = context; } - private void encodeHeaders(HttpMessage msg, ByteBuff out) { + private int encodeHeaders(HttpMessage msg, ByteBuff out) { byteBuffer.clear(); encoder.encodeHeaders(msg.getHeaders(), byteBuffer); @@ -48,6 +52,8 @@ Http2Stream stream = new Http2Stream(nextStreamId); stream.state = Http2Stream.STATE_OPEN; context.registerStream(stream); + + return byteBuffer.length(); } @Override @@ -78,7 +84,10 @@ context.remoteFlags &= ~Http2FlowContext.FLAG_SETTINGS_SENT; } - encodeHeaders(request, out); + int headerSize = encodeHeaders(request, out); + request.setTag(TAG_HEADER_SIZE, headerSize); + request.setTag(TAG_CONTENT_SIZE, flowContext.buffer().readableBytes() - headerSize); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stress-tester/src/main/java/com/passus/st/client/http/Http2Metric.java Mon Jun 29 11:25:32 2020 +0200 @@ -0,0 +1,10 @@ +package com.passus.st.client.http; + +public class Http2Metric extends HttpMetric { + + public static final String DEFAULT_NAME = "HTTP2"; + + public Http2Metric() { + super(DEFAULT_NAME); + } +}
--- a/stress-tester/src/main/java/com/passus/st/client/http/HttpMetric.java Mon Jun 29 10:53:53 2020 +0200 +++ b/stress-tester/src/main/java/com/passus/st/client/http/HttpMetric.java Mon Jun 29 11:25:32 2020 +0200 @@ -31,7 +31,6 @@ attrs.put("responseStatusCodes", respStatuses); attrs.put("responseTimeDist", responseTimeHistogram); attrs.put("responseSizeHistogram", responseSizeHistogram); - } @Override