From dd8a493feec756dd90099e60c362be412d1b0ed3 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Thu, 26 Feb 2026 15:31:17 +0800 Subject: [PATCH] api(metric): opt --- .../services/filter/CharResponseWrapper.java | 28 ++++++------- .../core/services/filter/HttpInterceptor.java | 20 ++++----- .../filter/ServletOutputStreamCopy.java | 41 ++++++++++++++----- 3 files changed, 54 insertions(+), 35 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/filter/CharResponseWrapper.java b/framework/src/main/java/org/tron/core/services/filter/CharResponseWrapper.java index e6421c6a257..dc1a2a85d05 100644 --- a/framework/src/main/java/org/tron/core/services/filter/CharResponseWrapper.java +++ b/framework/src/main/java/org/tron/core/services/filter/CharResponseWrapper.java @@ -9,12 +9,10 @@ public class CharResponseWrapper extends HttpServletResponseWrapper { - private ServletOutputStream outputStream; + private ServletOutputStreamCopy outputStream; private PrintWriter writer; - private ServletOutputStreamCopy streamCopy; - - public CharResponseWrapper(HttpServletResponse response) throws IOException { + public CharResponseWrapper(HttpServletResponse response) { super(response); } @@ -25,11 +23,10 @@ public ServletOutputStream getOutputStream() throws IOException { } if (outputStream == null) { - outputStream = getResponse().getOutputStream(); - streamCopy = new ServletOutputStreamCopy(outputStream); + outputStream = new ServletOutputStreamCopy(super.getOutputStream()); } - return streamCopy; + return outputStream; } @Override @@ -39,10 +36,10 @@ public PrintWriter getWriter() throws IOException { } if (writer == null) { - streamCopy = new ServletOutputStreamCopy(getResponse().getOutputStream()); + outputStream = new ServletOutputStreamCopy(super.getOutputStream()); // set auto flash so that copy can be valid - writer = new PrintWriter(new OutputStreamWriter(streamCopy, - getResponse().getCharacterEncoding()), true); + writer = new PrintWriter(new OutputStreamWriter(outputStream, super.getCharacterEncoding()), + true); } return writer; @@ -52,13 +49,16 @@ public PrintWriter getWriter() throws IOException { public void flushBuffer() throws IOException { // flush both stream if (writer != null) { writer.flush(); - } else if (outputStream != null) { - streamCopy.flush(); } + if (outputStream != null) { + outputStream.flush(); + } + super.flushBuffer(); } - public int getByteSize() { - return streamCopy == null ? 0 : streamCopy.getStreamByteSize(); + public long getByteSize() throws IOException { + flushBuffer(); + return outputStream == null ? 0 : outputStream.getStreamByteSize(); } } \ No newline at end of file diff --git a/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java b/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java index 2ff8a5ad321..1438e46aa7f 100644 --- a/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java +++ b/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java @@ -1,6 +1,5 @@ package org.tron.core.services.filter; -import com.google.common.base.Strings; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -18,9 +17,9 @@ @Slf4j(topic = "httpInterceptor") public class HttpInterceptor implements Filter { - private final int HTTP_SUCCESS = 200; - private final int HTTP_BAD_REQUEST = 400; - private final int HTTP_NOT_ACCEPTABLE = 406; + private static final int HTTP_SUCCESS = 200; + private static final int HTTP_BAD_REQUEST = 400; + private static final int HTTP_NOT_ACCEPTABLE = 406; @Override public void init(FilterConfig filterConfig) { @@ -36,20 +35,19 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha } String contextPath = ((HttpServletRequest) request).getContextPath(); endpoint = contextPath + ((HttpServletRequest) request).getServletPath(); - CharResponseWrapper responseWrapper = new CharResponseWrapper( - (HttpServletResponse) response); + CharResponseWrapper responseWrapper = new CharResponseWrapper((HttpServletResponse) response); chain.doFilter(request, responseWrapper); - HttpServletResponse resp = (HttpServletResponse) response; - int size = responseWrapper.getByteSize(); + long size = responseWrapper.getByteSize(); + int status = responseWrapper.getStatus(); MetricsUtil.meterMark(MetricsKey.NET_API_OUT_TRAFFIC, size); MetricsUtil.meterMark(MetricsKey.NET_API_QPS); - if (resp.getStatus() >= HTTP_BAD_REQUEST && resp.getStatus() <= HTTP_NOT_ACCEPTABLE) { + if (status >= HTTP_BAD_REQUEST && status <= HTTP_NOT_ACCEPTABLE) { MetricsUtil.meterMark(MetricsKey.NET_API_FAIL_QPS); Metrics.histogramObserve(MetricKeys.Histogram.HTTP_BYTES, size, MetricLabels.UNDEFINED, String.valueOf(responseWrapper.getStatus())); return; } - if (resp.getStatus() == HTTP_SUCCESS) { + if (status == HTTP_SUCCESS) { MetricsUtil.meterMark(MetricsKey.NET_API_DETAIL_QPS + endpoint); } else { MetricsUtil.meterMark(MetricsKey.NET_API_FAIL_QPS); @@ -57,7 +55,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha } MetricsUtil.meterMark(MetricsKey.NET_API_DETAIL_OUT_TRAFFIC + endpoint, size); Metrics.histogramObserve(MetricKeys.Histogram.HTTP_BYTES, - size, endpoint, String.valueOf(responseWrapper.getStatus())); + size, endpoint, String.valueOf(status)); } catch (Exception e) { String key = MetricsKey.NET_API_DETAIL_QPS + endpoint; if (MetricsUtil.getMeters(MetricsKey.NET_API_DETAIL_QPS).containsKey(key)) { diff --git a/framework/src/main/java/org/tron/core/services/filter/ServletOutputStreamCopy.java b/framework/src/main/java/org/tron/core/services/filter/ServletOutputStreamCopy.java index d29b4a4fa57..4768566bc96 100644 --- a/framework/src/main/java/org/tron/core/services/filter/ServletOutputStreamCopy.java +++ b/framework/src/main/java/org/tron/core/services/filter/ServletOutputStreamCopy.java @@ -1,35 +1,56 @@ package org.tron.core.services.filter; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicLong; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; +import org.checkerframework.checker.nullness.qual.NonNull; -class ServletOutputStreamCopy extends ServletOutputStream { +public class ServletOutputStreamCopy extends ServletOutputStream { - private OutputStream outputStream; - private ByteArrayOutputStream copy; - private int MAX_RESPONSE_SIZE = 4096; + private final OutputStream outputStream; + private final AtomicLong byteSize = new AtomicLong(0); public ServletOutputStreamCopy(OutputStream outputStream) { this.outputStream = outputStream; - this.copy = new ByteArrayOutputStream(MAX_RESPONSE_SIZE); } @Override public void write(int b) throws IOException { outputStream.write(b); - copy.write(b); + byteSize.incrementAndGet(); } - public int getStreamByteSize() { - return this.copy.size(); + @Override + public void write(byte @NonNull [] b, int off, int len) throws IOException { + outputStream.write(b, off, len); + byteSize.addAndGet(len); + } + + @Override + public void write(byte @NonNull [] b) throws IOException { + outputStream.write(b); + byteSize.addAndGet(b.length); + } + + @Override + public void flush() throws IOException { + outputStream.flush(); + } + + @Override + public void close() throws IOException { + outputStream.close(); + } + + public long getStreamByteSize() { + return byteSize.get(); } @Override public boolean isReady() { - return false; + return true; } @Override