LCOV - code coverage report
Current view: top level - pgm/http/jetty - HttpLog.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 46 48 95.8 %
Date: 2022-11-19 15:00:39 Functions: 7 7 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2010 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.pgm.http.jetty;
      16             : 
      17             : import static com.google.gerrit.httpd.GitOverHttpServlet.GIT_COMMAND_STATUS_HEADER;
      18             : 
      19             : import com.google.common.base.Strings;
      20             : import com.google.gerrit.httpd.GetUserFilter;
      21             : import com.google.gerrit.httpd.RequestMetricsFilter;
      22             : import com.google.gerrit.httpd.restapi.LogRedactUtil;
      23             : import com.google.gerrit.server.config.GerritServerConfig;
      24             : import com.google.gerrit.server.util.SystemLog;
      25             : import com.google.gerrit.server.util.time.TimeUtil;
      26             : import com.google.inject.Inject;
      27             : import org.apache.log4j.AsyncAppender;
      28             : import org.apache.log4j.Level;
      29             : import org.apache.log4j.Logger;
      30             : import org.apache.log4j.spi.LoggingEvent;
      31             : import org.eclipse.jetty.server.Request;
      32             : import org.eclipse.jetty.server.RequestLog;
      33             : import org.eclipse.jetty.server.Response;
      34             : import org.eclipse.jetty.util.component.AbstractLifeCycle;
      35             : import org.eclipse.jgit.lib.Config;
      36             : 
      37             : /** Writes the {@code httpd_log} file with per-request data. */
      38             : class HttpLog extends AbstractLifeCycle implements RequestLog {
      39          15 :   private static final Logger log = Logger.getLogger(HttpLog.class);
      40             :   private static final String LOG_NAME = "httpd_log";
      41             :   private static final String JSON_SUFFIX = ".json";
      42             : 
      43             :   interface HttpLogFactory {
      44             :     HttpLog get();
      45             :   }
      46             : 
      47             :   protected static final String P_HOST = "Host";
      48             :   protected static final String P_USER = "User";
      49             :   protected static final String P_METHOD = "Method";
      50             :   protected static final String P_RESOURCE = "Resource";
      51             :   protected static final String P_PROTOCOL = "Version";
      52             :   protected static final String P_STATUS = "Status";
      53             :   protected static final String P_CONTENT_LENGTH = "Content-Length";
      54             :   protected static final String P_LATENCY = "Latency";
      55             :   protected static final String P_REFERER = "Referer";
      56             :   protected static final String P_USER_AGENT = "User-Agent";
      57             :   protected static final String P_CPU_TOTAL = "Cpu-Total";
      58             :   protected static final String P_CPU_USER = "Cpu-User";
      59             :   protected static final String P_MEMORY = "Memory";
      60             :   protected static final String P_COMMAND_STATUS = "Command-Status";
      61             : 
      62             :   private final AsyncAppender async;
      63             : 
      64             :   @Inject
      65          15 :   HttpLog(SystemLog systemLog, @GerritServerConfig Config config) {
      66          15 :     boolean json = config.getBoolean("log", "jsonLogging", false);
      67          15 :     boolean text = config.getBoolean("log", "textLogging", true) || !json;
      68             : 
      69          15 :     async = new AsyncAppender();
      70             : 
      71          15 :     if (text) {
      72          15 :       async.addAppender(systemLog.createAsyncAppender(LOG_NAME, new HttpLogLayout()));
      73             :     }
      74             : 
      75          15 :     if (json) {
      76           0 :       async.addAppender(
      77           0 :           systemLog.createAsyncAppender(LOG_NAME + JSON_SUFFIX, new HttpLogJsonLayout()));
      78             :     }
      79          15 :   }
      80             : 
      81             :   @Override
      82          15 :   protected void doStart() throws Exception {}
      83             : 
      84             :   @Override
      85             :   protected void doStop() throws Exception {
      86          15 :     async.close();
      87          15 :   }
      88             : 
      89             :   @Override
      90             :   public void log(Request req, Response rsp) {
      91           6 :     final LoggingEvent event =
      92             :         new LoggingEvent( //
      93           6 :             Logger.class.getName(), // fqnOfCategoryClass
      94             :             log, // logger
      95           6 :             TimeUtil.nowMs(), // when
      96             :             Level.INFO, // level
      97             :             "", // message text
      98           6 :             Thread.currentThread().getName(), // thread name
      99             :             null, // exception information
     100             :             null, // current NDC string
     101             :             null, // caller location
     102             :             null // MDC properties
     103             :             );
     104             : 
     105           6 :     String uri = req.getRequestURI();
     106           6 :     if (!Strings.isNullOrEmpty(req.getQueryString())) {
     107           3 :       uri += "?" + LogRedactUtil.redactQueryString(req.getQueryString());
     108             :     }
     109           6 :     String user = (String) req.getAttribute(GetUserFilter.USER_ATTR_KEY);
     110           6 :     if (user != null) {
     111           5 :       event.setProperty(P_USER, user);
     112             :     }
     113             : 
     114           6 :     set(event, P_HOST, req.getRemoteAddr());
     115           6 :     set(event, P_METHOD, req.getMethod());
     116           6 :     set(event, P_RESOURCE, uri);
     117           6 :     set(event, P_PROTOCOL, req.getProtocol());
     118           6 :     set(event, P_STATUS, rsp.getStatus());
     119           6 :     set(event, P_CONTENT_LENGTH, rsp.getContentCount());
     120           6 :     set(event, P_LATENCY, System.currentTimeMillis() - req.getTimeStamp());
     121           6 :     set(event, P_REFERER, req.getHeader("Referer"));
     122           6 :     set(event, P_USER_AGENT, req.getHeader("User-Agent"));
     123           6 :     set(event, P_COMMAND_STATUS, rsp.getHeader(GIT_COMMAND_STATUS_HEADER));
     124             : 
     125           6 :     RequestMetricsFilter.Context ctx =
     126           6 :         (RequestMetricsFilter.Context) req.getAttribute(RequestMetricsFilter.METRICS_CONTEXT);
     127           6 :     if (ctx != null) {
     128           6 :       set(event, P_CPU_TOTAL, ctx.getTotalCpuTime());
     129           6 :       set(event, P_CPU_USER, ctx.getUserCpuTime());
     130           6 :       set(event, P_MEMORY, ctx.getAllocatedMemory());
     131             :     }
     132             : 
     133           6 :     async.append(event);
     134           6 :   }
     135             : 
     136             :   private static void set(LoggingEvent event, String key, String val) {
     137           6 :     if (val != null && !val.isEmpty()) {
     138           6 :       event.setProperty(key, val);
     139             :     }
     140           6 :   }
     141             : 
     142             :   private static void set(LoggingEvent event, String key, long val) {
     143           6 :     if (0 < val) {
     144           6 :       event.setProperty(key, String.valueOf(val));
     145             :     }
     146           6 :   }
     147             : }

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