ChunkStorageStatsCommand class

Пакет: com.hypixel.hytale.server.core.command.commands.world.chunk

Файл: com/hypixel/hytale/server/core/command/commands/world/chunk/ChunkStorageStatsCommand.java

extends: AbstractWorldCommand

Поля (57)

МодификаторыТипИмя
break
break
break
continue
return
long var1
MetricResults var10
long var10
Path var11
String var11
BsonValue var11
long var12
long var12
BsonDocument var14
long var14
String var15
BsonValue var16
BsonDocument var16
long var16
StringBuilder var17
double var18
BsonValue var2
BsonValue var2
String var20
String var21
String var22
var22
var22
String var23
String var24
BsonDocument var3
Iterator var3
ChunkStore var4
ExtraInfo var4
BsonDocument var4
Entry var4
IChunkLoader var5
BsonValue var5
String var5
var5
BsonDocument var5
IChunkSaver var6
BsonValue var6
long var6
MetricResults var7
BsonValue var7
String var7
String var7
var7
var7
var7
Path var8
BsonValue var8
long var8
long var8
long var9
BsonArray var9

Методы (26)

МодификаторыВозвратСигнатура
for for(BsonValue var4 : var2)
abstract for for(int var10 = 0; var10 < var9.size()
if if(var7 == null && var10 == null)
if if(var1 != null)
if if(var5 != null)
if if(var2 != null)
if if(var7 != null)
if if(var4 != null && var2 != null)
if if(var5 != null && var3 != null)
if if(var10 > 0)
if if(var2 == null)
if if(var8 > 0L)
if if(var10 > 0L)
if if(var2 == null)
static boolean looksLikeBytesboolean looksLikeBytes(@Nonnull String var0)
static boolean looksLikeHistogramboolean looksLikeHistogram(@Nonnull BsonDocument var0)
static long readLonglong readLong(@Nonnull BsonDocument var0, @Nonnull String var1)
static void sendCounterGroupvoid sendCounterGroup(@Nonnull CommandContext var0, @Nonnull String var1, @Nonnull BsonDocument var2)
abstract sendCounterGroup sendCounterGroup(var0, var15, var14)
static void sendSectionvoid sendSection(@Nonnull CommandContext var0, @Nonnull String var1, @Nonnull String var2, @Nonnull MetricResults var3)
static void sendStatsBlockvoid sendStatsBlock(@Nonnull CommandContext var0, @Nonnull String var1, @Nonnull BsonArray var2)
static void sendSummaryvoid sendSummary(@Nonnull CommandContext var0, @Nonnull World var1, @Nullable Object var2, @Nullable Object var3, @Nullable MetricResults var4, @Nullable MetricResults var5)
abstract sendSummary sendSummary(var1, var2, var5, var6, var7, var10)
abstract super super("storagestats", "server.commands.chunk.storagestats.desc")
while while(true)
while while(true)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.command.commands.world.chunk;

class="kw">import com.hypixel.hytale.codec.ExtraInfo;
class="kw">import com.hypixel.hytale.common.util.FormatUtil;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.metrics.MetricProvider;
class="kw">import com.hypixel.hytale.metrics.MetricResults;
class="kw">import com.hypixel.hytale.metrics.MetricsRegistry;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.command.system.CommandContext;
class="kw">import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;
class="kw">import com.hypixel.hytale.server.core.command.system.basecommands.AbstractWorldCommand;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.IChunkLoader;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.IChunkSaver;
class="kw">import com.hypixel.hytale.server.core.util.BsonUtil;
class="kw">import com.hypixel.hytale.sneakythrow.SneakyThrow;
class="kw">import java.io.IOException;
class="kw">import java.nio.file.Files;
class="kw">import java.nio.file.Path;
class="kw">import java.util.Iterator;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.bson.BsonArray;
class="kw">import org.bson.BsonDocument;
class="kw">import org.bson.BsonString;
class="kw">import org.bson.BsonValue;

class="kw">public class ChunkStorageStatsCommand class="kw">extends AbstractWorldCommand {
   @Nonnull
   class="kw">private class="kw">static class="kw">final Message MESSAGE_NO_METRICS = Message.translation("server.commands.chunk.storagestats.noMetrics");
   @Nonnull
   class="kw">private class="kw">final FlagArg jsonFlag = this.withFlagArg("json", "server.commands.chunk.storagestats.json.desc");

   class="kw">public ChunkStorageStatsCommand() {
      super("storagestats", "server.commands.chunk.storagestats.desc");
   }

   @Override
   class="kw">protected void execute(@Nonnull CommandContext var1, @Nonnull World var2, @Nonnull Store<EntityStore> var3) {
      ChunkStore var4 = var2.getChunkStore();
      IChunkLoader var5 = var4.getLoader();
      IChunkSaver var6 = var4.getSaver();
      MetricResults var7 = var5 class="kw">instanceof MetricProvider var8 ? var8.toMetricResults() : null;
      MetricResults var10 = var6 class="kw">instanceof MetricProvider var9 ? var9.toMetricResults() : null;
      if (var7 == null && var10 == null) {
         var1.sendMessage(MESSAGE_NO_METRICS);
      } else if (this.jsonFlag.provided(var1)) {
         Path var11 = writeDump(var2, var7, var10);
         var1.sendMessage(Message.translation("server.commands.chunk.storagestats.dumped").param("filepath", var11.toAbsolutePath().toString()));
      } else {
         sendSummary(var1, var2, var5, var6, var7, var10);
      }
   }

   @Nonnull
   class="kw">private class="kw">static Path writeDump(@Nonnull World var0, @Nullable MetricResults var1, @Nullable MetricResults var2) {
      BsonDocument var3 = new BsonDocument();
      var3.put("World", new BsonString(var0.getName()));
      ExtraInfo var4 = ExtraInfo.THREAD_LOCAL.get();
      if (var1 != null) {
         BsonValue var5 = MetricResults.CODEC.encode(var1, var4);
         if (var5 != null) {
            var3.put("Loader", var5);
         }
      }

      if (var2 != null) {
         BsonValue var7 = MetricResults.CODEC.encode(var2, var4);
         if (var7 != null) {
            var3.put("Saver", var7);
         }
      }

      try {
         Path var8 = MetricsRegistry.createDumpPath("chunk-storage-stats-", ".dump.json");
         Files.writeString(var8, BsonUtil.toJson(var3));
         class="kw">return var8;
      } catch (IOException var6) {
         throw SneakyThrow.sneakyThrow(var6);
      }
   }

   class="kw">private class="kw">static void sendSummary(
      @Nonnull CommandContext var0,
      @Nonnull World var1,
      @Nullable Object var2,
      @Nullable Object var3,
      @Nullable MetricResults var4,
      @Nullable MetricResults var5
   ) {
      var0.sendMessage(
         Message.translation("server.commands.chunk.storagestats.header")
            .param("worldName", var1.getName())
            .param("provider", var1.getWorldConfig().getChunkStorageProvider().getClass().getSimpleName())
      );
      if (var4 != null && var2 != null) {
         sendSection(var0, "loader", var2.getClass().getSimpleName(), var4);
      }

      if (var5 != null && var3 != null) {
         sendSection(var0, "saver", var3.getClass().getSimpleName(), var5);
      }
   }

   class="kw">private class="kw">static void sendSection(@Nonnull CommandContext var0, @Nonnull String var1, @Nonnull String var2, @Nonnull MetricResults var3) {
      BsonDocument var4 = MetricResults.CODEC.encode(var3, ExtraInfo.THREAD_LOCAL.get()).asDocument();
      var0.sendMessage(Message.translation("server.commands.chunk.storagestats." + var1 + ".header").param("className", var2));

      for (Entry var6 : var4.entrySet()) {
         String var7 = var6.getKey();
         BsonValue var8 = var6.getValue();
         if (var8.isInt64() || var8.isInt32()) {
            long var9 = var8.isInt64() ? var8.asInt64().getValue() : var8.asInt32().getValue();
            String var11 = looksLikeBytes(var7) ? FormatUtil.bytesToString(var9) : Long.toString(var9);
            var0.sendMessage(Message.translation("server.commands.chunk.storagestats.counter").param("key", var7).param("value", var11));
         }
      }

      for (Entry var13 : var4.entrySet()) {
         if (var13.getValue().isDocument()) {
            BsonDocument var14 = var13.getValue().asDocument();
            String var15 = stripStatsSuffix(var13.getKey());
            BsonValue var16 = var14.get("Periods");
            if (var16 != null && var16.isArray()) {
               sendStatsBlock(var0, var15, var16.asArray());
            } else {
               sendCounterGroup(var0, var15, var14);
            }
         }
      }
   }

   @Nonnull
   class="kw">private class="kw">static String stripStatsSuffix(@Nonnull String var0) {
      class="kw">return var0.endsWith("Stats") ? var0.substring(0, var0.length() - "Stats".length()) : var0;
   }

   class="kw">private class="kw">static void sendCounterGroup(@Nonnull CommandContext var0, @Nonnull String var1, @Nonnull BsonDocument var2) {
      if (!var2.isEmpty()) {
         var0.sendMessage(Message.translation("server.commands.chunk.storagestats.group.header").param("label", var1));
         Iterator var3 = var2.entrySet().iterator();

         while (true) {
            String var5;
            String var7;
            while (true) {
               if (!var3.hasNext()) {
                  for (Entry var15 : var2.entrySet()) {
                     if (var15.getValue().isDocument()) {
                        BsonDocument var16 = var15.getValue().asDocument();
                        if (looksLikeHistogram(var16)) {
                           var0.sendMessage(
                              Message.translation("server.commands.chunk.storagestats.group.row")
                                 .param("key", var15.getKey())
                                 .param("value", formatHistogram(var16))
                           );
                        } else {
                           sendCounterGroup(var0, var1 + "." + var15.getKey(), var16);
                        }
                     }
                  }

                  class="kw">return;
               }

               Entry var4 = (Entry<String, BsonValue>)var3.next();
               var5 = var4.getKey();
               BsonValue var6 = var4.getValue();
               if (!var6.isInt64() && !var6.isInt32()) {
                  if (var6.isDouble()) {
                     var7 = String.format("%.3f", var6.asDouble().getValue());
                     break;
                  }

                  if (!var6.isArray()) {
                     class="kw">continue;
                  }

                  StringBuilder var17 = new StringBuilder();
                  BsonArray var9 = var6.asArray();

                  for (int var10 = 0; var10 < var9.size(); var10++) {
                     if (var10 > 0) {
                        var17.append(", ");
                     }

                     BsonValue var11 = var9.get(var10);
                     long var12 = var11.isInt64() ? var11.asInt64().getValue() : (var11.isInt32() ? var11.asInt32().getValue() : 0L);
                     var17.append('[').append(var10).append("]=").append(var12);
                  }

                  var7 = var17.toString();
                  break;
               }

               long var8 = var6.isInt64() ? var6.asInt64().getValue() : var6.asInt32().getValue();
               var7 = looksLikeBytes(var5) ? FormatUtil.bytesToString(var8) : Long.toString(var8);
               break;
            }

            var0.sendMessage(Message.translation("server.commands.chunk.storagestats.group.row").param("key", var5).param("value", var7));
         }
      }
   }

   class="kw">private class="kw">static boolean looksLikeBytes(@Nonnull String var0) {
      class="kw">return var0.endsWith("Bytes");
   }

   class="kw">private class="kw">static boolean looksLikeHistogram(@Nonnull BsonDocument var0) {
      class="kw">return var0.containsKey("Count") && var0.containsKey("P95");
   }

   @Nonnull
   class="kw">private class="kw">static String formatHistogram(@Nonnull BsonDocument var0) {
      long var1 = readLong(var0, "Count");
      class="kw">return var1 == 0L
         ? "no samples"
         : var1
            + " samples, p50="
            + readDoubleStr(var0, "Median")
            + ", p95="
            + readDoubleStr(var0, "P95")
            + ", p99="
            + readDoubleStr(var0, "P99")
            + ", max="
            + readDoubleStr(var0, "Max")
            + ", avg="
            + readDoubleStr(var0, "Average");
   }

   @Nonnull
   class="kw">private class="kw">static String readDoubleStr(@Nonnull BsonDocument var0, @Nonnull String var1) {
      BsonValue var2 = var0.get(var1);
      if (var2 == null) {
         class="kw">return "0";
      } else if (var2.isDouble()) {
         class="kw">return String.format("%.2f", var2.asDouble().getValue());
      } else if (var2.isInt64()) {
         class="kw">return Long.toString(var2.asInt64().getValue());
      } else {
         class="kw">return var2.isInt32() ? Integer.toString(var2.asInt32().getValue()) : "0";
      }
   }

   class="kw">private class="kw">static void sendStatsBlock(@Nonnull CommandContext var0, @Nonnull String var1, @Nonnull BsonArray var2) {
      if (!var2.isEmpty()) {
         var0.sendMessage(Message.translation("server.commands.chunk.storagestats.rates.header").param("op", var1));

         for (BsonValue var4 : var2) {
            if (var4.isDocument()) {
               BsonDocument var5 = var4.asDocument();
               long var6 = readLong(var5, "PeriodSec");
               long var8 = readLong(var5, "Count");
               long var10 = readLong(var5, "Bytes");
               long var12 = readLong(var5, "LatencySumNanos");
               long var14 = readLong(var5, "MinLatencyNanos");
               long var16 = readLong(var5, "MaxLatencyNanos");
               double var18 = var6 <= 0L ? 1.0 : var6;
               String var20 = String.format("%.2f/s", var8 / var18);
               String var21 = var8 == 0L ? "n/a" : FormatUtil.nanosToString(var12 / var8);
               String var22 = var8 + " ops, " + var20 + ", avg " + var21;
               if (var8 > 0L) {
                  var22 = var22 + " (min " + FormatUtil.nanosToString(var14) + ", max " + FormatUtil.nanosToString(var16) + ")";
               }

               if (var10 > 0L) {
                  String var23 = FormatUtil.bytesToString((long)(var10 / var18)) + "/s";
                  String var24 = var8 == 0L ? "n/a" : FormatUtil.bytesToString(var10 / var8);
                  var22 = var22 + ", " + FormatUtil.bytesToString(var10) + " (" + var23 + ", avg " + var24 + "/op)";
               }

               var0.sendMessage(
                  Message.translation("server.commands.chunk.storagestats.rates.row")
                     .param("period", FormatUtil.timeUnitToString(var6, TimeUnit.SECONDS, true))
                     .param("summary", var22)
               );
            }
         }
      }
   }

   class="kw">private class="kw">static long readLong(@Nonnull BsonDocument var0, @Nonnull String var1) {
      BsonValue var2 = var0.get(var1);
      if (var2 == null) {
         class="kw">return 0L;
      } else if (var2.isInt64()) {
         class="kw">return var2.asInt64().getValue();
      } else {
         class="kw">return var2.isInt32() ? var2.asInt32().getValue() : 0L;
      }
   }
}