mirror of
https://e.coding.net/circlecloud/Yum.git
synced 2024-12-22 20:58:47 +00:00
feat: 添加全局能耗监控
Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
parent
58fe1d3f0c
commit
935a2eb4f9
3
pom.xml
3
pom.xml
@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>pw.yumc</groupId>
|
||||
<artifactId>Yum</artifactId>
|
||||
<version>2.6.4</version>
|
||||
<version>2.6.5</version>
|
||||
<name>Yum</name>
|
||||
<description>Minecraft 服务器插件管理系统</description>
|
||||
<build>
|
||||
@ -60,6 +60,7 @@
|
||||
<properties>
|
||||
<update.description>&a全新 2.X 版本 更多守护与优化</update.description>
|
||||
<update.changes>
|
||||
&b2.6.5 &6- &c修复list命令 &a添加全局能耗统计...;
|
||||
&b2.6.4 &6- &e添加从&bBukkitDev&e下载和更新...;
|
||||
&b2.6.3 &6- &a注入操作延时执行 防止部分任务未注册 添加手动注入...;
|
||||
&b2.6.2 &6- &d能耗监控添加忽略列表 &3详见monitor.yml...;
|
||||
|
@ -33,6 +33,7 @@ import pw.yumc.Yum.runnables.MainThreadCheckTask;
|
||||
* @since 2015年8月21日下午5:14:39
|
||||
*/
|
||||
public class Yum extends JavaPlugin {
|
||||
public static boolean disable = false;;
|
||||
public static Thread mainThread = null;
|
||||
public static Timer task = new Timer();
|
||||
public static TimerTask tt;
|
||||
@ -45,6 +46,7 @@ public class Yum extends JavaPlugin {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
NetworkManager.unregister();
|
||||
disable = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -59,6 +61,10 @@ public class Yum extends JavaPlugin {
|
||||
new VersionChecker(this);
|
||||
YumAPI.updateRepo(Bukkit.getConsoleSender());
|
||||
YumAPI.updateCheck(Bukkit.getConsoleSender());
|
||||
if (disable) {
|
||||
YumAPI.updateInject();
|
||||
disable = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,6 +32,8 @@ import pw.yumc.Yum.inject.CommandInjector;
|
||||
import pw.yumc.Yum.inject.ListenerInjector;
|
||||
import pw.yumc.Yum.inject.TaskInjector;
|
||||
import pw.yumc.Yum.managers.ConfigManager;
|
||||
import pw.yumc.Yum.managers.MonitorManager;
|
||||
import pw.yumc.Yum.managers.MonitorManager.MonitorInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -49,16 +51,20 @@ public class MonitorCommand implements HandlerCommands {
|
||||
private final String avg = "§6平均耗时: §d%.5f毫秒!";
|
||||
private final String avg_warn = "§6平均耗时: §c%.5f毫秒!";
|
||||
|
||||
private final String injected = "§a插件 §b%s §a成功注入能耗监控器!";
|
||||
private final String uninjected = "§a插件 §b%s §a成功撤销能耗监控器!";
|
||||
private final String notEnable = "§c插件 §b%s §c未成功加载 无法执行注入!";
|
||||
private final String reinject = prefix + "§a能耗监控器重载完毕!";
|
||||
private final String injected = prefix + "§a插件 §b%s §a成功注入能耗监控器!";
|
||||
private final String uninjected = prefix + "§a插件 §b%s §a成功撤销能耗监控器!";
|
||||
private final String notEnable = prefix + "§c插件 §b%s §c未成功加载 无法执行注入!";
|
||||
|
||||
private final String lagprefix = "§6插件名称 §c主线程耗时 §a命令耗时 §b事件耗时 §d任务耗时";
|
||||
private final String laglist = "§b%-15s §c%-11.2f §a%-9.2f §b%-9.2f §d%-9.2f";
|
||||
|
||||
private final String no_error = prefix + "§a自服务器启动以来尚未发现报错!";
|
||||
private final String last_error = prefix + "§c最后一次错误异常由 §b%s §c造成 详细如下:";
|
||||
|
||||
private final String p_n_f = prefix + "§c插件 §b%s §c不存在!";
|
||||
|
||||
private final double um = 1000000.0;
|
||||
private final double um = 1000000.00;
|
||||
|
||||
public MonitorCommand(final Yum yum) {
|
||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "monitor");
|
||||
@ -140,7 +146,7 @@ public class MonitorCommand implements HandlerCommands {
|
||||
}
|
||||
for (final String event : eventTotalTime.keySet()) {
|
||||
final StringBuffer str = new StringBuffer();
|
||||
str.append("§6- §e" + event + " ");
|
||||
str.append(String.format("§6- §e%-25s ", event));
|
||||
str.append(String.format(total, eventTotalTime.get(event) / um));
|
||||
str.append(String.format(count, eventCount.get(event)));
|
||||
if (eventCount.get(event) != 0) {
|
||||
@ -162,9 +168,24 @@ public class MonitorCommand implements HandlerCommands {
|
||||
}
|
||||
if (plugin.isEnabled()) {
|
||||
YumAPI.inject(plugin);
|
||||
sender.sendMessage(String.format(prefix + injected, pname));
|
||||
sender.sendMessage(String.format(injected, pname));
|
||||
} else {
|
||||
sender.sendMessage(String.format(prefix + notEnable, pname));
|
||||
sender.sendMessage(String.format(notEnable, pname));
|
||||
}
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "lag", aliases = "l", description = "查看插件总耗时")
|
||||
public void lag(final InvokeCommandEvent e) {
|
||||
final CommandSender sender = e.getSender();
|
||||
final Map<String, Long> mm = MonitorManager.getMonitor();
|
||||
int i = 0;
|
||||
sender.sendMessage(lagprefix);
|
||||
for (final Entry<String, Long> entry : mm.entrySet()) {
|
||||
if (i++ > 5) {
|
||||
break;
|
||||
}
|
||||
final MonitorInfo mi = MonitorManager.getMonitorInfo(entry.getKey());
|
||||
sender.sendMessage(String.format(laglist, entry.getKey(), mi.monitor, mi.cmd, mi.event, mi.task));
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,6 +203,13 @@ public class MonitorCommand implements HandlerCommands {
|
||||
}
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "reinject", aliases = "i", description = "重载能耗监控器")
|
||||
public void reinject(final InvokeCommandEvent e) {
|
||||
final CommandSender sender = e.getSender();
|
||||
YumAPI.updateInject();
|
||||
sender.sendMessage(reinject);
|
||||
}
|
||||
|
||||
@HandlerCommand(name = "task", description = "查看插件任务能耗", minimumArguments = 1, possibleArguments = "[插件名称]")
|
||||
public void task(final InvokeCommandEvent e) {
|
||||
final String pname = e.getArgs()[0];
|
||||
@ -199,8 +227,7 @@ public class MonitorCommand implements HandlerCommands {
|
||||
if (task instanceof TaskInjector) {
|
||||
final TaskInjector executor = (TaskInjector) task;
|
||||
final StringBuffer str = new StringBuffer();
|
||||
final Class<? extends Runnable> taskName = executor.getOriginalTask().getClass();
|
||||
str.append("§6- §e" + (StrKit.isBlank(taskName.getSimpleName()) ? taskName.getName() : taskName.getSimpleName()) + " ");
|
||||
str.append("§6- §e" + getClassName(executor.getOriginalTask().getClass()) + " ");
|
||||
str.append(String.format(total, executor.totalTime / um));
|
||||
str.append(String.format(count, executor.count));
|
||||
if (executor.count != 0) {
|
||||
@ -223,7 +250,11 @@ public class MonitorCommand implements HandlerCommands {
|
||||
}
|
||||
if (plugin.isEnabled()) {
|
||||
YumAPI.uninject(plugin);
|
||||
sender.sendMessage(String.format(prefix + uninjected, pname));
|
||||
sender.sendMessage(String.format(uninjected, pname));
|
||||
}
|
||||
}
|
||||
|
||||
private String getClassName(final Class<?> clazz) {
|
||||
return StrKit.isBlank(clazz.getSimpleName()) ? clazz.getName().substring(clazz.getName().lastIndexOf(".") + 1) : clazz.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +253,9 @@ public class YumCommand implements HandlerCommands, Listener {
|
||||
fm.then(unload).command("yum unload " + pname);
|
||||
fm.then(" ");
|
||||
fm.then(reload).command("yum re " + pname);
|
||||
fm.then(" ");
|
||||
fm.then(delete).command("yum del " + pname);
|
||||
fm.send(sender);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
||||
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||
import cn.citycraft.PluginHelper.kit.StrKit;
|
||||
import pw.yumc.Yum.commands.MonitorCommand;
|
||||
import pw.yumc.Yum.managers.MonitorManager;
|
||||
|
||||
public class CommandInjector implements TabExecutor {
|
||||
private final String prefix = "§6[§bYum §a命令监控§6] ";
|
||||
@ -43,11 +44,13 @@ public class CommandInjector implements TabExecutor {
|
||||
final PluginCommand pluginCommand = (PluginCommand) command;
|
||||
final Plugin plugin = pluginCommand.getPlugin();
|
||||
if (plugin.equals(toInjectPlugin)) {
|
||||
final CommandExecutor executor = Reflect.on(command).get("executor");
|
||||
CommandExecutor executor = Reflect.on(command).get("executor");
|
||||
TabCompleter completer = Reflect.on(command).get("completer");;
|
||||
if (executor instanceof CommandInjector) {
|
||||
return;
|
||||
final CommandInjector cInjector = (CommandInjector) executor;
|
||||
executor = cInjector.getOriginalExecutor();
|
||||
completer = cInjector.getOriginalCompleter();
|
||||
}
|
||||
final TabCompleter completer = Reflect.on(command).get("completer");
|
||||
final CommandInjector commandInjector = new CommandInjector(executor, completer, toInjectPlugin);
|
||||
Reflect.on(command).set("executor", commandInjector);
|
||||
Reflect.on(command).set("completer", commandInjector);
|
||||
@ -100,6 +103,7 @@ public class CommandInjector implements TabExecutor {
|
||||
}
|
||||
totalTime += lag;
|
||||
count++;
|
||||
MonitorManager.addCmd(plugin.getName(), lag);
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
while (e.getCause() != null) {
|
||||
|
@ -17,6 +17,7 @@ import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
||||
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||
import pw.yumc.Yum.commands.MonitorCommand;
|
||||
import pw.yumc.Yum.managers.ConfigManager;
|
||||
import pw.yumc.Yum.managers.MonitorManager;
|
||||
|
||||
public class ListenerInjector implements EventExecutor {
|
||||
private final String prefix = "§6[§bYum §a事件监控§6] ";
|
||||
@ -40,9 +41,9 @@ public class ListenerInjector implements EventExecutor {
|
||||
if (listener instanceof TimedRegisteredListener) {
|
||||
return;
|
||||
}
|
||||
final EventExecutor originalExecutor = Reflect.on(listener).get("executor");
|
||||
EventExecutor originalExecutor = Reflect.on(listener).get("executor");
|
||||
if (originalExecutor instanceof ListenerInjector) {
|
||||
return;
|
||||
originalExecutor = ((ListenerInjector) originalExecutor).getOriginalExecutor();
|
||||
}
|
||||
final ListenerInjector listenerInjector = new ListenerInjector(originalExecutor, plugin);
|
||||
Reflect.on(listener).set("executor", listenerInjector);
|
||||
@ -82,6 +83,7 @@ public class ListenerInjector implements EventExecutor {
|
||||
eventTotalTime.put(en, end - start);
|
||||
eventCount.put(en, 1);
|
||||
}
|
||||
MonitorManager.addEvent(plugin.getName(), lag);
|
||||
} else {
|
||||
originalExecutor.execute(listener, event);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
||||
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||
import cn.citycraft.PluginHelper.kit.StrKit;
|
||||
import pw.yumc.Yum.commands.MonitorCommand;
|
||||
import pw.yumc.Yum.managers.MonitorManager;
|
||||
|
||||
public class TaskInjector implements Runnable {
|
||||
private final String prefix = "§6[§bYum §a任务监控§6] ";
|
||||
@ -38,9 +39,9 @@ public class TaskInjector implements Runnable {
|
||||
for (final BukkitTask pendingTask : pendingTasks) {
|
||||
// 忽略异步任务
|
||||
if (pendingTask.isSync() && pendingTask.getOwner().equals(plugin)) {
|
||||
final Runnable originalTask = Reflect.on(pendingTask).get("task");
|
||||
Runnable originalTask = Reflect.on(pendingTask).get("task");
|
||||
if (originalTask instanceof TaskInjector) {
|
||||
return;
|
||||
originalTask = ((TaskInjector) originalTask).getOriginalTask();
|
||||
}
|
||||
final TaskInjector taskInjector = new TaskInjector(originalTask, plugin);
|
||||
Reflect.on(pendingTask).set("task", taskInjector);
|
||||
@ -80,6 +81,7 @@ public class TaskInjector implements Runnable {
|
||||
}
|
||||
totalTime += lag;
|
||||
count++;
|
||||
MonitorManager.addTask(plugin.getName(), lag);
|
||||
} catch (Throwable e) {
|
||||
while (e.getCause() != null) {
|
||||
e = e.getCause();
|
||||
|
@ -9,6 +9,7 @@ import org.bukkit.event.server.PluginEnableEvent;
|
||||
import cn.citycraft.PluginHelper.kit.PKit;
|
||||
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||
import pw.yumc.Yum.api.YumAPI;
|
||||
import pw.yumc.Yum.managers.MonitorManager;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -29,6 +30,7 @@ public class PluginListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPluginEnable(final PluginEnableEvent e) {
|
||||
MonitorManager.reset(e.getPlugin().getName());
|
||||
PluginKit.runTaskLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
98
src/main/java/pw/yumc/Yum/managers/MonitorManager.java
Normal file
98
src/main/java/pw/yumc/Yum/managers/MonitorManager.java
Normal file
@ -0,0 +1,98 @@
|
||||
package pw.yumc.Yum.managers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 2016年7月19日 下午3:55:54
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class MonitorManager {
|
||||
private static Map<String, Long> monitor = new HashMap<>();
|
||||
private static Map<String, Long> task = new HashMap<>();
|
||||
private static Map<String, Long> event = new HashMap<>();
|
||||
private static Map<String, Long> cmd = new HashMap<>();
|
||||
|
||||
private final static double um = 1000000.00;
|
||||
|
||||
public static void addCmd(final String pname, final long time) {
|
||||
monitor.put(pname, monitor.get(pname) + time);
|
||||
cmd.put(pname, cmd.get(pname) + time);
|
||||
}
|
||||
|
||||
public static void addEvent(final String pname, final long time) {
|
||||
monitor.put(pname, monitor.get(pname) + time);
|
||||
event.put(pname, event.get(pname) + time);
|
||||
}
|
||||
|
||||
public static void addTask(final String pname, final long time) {
|
||||
monitor.put(pname, monitor.get(pname) + time);
|
||||
task.put(pname, task.get(pname) + time);
|
||||
}
|
||||
|
||||
public static Map<String, Long> getMonitor() {
|
||||
return sortMapByValue(monitor);
|
||||
}
|
||||
|
||||
public static MonitorInfo getMonitorInfo(final String pname) {
|
||||
return new MonitorInfo(monitor.get(pname) / um, cmd.get(pname) / um, event.get(pname) / um, task.get(pname) / um);
|
||||
}
|
||||
|
||||
public static void reset(final String pname) {
|
||||
monitor.put(pname, 0L);
|
||||
task.put(pname, 0L);
|
||||
event.put(pname, 0L);
|
||||
cmd.put(pname, 0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 Map按value进行排序
|
||||
*
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, Long> sortMapByValue(final Map<String, Long> oriMap) {
|
||||
if (oriMap == null || oriMap.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final Map<String, Long> sortedMap = new LinkedHashMap<String, Long>();
|
||||
final List<Map.Entry<String, Long>> entryList = new ArrayList<Map.Entry<String, Long>>(oriMap.entrySet());
|
||||
Collections.sort(entryList, new MonitorComparator());
|
||||
final Iterator<Map.Entry<String, Long>> iter = entryList.iterator();
|
||||
Entry<String, Long> tmpEntry = null;
|
||||
while (iter.hasNext()) {
|
||||
tmpEntry = iter.next();
|
||||
sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
|
||||
}
|
||||
return sortedMap;
|
||||
}
|
||||
|
||||
public static class MonitorInfo {
|
||||
public double monitor;
|
||||
public double cmd;
|
||||
public double event;
|
||||
public double task;
|
||||
|
||||
public MonitorInfo(final double monitor, final double cmd, final double event, final double task) {
|
||||
this.monitor = monitor;
|
||||
this.cmd = cmd;
|
||||
this.event = event;
|
||||
this.task = task;
|
||||
}
|
||||
}
|
||||
|
||||
static class MonitorComparator implements Comparator<Map.Entry<String, Long>> {
|
||||
@Override
|
||||
public int compare(final Entry<String, Long> o1, final Entry<String, Long> o2) {
|
||||
return o2.getValue().compareTo(o1.getValue());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user