LCOV - code coverage report
Current view: top level - httpd - RequestMetricsFilter.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 38 42 90.5 %
Date: 2022-11-19 15:00:39 Functions: 17 18 94.4 %

          Line data    Source code
       1             : // Copyright (C) 2015 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.httpd;
      16             : 
      17             : import com.google.gerrit.metrics.proc.ThreadMXBeanFactory;
      18             : import com.google.gerrit.metrics.proc.ThreadMXBeanInterface;
      19             : import com.google.inject.Inject;
      20             : import com.google.inject.Module;
      21             : import com.google.inject.Singleton;
      22             : import com.google.inject.servlet.ServletModule;
      23             : import java.io.IOException;
      24             : import javax.servlet.Filter;
      25             : import javax.servlet.FilterChain;
      26             : import javax.servlet.FilterConfig;
      27             : import javax.servlet.ServletException;
      28             : import javax.servlet.ServletRequest;
      29             : import javax.servlet.ServletResponse;
      30             : import javax.servlet.http.HttpServletResponse;
      31             : import javax.servlet.http.HttpServletResponseWrapper;
      32             : 
      33             : @Singleton
      34             : public class RequestMetricsFilter implements Filter {
      35             :   public static final String METRICS_CONTEXT = "metrics-context";
      36             : 
      37             :   public static Module module() {
      38          99 :     return new ServletModule() {
      39             :       @Override
      40             :       protected void configureServlets() {
      41          99 :         filter("/*").through(RequestMetricsFilter.class);
      42          99 :       }
      43             :     };
      44             :   }
      45             : 
      46             :   public static class Context {
      47          38 :     private static final ThreadMXBeanInterface threadMxBean = ThreadMXBeanFactory.create();
      48             :     private final long startedTotalCpu;
      49             :     private final long startedUserCpu;
      50             :     private final long startedMemory;
      51             : 
      52          38 :     Context() {
      53          38 :       startedTotalCpu = threadMxBean.getCurrentThreadCpuTime();
      54          38 :       startedUserCpu = threadMxBean.getCurrentThreadUserTime();
      55          38 :       startedMemory = threadMxBean.getCurrentThreadAllocatedBytes();
      56          38 :     }
      57             : 
      58             :     /** Returns total CPU time in milliseconds for executing request */
      59             :     public long getTotalCpuTime() {
      60           6 :       return (threadMxBean.getCurrentThreadCpuTime() - startedTotalCpu) / 1_000_000;
      61             :     }
      62             : 
      63             :     /** Returns CPU time in user mode in milliseconds for executing request */
      64             :     public long getUserCpuTime() {
      65           6 :       return (threadMxBean.getCurrentThreadUserTime() - startedUserCpu) / 1_000_000;
      66             :     }
      67             : 
      68             :     /** Returns memory allocated in bytes for executing request */
      69             :     public long getAllocatedMemory() {
      70           6 :       return startedMemory == -1
      71           0 :           ? -1
      72           6 :           : threadMxBean.getCurrentThreadAllocatedBytes() - startedMemory;
      73             :     }
      74             :   }
      75             : 
      76             :   private final RequestMetrics metrics;
      77             : 
      78             :   @Inject
      79          99 :   RequestMetricsFilter(RequestMetrics metrics) {
      80          99 :     this.metrics = metrics;
      81          99 :   }
      82             : 
      83             :   @Override
      84          99 :   public void destroy() {}
      85             : 
      86             :   @Override
      87             :   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      88             :       throws IOException, ServletException {
      89          38 :     request.setAttribute(METRICS_CONTEXT, new Context());
      90          38 :     Response rsp = new Response((HttpServletResponse) response, metrics);
      91             : 
      92          38 :     chain.doFilter(request, rsp);
      93          38 :   }
      94             : 
      95             :   @Override
      96          99 :   public void init(FilterConfig cfg) throws ServletException {}
      97             : 
      98             :   private static class Response extends HttpServletResponseWrapper {
      99             :     private final RequestMetrics metrics;
     100             : 
     101             :     Response(HttpServletResponse response, RequestMetrics metrics) {
     102          38 :       super(response);
     103          38 :       this.metrics = metrics;
     104          38 :     }
     105             : 
     106             :     @Override
     107             :     public void sendError(int sc, String msg) throws IOException {
     108           1 :       status(sc);
     109           1 :       super.sendError(sc, msg);
     110           1 :     }
     111             : 
     112             :     @Override
     113             :     public void sendError(int sc) throws IOException {
     114          31 :       status(sc);
     115          31 :       super.sendError(sc);
     116          31 :     }
     117             : 
     118             :     @Override
     119             :     @Deprecated
     120             :     public void setStatus(int sc, String sm) {
     121           0 :       status(sc);
     122           0 :       super.setStatus(sc, sm);
     123           0 :     }
     124             : 
     125             :     @Override
     126             :     public void setStatus(int sc) {
     127          33 :       status(sc);
     128          33 :       super.setStatus(sc);
     129          33 :     }
     130             : 
     131             :     private void status(int sc) {
     132          33 :       if (sc >= SC_BAD_REQUEST) {
     133          31 :         metrics.errors.increment(sc);
     134             :       } else {
     135          30 :         metrics.successes.increment(sc);
     136             :       }
     137          33 :     }
     138             :   }
     139             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750