| // Copyright (C) 2009 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.google.gerrit.server.ssh.commands; |
| |
| import com.google.gerrit.server.ssh.AdminCommand; |
| |
| import net.sf.ehcache.Ehcache; |
| import net.sf.ehcache.Statistics; |
| import net.sf.ehcache.config.CacheConfiguration; |
| |
| import org.spearce.jgit.lib.WindowCacheStatAccessor; |
| |
| import java.io.PrintWriter; |
| |
| /** Show the current cache states. */ |
| @AdminCommand |
| final class AdminShowCaches extends CacheCommand { |
| private PrintWriter p; |
| |
| @Override |
| public void start() { |
| startThread(new CommandRunnable() { |
| @Override |
| public void run() throws Exception { |
| parseCommandLine(); |
| display(); |
| } |
| }); |
| } |
| |
| private void display() { |
| p = toPrintWriter(out); |
| |
| p.print(String.format(// |
| "%1s %-18s %-4s|%-20s| %-5s |%-14s|\n" // |
| , "" // |
| , "Name" // |
| , "Max" // |
| , "Object Count" // |
| , "AvgGet" // |
| , "Hit Ratio" // |
| )); |
| p.print(String.format(// |
| "%1s %-18s %-4s|%6s %6s %6s| %-5s |%-4s %-4s %-4s|\n" // |
| , "" // |
| , "" // |
| , "Age" // |
| , "Disk" // |
| , "Mem" // |
| , "Cnt" // |
| , "" // |
| , "Disk" // |
| , "Mem" // |
| , "Agg" // |
| )); |
| p.println("------------------" |
| + "-------+--------------------+----------+--------------+"); |
| for (final Ehcache cache : getAllCaches()) { |
| final CacheConfiguration cfg = cache.getCacheConfiguration(); |
| final boolean useDisk = cfg.isDiskPersistent() || cfg.isOverflowToDisk(); |
| final Statistics stat = cache.getStatistics(); |
| final long total = stat.getCacheHits() + stat.getCacheMisses(); |
| |
| if (useDisk) { |
| p.print(String.format(// |
| "D %-18s %-4s|%6s %6s %6s| %7s |%4s %4s %4s|\n" // |
| , cache.getName() // |
| , interval(cfg.getTimeToLiveSeconds()) // |
| , count(stat.getDiskStoreObjectCount()) // |
| , count(stat.getMemoryStoreObjectCount()) // |
| , count(stat.getObjectCount()) // |
| , duration(stat.getAverageGetTime()) // |
| , percent(stat.getOnDiskHits(), total) // |
| , percent(stat.getInMemoryHits(), total) // |
| , percent(stat.getCacheHits(), total) // |
| )); |
| } else { |
| p.print(String.format(// |
| " %-18s %-4s|%6s %6s %6s| %7s |%4s %4s %4s|\n" // |
| , cache.getName() // |
| , interval(cfg.getTimeToLiveSeconds()) // |
| , "", "" // |
| , count(stat.getObjectCount()) // |
| , duration(stat.getAverageGetTime()) // |
| , "", "" // |
| , percent(stat.getCacheHits(), total) // |
| )); |
| } |
| } |
| p.println(); |
| |
| final Runtime r = Runtime.getRuntime(); |
| final long mMax = r.maxMemory(); |
| final long mFree = r.freeMemory(); |
| final long mTotal = r.totalMemory(); |
| final long mInuse = mTotal - mFree; |
| final long jgitBytes = WindowCacheStatAccessor.getOpenBytes(); |
| |
| p.println("JGit Buffer Cache:"); |
| fItemCount("open files", WindowCacheStatAccessor.getOpenFiles()); |
| fByteCount("loaded", jgitBytes); |
| fPercent("mem%", jgitBytes, mTotal); |
| p.println(); |
| |
| p.println("JVM Heap:"); |
| fByteCount("max", mMax); |
| fByteCount("inuse", mInuse); |
| fPercent("mem%", mInuse, mTotal); |
| p.println(); |
| |
| p.flush(); |
| } |
| |
| private void fItemCount(final String name, final long value) { |
| p.println(String.format(" %1$-12s: %2$15d", name, value)); |
| } |
| |
| private void fByteCount(final String name, double value) { |
| String suffix = "bytes"; |
| if (value > 1024) { |
| value /= 1024; |
| suffix = "kb"; |
| } |
| if (value > 1024) { |
| value /= 1024; |
| suffix = "mb"; |
| } |
| if (value > 1024) { |
| value /= 1024; |
| suffix = "gb"; |
| } |
| p.println(String.format(" %1$-12s: %2$6.2f %3$s", name, value, suffix)); |
| } |
| |
| private String count(long cnt) { |
| if (cnt == 0) { |
| return ""; |
| } |
| return String.format("%6d", cnt); |
| } |
| |
| private String duration(double ms) { |
| if (Math.abs(ms) <= 0.05) { |
| return ""; |
| } |
| String suffix = "ms"; |
| if (ms >= 1000) { |
| ms /= 1000; |
| suffix = "s "; |
| } |
| return String.format("%4.1f%s", ms, suffix); |
| } |
| |
| private String interval(double ttl) { |
| if (ttl == 0) { |
| return "inf"; |
| } |
| |
| String suffix = "s"; |
| if (ttl >= 60) { |
| ttl /= 60; |
| suffix = "m"; |
| |
| if (ttl >= 60) { |
| ttl /= 60; |
| suffix = "h"; |
| } |
| |
| if (ttl >= 24) { |
| ttl /= 24; |
| suffix = "d"; |
| |
| if (ttl >= 365) { |
| ttl /= 365; |
| suffix = "y"; |
| } |
| } |
| } |
| |
| return Integer.toString((int) ttl) + suffix; |
| } |
| |
| private String percent(final long value, final long total) { |
| if (total <= 0) { |
| return ""; |
| } |
| final long pcent = (100 * value) / total; |
| return String.format("%3d%%", (int) pcent); |
| } |
| |
| private void fPercent(final String name, final long value, final long total) { |
| final long pcent = 0 < total ? (100 * value) / total : 0; |
| p.println(String.format(" %1$-12s: %2$3d%%", name, (int) pcent)); |
| } |
| } |