diff --git a/docs/content/operations/metrics.md b/docs/content/operations/metrics.md index a3964d4a102..2669208c175 100644 --- a/docs/content/operations/metrics.md +++ b/docs/content/operations/metrics.md @@ -29,8 +29,9 @@ Available Metrics |Metric|Description|Dimensions|Normal Value| |------|-----------|----------|------------| |`query/time`|Milliseconds taken to complete a query.|Common: dataSource, type, interval, hasFilters, duration, context, remoteAddress, id. Aggregation Queries: numMetrics, numComplexMetrics. GroupBy: numDimensions. TopN: threshold, dimension.|< 1s| +|`query/bytes`|number of bytes returned in query response.|Common: dataSource, type, interval, hasFilters, duration, context, remoteAddress, id. Aggregation Queries: numMetrics, numComplexMetrics. GroupBy: numDimensions. TopN: threshold, dimension.| | |`query/node/time`|Milliseconds taken to query individual historical/realtime nodes.|id, status, server.|< 1s| -|`query/node/bytes`|bytes returned from querying individual historical/realtime nodes.|id, status, server.| | +|`query/node/bytes`|number of bytes returned from querying individual historical/realtime nodes.|id, status, server.| | |`query/node/ttfb`|Time to first byte. Milliseconds elapsed until broker starts receiving the response from individual historical/realtime nodes.|id, status, server.|< 1s| |`query/intervalChunk/time`|Only emitted if interval chunking is enabled. Milliseconds required to query an interval chunk.|id, status, chunkInterval (if interval chunking is enabled).|< 1s| diff --git a/server/src/main/java/io/druid/server/QueryResource.java b/server/src/main/java/io/druid/server/QueryResource.java index 7f0900a835e..0ebe1b52d51 100644 --- a/server/src/main/java/io/druid/server/QueryResource.java +++ b/server/src/main/java/io/druid/server/QueryResource.java @@ -25,6 +25,7 @@ import com.fasterxml.jackson.jaxrs.smile.SmileMediaTypes; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; import com.google.common.collect.MapMaker; +import com.google.common.io.CountingOutputStream; import com.google.inject.Inject; import com.metamx.common.guava.Sequence; import com.metamx.common.guava.Sequences; @@ -184,15 +185,21 @@ public class QueryResource public void write(OutputStream outputStream) throws IOException, WebApplicationException { // json serializer will always close the yielder - jsonWriter.writeValue(outputStream, yielder); - outputStream.flush(); // Some types of OutputStream suppress flush errors in the .close() method. - outputStream.close(); + CountingOutputStream os = new CountingOutputStream(outputStream); + jsonWriter.writeValue(os, yielder); + + os.flush(); // Some types of OutputStream suppress flush errors in the .close() method. + os.close(); final long queryTime = System.currentTimeMillis() - start; emitter.emit( DruidMetrics.makeQueryTimeMetric(jsonMapper, theQuery, req.getRemoteAddr()) .build("query/time", queryTime) ); + emitter.emit( + DruidMetrics.makeQueryTimeMetric(jsonMapper, theQuery, req.getRemoteAddr()) + .build("query/bytes", os.getCount()) + ); requestLogger.log( new RequestLogLine( @@ -202,6 +209,7 @@ public class QueryResource new QueryStats( ImmutableMap.of( "query/time", queryTime, + "query/bytes", os.getCount(), "success", true ) )