LCOV - code coverage report
Current view: top level - server/restapi/config - GetSummary.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 85 124 68.5 %
Date: 2022-11-19 15:00:39 Functions: 11 16 68.8 %

          Line data    Source code
       1             : // Copyright (C) 2014 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.server.restapi.config;
      16             : 
      17             : import com.google.gerrit.common.Nullable;
      18             : import com.google.gerrit.common.data.GlobalCapability;
      19             : import com.google.gerrit.extensions.annotations.RequiresCapability;
      20             : import com.google.gerrit.extensions.restapi.Response;
      21             : import com.google.gerrit.extensions.restapi.RestReadView;
      22             : import com.google.gerrit.server.config.ConfigResource;
      23             : import com.google.gerrit.server.config.SitePath;
      24             : import com.google.gerrit.server.git.WorkQueue;
      25             : import com.google.gerrit.server.git.WorkQueue.Task;
      26             : import com.google.inject.Inject;
      27             : import java.io.IOException;
      28             : import java.lang.management.ManagementFactory;
      29             : import java.lang.management.OperatingSystemMXBean;
      30             : import java.lang.management.RuntimeMXBean;
      31             : import java.lang.management.ThreadInfo;
      32             : import java.lang.management.ThreadMXBean;
      33             : import java.net.InetAddress;
      34             : import java.net.UnknownHostException;
      35             : import java.nio.file.Path;
      36             : import java.nio.file.Paths;
      37             : import java.util.Arrays;
      38             : import java.util.Collection;
      39             : import java.util.HashMap;
      40             : import java.util.List;
      41             : import java.util.Map;
      42             : import org.eclipse.jgit.storage.file.WindowCacheStats;
      43             : import org.kohsuke.args4j.Option;
      44             : 
      45             : @RequiresCapability(GlobalCapability.MAINTAIN_SERVER)
      46             : public class GetSummary implements RestReadView<ConfigResource> {
      47             : 
      48             :   private final WorkQueue workQueue;
      49             :   private final Path sitePath;
      50             : 
      51             :   @Option(name = "--gc", usage = "perform Java GC before retrieving memory stats")
      52             :   private boolean gc;
      53             : 
      54             :   public GetSummary setGc(boolean gc) {
      55           0 :     this.gc = gc;
      56           0 :     return this;
      57             :   }
      58             : 
      59             :   @Option(name = "--jvm", usage = "include details about the JVM")
      60             :   private boolean jvm;
      61             : 
      62             :   public GetSummary setJvm(boolean jvm) {
      63           0 :     this.jvm = jvm;
      64           0 :     return this;
      65             :   }
      66             : 
      67             :   @Inject
      68           2 :   public GetSummary(WorkQueue workQueue, @SitePath Path sitePath) {
      69           2 :     this.workQueue = workQueue;
      70           2 :     this.sitePath = sitePath;
      71           2 :   }
      72             : 
      73             :   @Override
      74             :   public Response<SummaryInfo> apply(ConfigResource rsrc) {
      75           1 :     if (gc) {
      76           0 :       System.gc();
      77           0 :       System.runFinalization();
      78           0 :       System.gc();
      79             :     }
      80             : 
      81           1 :     SummaryInfo summary = new SummaryInfo();
      82           1 :     summary.taskSummary = getTaskSummary();
      83           1 :     summary.memSummary = getMemSummary();
      84           1 :     summary.threadSummary = getThreadSummary();
      85           1 :     if (jvm) {
      86           0 :       summary.jvmSummary = getJvmSummary();
      87             :     }
      88           1 :     return Response.ok(summary);
      89             :   }
      90             : 
      91             :   private TaskSummaryInfo getTaskSummary() {
      92           1 :     Collection<Task<?>> pending = workQueue.getTasks();
      93           1 :     int tasksTotal = pending.size();
      94           1 :     int tasksStopping = 0;
      95           1 :     int tasksRunning = 0;
      96           1 :     int tasksStarting = 0;
      97           1 :     int tasksReady = 0;
      98           1 :     int tasksSleeping = 0;
      99           1 :     for (Task<?> task : pending) {
     100           1 :       switch (task.getState()) {
     101             :         case STOPPING:
     102           0 :           tasksStopping++;
     103           0 :           break;
     104             :         case RUNNING:
     105           0 :           tasksRunning++;
     106           0 :           break;
     107             :         case STARTING:
     108           0 :           tasksStarting++;
     109           0 :           break;
     110             :         case READY:
     111           0 :           tasksReady++;
     112           0 :           break;
     113             :         case SLEEPING:
     114           1 :           tasksSleeping++;
     115           1 :           break;
     116             :         case CANCELLED:
     117             :         case DONE:
     118             :         case OTHER:
     119             :           break;
     120             :       }
     121           1 :     }
     122             : 
     123           1 :     TaskSummaryInfo taskSummary = new TaskSummaryInfo();
     124           1 :     taskSummary.total = toInteger(tasksTotal);
     125           1 :     taskSummary.stopping = toInteger(tasksStopping);
     126           1 :     taskSummary.running = toInteger(tasksRunning);
     127           1 :     taskSummary.starting = toInteger(tasksStarting);
     128           1 :     taskSummary.ready = toInteger(tasksReady);
     129           1 :     taskSummary.sleeping = toInteger(tasksSleeping);
     130           1 :     return taskSummary;
     131             :   }
     132             : 
     133             :   private MemSummaryInfo getMemSummary() {
     134           1 :     Runtime r = Runtime.getRuntime();
     135           1 :     long mMax = r.maxMemory();
     136           1 :     long mFree = r.freeMemory();
     137           1 :     long mTotal = r.totalMemory();
     138           1 :     long mInuse = mTotal - mFree;
     139             : 
     140           1 :     long jgitOpen = WindowCacheStats.getStats().getOpenFileCount();
     141           1 :     long jgitBytes = WindowCacheStats.getStats().getOpenByteCount();
     142             : 
     143           1 :     MemSummaryInfo memSummaryInfo = new MemSummaryInfo();
     144           1 :     memSummaryInfo.total = bytes(mTotal);
     145           1 :     memSummaryInfo.used = bytes(mInuse - jgitBytes);
     146           1 :     memSummaryInfo.free = bytes(mFree);
     147           1 :     memSummaryInfo.buffers = bytes(jgitBytes);
     148           1 :     memSummaryInfo.max = bytes(mMax);
     149           1 :     memSummaryInfo.openFiles = Long.valueOf(jgitOpen);
     150           1 :     return memSummaryInfo;
     151             :   }
     152             : 
     153             :   private ThreadSummaryInfo getThreadSummary() {
     154           1 :     Runtime r = Runtime.getRuntime();
     155           1 :     ThreadSummaryInfo threadInfo = new ThreadSummaryInfo();
     156           1 :     threadInfo.cpus = r.availableProcessors();
     157           1 :     threadInfo.threads = toInteger(ManagementFactory.getThreadMXBean().getThreadCount());
     158             : 
     159           1 :     List<String> prefixes =
     160           1 :         Arrays.asList(
     161             :             "H2",
     162             :             "HTTP",
     163             :             "IntraLineDiff",
     164             :             "ReceiveCommits",
     165             :             "SSH git-receive-pack",
     166             :             "SSH git-upload-pack",
     167             :             "SSH-Interactive-Worker",
     168             :             "SSH-Stream-Worker",
     169             :             "SshCommandStart",
     170             :             "sshd-SshServer");
     171           1 :     String other = "Other";
     172           1 :     ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
     173             : 
     174           1 :     threadInfo.counts = new HashMap<>();
     175           1 :     for (long id : threadMXBean.getAllThreadIds()) {
     176           1 :       ThreadInfo info = threadMXBean.getThreadInfo(id);
     177           1 :       if (info == null) {
     178           0 :         continue;
     179             :       }
     180           1 :       String name = info.getThreadName();
     181           1 :       Thread.State state = info.getThreadState();
     182           1 :       String group = other;
     183           1 :       for (String p : prefixes) {
     184           1 :         if (name.startsWith(p)) {
     185           1 :           group = p;
     186           1 :           break;
     187             :         }
     188           1 :       }
     189           1 :       Map<Thread.State, Integer> counts = threadInfo.counts.get(group);
     190           1 :       if (counts == null) {
     191           1 :         counts = new HashMap<>();
     192           1 :         threadInfo.counts.put(group, counts);
     193             :       }
     194           1 :       Integer c = counts.get(state);
     195           1 :       counts.put(state, c != null ? c + 1 : 1);
     196             :     }
     197             : 
     198           1 :     return threadInfo;
     199             :   }
     200             : 
     201             :   private JvmSummaryInfo getJvmSummary() {
     202           0 :     OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
     203           0 :     RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
     204             : 
     205           0 :     JvmSummaryInfo jvmSummary = new JvmSummaryInfo();
     206           0 :     jvmSummary.vmVendor = runtimeBean.getVmVendor();
     207           0 :     jvmSummary.vmName = runtimeBean.getVmName();
     208           0 :     jvmSummary.vmVersion = runtimeBean.getVmVersion();
     209           0 :     jvmSummary.osName = osBean.getName();
     210           0 :     jvmSummary.osVersion = osBean.getVersion();
     211           0 :     jvmSummary.osArch = osBean.getArch();
     212           0 :     jvmSummary.user = System.getProperty("user.name");
     213             : 
     214             :     try {
     215           0 :       jvmSummary.host = InetAddress.getLocalHost().getHostName();
     216           0 :     } catch (UnknownHostException e) {
     217             :       // Ignored
     218           0 :     }
     219             : 
     220           0 :     jvmSummary.currentWorkingDirectory = path(Paths.get(".").toAbsolutePath().getParent());
     221           0 :     jvmSummary.site = path(sitePath);
     222           0 :     return jvmSummary;
     223             :   }
     224             : 
     225             :   @Nullable
     226             :   private static Integer toInteger(int i) {
     227           1 :     return i != 0 ? i : null;
     228             :   }
     229             : 
     230             :   private static String bytes(double value) {
     231           1 :     value /= 1024;
     232           1 :     String suffix = "k";
     233             : 
     234           1 :     if (value > 1024) {
     235           1 :       value /= 1024;
     236           1 :       suffix = "m";
     237             :     }
     238           1 :     if (value > 1024) {
     239           0 :       value /= 1024;
     240           0 :       suffix = "g";
     241             :     }
     242           1 :     return String.format("%1$6.2f%2$s", value, suffix).trim();
     243             :   }
     244             : 
     245             :   private static String path(Path path) {
     246             :     try {
     247           0 :       return path.toRealPath().normalize().toString();
     248           0 :     } catch (IOException err) {
     249           0 :       return path.toAbsolutePath().normalize().toString();
     250             :     }
     251             :   }
     252             : 
     253           1 :   public static class SummaryInfo {
     254             :     public TaskSummaryInfo taskSummary;
     255             :     public MemSummaryInfo memSummary;
     256             :     public ThreadSummaryInfo threadSummary;
     257             :     public JvmSummaryInfo jvmSummary;
     258             :   }
     259             : 
     260           1 :   public static class TaskSummaryInfo {
     261             :     public Integer total;
     262             :     public Integer stopping;
     263             :     public Integer running;
     264             :     public Integer starting;
     265             :     public Integer ready;
     266             :     public Integer sleeping;
     267             :   }
     268             : 
     269           1 :   public static class MemSummaryInfo {
     270             :     public String total;
     271             :     public String used;
     272             :     public String free;
     273             :     public String buffers;
     274             :     public String max;
     275             :     public Long openFiles;
     276             :   }
     277             : 
     278           1 :   public static class ThreadSummaryInfo {
     279             :     public Integer cpus;
     280             :     public Integer threads;
     281             :     public Map<String, Map<Thread.State, Integer>> counts;
     282             :   }
     283             : 
     284           0 :   public static class JvmSummaryInfo {
     285             :     public String vmVendor;
     286             :     public String vmName;
     287             :     public String vmVersion;
     288             :     public String osName;
     289             :     public String osVersion;
     290             :     public String osArch;
     291             :     public String user;
     292             :     public String host;
     293             :     public String currentWorkingDirectory;
     294             :     public String site;
     295             :   }
     296             : }

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