mirror of
https://e.coding.net/circlecloud/Yum.git
synced 2024-12-23 05:08:47 +00:00
feat: 添加监控异常拦截处理
Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
parent
ce4e6650d7
commit
e954b10e82
@ -24,12 +24,14 @@ import cn.citycraft.PluginHelper.commands.HandlerCommands;
|
|||||||
import cn.citycraft.PluginHelper.commands.InvokeCommandEvent;
|
import cn.citycraft.PluginHelper.commands.InvokeCommandEvent;
|
||||||
import cn.citycraft.PluginHelper.commands.InvokeSubCommand;
|
import cn.citycraft.PluginHelper.commands.InvokeSubCommand;
|
||||||
import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
||||||
|
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||||
import cn.citycraft.PluginHelper.kit.StrKit;
|
import cn.citycraft.PluginHelper.kit.StrKit;
|
||||||
import pw.yumc.Yum.Yum;
|
import pw.yumc.Yum.Yum;
|
||||||
import pw.yumc.Yum.api.YumAPI;
|
import pw.yumc.Yum.api.YumAPI;
|
||||||
import pw.yumc.Yum.inject.CommandInjector;
|
import pw.yumc.Yum.inject.CommandInjector;
|
||||||
import pw.yumc.Yum.inject.ListenerInjector;
|
import pw.yumc.Yum.inject.ListenerInjector;
|
||||||
import pw.yumc.Yum.inject.TaskInjector;
|
import pw.yumc.Yum.inject.TaskInjector;
|
||||||
|
import pw.yumc.Yum.managers.ConfigManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -37,26 +39,35 @@ import pw.yumc.Yum.inject.TaskInjector;
|
|||||||
* @author 喵♂呜
|
* @author 喵♂呜
|
||||||
*/
|
*/
|
||||||
public class MonitorCommand implements HandlerCommands {
|
public class MonitorCommand implements HandlerCommands {
|
||||||
|
public static boolean debug = false;
|
||||||
|
public static Throwable lastError = null;
|
||||||
|
|
||||||
private final String prefix = "§6[§bYum §a能耗监控§6] ";
|
private final String prefix = "§6[§bYum §a能耗监控§6] ";
|
||||||
|
|
||||||
private final String total = "§6总耗时: §a%.2f毫秒 ";
|
private final String total = "§6总耗时: §a%.2f毫秒 ";
|
||||||
private final String count = "§6执行次数: §b%s次 ";
|
private final String count = "§6执行次数: §b%s次 ";
|
||||||
private final String avg = "§6平均耗时: §d%.5f毫秒!";
|
private final String avg = "§6平均耗时: §d%.5f毫秒!";
|
||||||
private final String avg_warn = "§6平均耗时: §c%.5f毫秒!";
|
private final String avg_warn = "§6平均耗时: §c%.5f毫秒!";
|
||||||
private final String p_n_f = prefix + "§c插件 §b%s §c不存在!";
|
|
||||||
|
|
||||||
private final String injected = "§a插件 §b%s §a成功注入能耗监控器!";
|
private final String injected = "§a插件 §b%s §a成功注入能耗监控器!";
|
||||||
private final String uninjected = "§a插件 §b%s §a成功撤销能耗监控器!";
|
private final String uninjected = "§a插件 §b%s §a成功撤销能耗监控器!";
|
||||||
private final String notEnable = "§c插件 §b%s §c未成功加载 无法执行注入!";
|
private final String notEnable = "§c插件 §b%s §c未成功加载 无法执行注入!";
|
||||||
|
|
||||||
|
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.0;
|
||||||
|
|
||||||
public MonitorCommand(final Yum yum) {
|
public MonitorCommand(final Yum yum) {
|
||||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "monitor");
|
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "monitor");
|
||||||
cmdhandler.registerCommands(this);
|
cmdhandler.registerCommands(this);
|
||||||
cmdhandler.registerCommands(PluginTabComplete.instence);
|
cmdhandler.registerCommands(PluginTabComplete.instence);
|
||||||
|
debug = ConfigManager.i().isMonitorDebug();
|
||||||
}
|
}
|
||||||
|
|
||||||
@HandlerCommand(name = "cmd", description = "查看插件命令能耗", minimumArguments = 1, possibleArguments = "[插件名称]")
|
@HandlerCommand(name = "cmd", aliases = "c", description = "查看插件命令能耗", minimumArguments = 1, possibleArguments = "[插件名称]")
|
||||||
public void cmd(final InvokeCommandEvent e) {
|
public void cmd(final InvokeCommandEvent e) {
|
||||||
final String pname = e.getArgs()[0];
|
final String pname = e.getArgs()[0];
|
||||||
final CommandSender sender = e.getSender();
|
final CommandSender sender = e.getSender();
|
||||||
@ -93,7 +104,7 @@ public class MonitorCommand implements HandlerCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@HandlerCommand(name = "event", description = "查看插件事件能耗", minimumArguments = 1, possibleArguments = "[插件名称]")
|
@HandlerCommand(name = "event", aliases = "e", description = "查看插件事件能耗", minimumArguments = 1, possibleArguments = "[插件名称]")
|
||||||
public void event(final InvokeCommandEvent e) throws InstantiationException, IllegalAccessException {
|
public void event(final InvokeCommandEvent e) throws InstantiationException, IllegalAccessException {
|
||||||
final String pname = e.getArgs()[0];
|
final String pname = e.getArgs()[0];
|
||||||
final CommandSender sender = e.getSender();
|
final CommandSender sender = e.getSender();
|
||||||
@ -157,6 +168,20 @@ public class MonitorCommand implements HandlerCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@HandlerCommand(name = "lasterror", aliases = "la", description = "查看最后一次报错")
|
||||||
|
public void lasterror(final InvokeCommandEvent e) {
|
||||||
|
final CommandSender sender = e.getSender();
|
||||||
|
if (lastError == null) {
|
||||||
|
sender.sendMessage(no_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Plugin plugin = PluginKit.getOperatePlugin(lastError.getStackTrace());
|
||||||
|
if (plugin != null) {
|
||||||
|
sender.sendMessage(String.format(last_error, plugin.getName()));
|
||||||
|
lastError.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@HandlerCommand(name = "task", description = "查看插件任务能耗", minimumArguments = 1, possibleArguments = "[插件名称]")
|
@HandlerCommand(name = "task", description = "查看插件任务能耗", minimumArguments = 1, possibleArguments = "[插件名称]")
|
||||||
public void task(final InvokeCommandEvent e) {
|
public void task(final InvokeCommandEvent e) {
|
||||||
final String pname = e.getArgs()[0];
|
final String pname = e.getArgs()[0];
|
||||||
|
@ -15,18 +15,24 @@ import org.bukkit.plugin.Plugin;
|
|||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
|
||||||
import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
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;
|
||||||
|
|
||||||
public class CommandInjector implements TabExecutor {
|
public class CommandInjector implements TabExecutor {
|
||||||
|
private final String prefix = "§6[§bYum §a命令监控§6] ";
|
||||||
private final CommandExecutor originalExecutor;
|
private final CommandExecutor originalExecutor;
|
||||||
private final TabCompleter originalCompleter;
|
private final TabCompleter originalCompleter;
|
||||||
|
|
||||||
|
private final Plugin plugin;
|
||||||
|
|
||||||
public long totalTime;
|
public long totalTime;
|
||||||
public int count;
|
public int count;
|
||||||
|
|
||||||
public CommandInjector(final CommandExecutor originalCommandExecutor, final TabCompleter originalTabCompleter) {
|
public CommandInjector(final CommandExecutor originalCommandExecutor, final TabCompleter originalTabCompleter, final Plugin plugin) {
|
||||||
this.originalExecutor = originalCommandExecutor;
|
this.originalExecutor = originalCommandExecutor;
|
||||||
this.originalCompleter = originalTabCompleter;
|
this.originalCompleter = originalTabCompleter;
|
||||||
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void inject(final Plugin toInjectPlugin) {
|
public static void inject(final Plugin toInjectPlugin) {
|
||||||
@ -42,7 +48,7 @@ public class CommandInjector implements TabExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final TabCompleter completer = Reflect.on(command).get("completer");
|
final TabCompleter completer = Reflect.on(command).get("completer");
|
||||||
final CommandInjector commandInjector = new CommandInjector(executor, completer);
|
final CommandInjector commandInjector = new CommandInjector(executor, completer, toInjectPlugin);
|
||||||
Reflect.on(command).set("executor", commandInjector);
|
Reflect.on(command).set("executor", commandInjector);
|
||||||
Reflect.on(command).set("completer", commandInjector);
|
Reflect.on(command).set("completer", commandInjector);
|
||||||
}
|
}
|
||||||
@ -83,13 +89,38 @@ public class CommandInjector implements TabExecutor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) {
|
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) {
|
||||||
|
try {
|
||||||
final long start = System.nanoTime();
|
final long start = System.nanoTime();
|
||||||
// TODO 当操作大于10ms的时候添加一个Lag提示
|
// TODO 当操作大于10ms的时候添加一个Lag提示
|
||||||
final boolean result = originalExecutor.onCommand(sender, command, label, args);
|
final boolean result = originalExecutor.onCommand(sender, command, label, args);
|
||||||
final long end = System.nanoTime();
|
final long end = System.nanoTime();
|
||||||
totalTime += end - start;
|
final long lag = end - start;
|
||||||
|
if (Bukkit.isPrimaryThread() && lag / 1000000 > 10) {
|
||||||
|
PluginKit.sc("§6[§bYum §a能耗监控§6] §c注意! §6插件 §b" + plugin.getName() + " §6执行 §d" + label + " " + StrKit.join(args, " ") + " §6命令 §c耗时 §4" + lag / 1000000 + "ms!");
|
||||||
|
}
|
||||||
|
totalTime += lag;
|
||||||
count++;
|
count++;
|
||||||
return result;
|
return result;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
while (e.getCause() != null) {
|
||||||
|
e = e.getCause();
|
||||||
|
}
|
||||||
|
MonitorCommand.lastError = e;
|
||||||
|
PluginKit.sc(prefix + "§6插件 §b" + plugin.getName() + " §6执行 §d" + label + " §6命令时发生异常!");
|
||||||
|
PluginKit.sc("§6异常名称: §c" + e.getClass().getName());
|
||||||
|
PluginKit.sc("§6异常说明: §3" + e.getMessage());
|
||||||
|
PluginKit.sc("§6简易错误信息如下:");
|
||||||
|
final int l = e.getStackTrace().length > 5 ? 5 : e.getStackTrace().length;
|
||||||
|
for (int i = 0; i < l; i++) {
|
||||||
|
final StackTraceElement ste = e.getStackTrace()[i];
|
||||||
|
PluginKit.sc(" §e位于 §c" + ste.getClassName() + "." + ste.getMethodName() + "(§4" + ste.getFileName() + ":" + ste.getLineNumber() + "§c)");
|
||||||
|
}
|
||||||
|
if (MonitorCommand.debug) {
|
||||||
|
PluginKit.sc("§c开发人员调试信息如下:");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,6 +15,7 @@ import org.bukkit.plugin.TimedRegisteredListener;
|
|||||||
|
|
||||||
import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
||||||
import cn.citycraft.PluginHelper.kit.PluginKit;
|
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||||
|
import pw.yumc.Yum.commands.MonitorCommand;
|
||||||
import pw.yumc.Yum.managers.ConfigManager;
|
import pw.yumc.Yum.managers.ConfigManager;
|
||||||
|
|
||||||
public class ListenerInjector implements EventExecutor {
|
public class ListenerInjector implements EventExecutor {
|
||||||
@ -72,7 +73,7 @@ public class ListenerInjector implements EventExecutor {
|
|||||||
final String en = event.getEventName();
|
final String en = event.getEventName();
|
||||||
final long lag = end - start;
|
final long lag = end - start;
|
||||||
if (lag / 1000000 > 10 && !ConfigManager.i().getMonitorIgnoreList().contains(plugin.getName())) {
|
if (lag / 1000000 > 10 && !ConfigManager.i().getMonitorIgnoreList().contains(plugin.getName())) {
|
||||||
PluginKit.sc("§6[§bYum §a能耗监控§6] §c注意! §6插件 §b" + plugin.getName() + " §6处理 §d" + event.getEventName() + " §6事件时§c耗时 §4" + lag / 1000000 + "ms!");
|
PluginKit.sc("§6[§bYum §a能耗监控§6] §c注意! §6插件 §b" + plugin.getName() + " §6处理 §d" + event.getEventName() + " §6事件 §c耗时 §4" + lag / 1000000 + "ms!");
|
||||||
}
|
}
|
||||||
if (eventTotalTime.containsKey(en)) {
|
if (eventTotalTime.containsKey(en)) {
|
||||||
eventTotalTime.put(en, eventTotalTime.get(en) + lag);
|
eventTotalTime.put(en, eventTotalTime.get(en) + lag);
|
||||||
@ -88,13 +89,20 @@ public class ListenerInjector implements EventExecutor {
|
|||||||
while (e.getCause() != null) {
|
while (e.getCause() != null) {
|
||||||
e = e.getCause();
|
e = e.getCause();
|
||||||
}
|
}
|
||||||
PluginKit.sc(prefix + "§6插件 §b" + plugin.getName() + " §6处理 §d" + event.getEventName() + " §6事件时发生异常 §c" + e.getClass().getName() + ": " + e.getMessage());
|
MonitorCommand.lastError = e;
|
||||||
PluginKit.sc("§c错误信息如下:");
|
PluginKit.sc(prefix + "§6插件 §b" + plugin.getName() + " §6处理 §d" + event.getEventName() + " §6事件时发生异常!");
|
||||||
|
PluginKit.sc("§6异常名称: §c" + e.getClass().getName());
|
||||||
|
PluginKit.sc("§6异常说明: §3" + e.getMessage());
|
||||||
|
PluginKit.sc("§6简易错误信息如下:");
|
||||||
final int l = e.getStackTrace().length > 5 ? 5 : e.getStackTrace().length;
|
final int l = e.getStackTrace().length > 5 ? 5 : e.getStackTrace().length;
|
||||||
for (int i = 0; i < l; i++) {
|
for (int i = 0; i < l; i++) {
|
||||||
final StackTraceElement ste = e.getStackTrace()[i];
|
final StackTraceElement ste = e.getStackTrace()[i];
|
||||||
PluginKit.sc(" §e位于 §c" + ste.getClassName() + "." + ste.getMethodName() + "(§4" + ste.getFileName() + ":" + ste.getLineNumber() + "§c)");
|
PluginKit.sc(" §e位于 §c" + ste.getClassName() + "." + ste.getMethodName() + "(§4" + ste.getFileName() + ":" + ste.getLineNumber() + "§c)");
|
||||||
}
|
}
|
||||||
|
if (MonitorCommand.debug) {
|
||||||
|
PluginKit.sc("§c开发人员调试信息如下:");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,16 +8,26 @@ import org.bukkit.scheduler.BukkitScheduler;
|
|||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
import cn.citycraft.PluginHelper.ext.kit.Reflect;
|
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;
|
||||||
|
|
||||||
public class TaskInjector implements Runnable {
|
public class TaskInjector implements Runnable {
|
||||||
|
private final String prefix = "§6[§bYum §a任务监控§6] ";
|
||||||
|
|
||||||
private final Runnable originalTask;
|
private final Runnable originalTask;
|
||||||
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
private final String taskName;
|
||||||
|
|
||||||
public long totalTime;
|
public long totalTime;
|
||||||
public int count;
|
public int count;
|
||||||
|
|
||||||
public TaskInjector(final Runnable originalTask) {
|
public TaskInjector(final Runnable originalTask, final Plugin plugin) {
|
||||||
this.originalTask = originalTask;
|
this.originalTask = originalTask;
|
||||||
|
this.plugin = plugin;
|
||||||
|
final Class<? extends Runnable> taskClass = getOriginalTask().getClass();
|
||||||
|
taskName = StrKit.isBlank(taskClass.getSimpleName()) ? taskClass.getName() : taskClass.getSimpleName();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前注入只能对TimerTask有效
|
// 当前注入只能对TimerTask有效
|
||||||
@ -32,7 +42,7 @@ public class TaskInjector implements Runnable {
|
|||||||
if (originalTask instanceof TaskInjector) {
|
if (originalTask instanceof TaskInjector) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final TaskInjector taskInjector = new TaskInjector(originalTask);
|
final TaskInjector taskInjector = new TaskInjector(originalTask, plugin);
|
||||||
Reflect.on(pendingTask).set("task", taskInjector);
|
Reflect.on(pendingTask).set("task", taskInjector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,11 +68,37 @@ public class TaskInjector implements Runnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
|
try {
|
||||||
final long start = System.nanoTime();
|
final long start = System.nanoTime();
|
||||||
// TODO 当操作大于10ms的时候添加一个Lag提示
|
// TODO 当操作大于10ms的时候添加一个Lag提示
|
||||||
originalTask.run();
|
originalTask.run();
|
||||||
final long end = System.nanoTime();
|
final long end = System.nanoTime();
|
||||||
totalTime += end - start;
|
final long lag = end - start;
|
||||||
|
if (Bukkit.isPrimaryThread() && lag / 1000000 > 10) {
|
||||||
|
PluginKit.sc("§6[§bYum §a能耗监控§6] §c注意! §6插件 §b" + plugin.getName() + " §6执行 §d" + taskName + " §6任务 §c耗时 §4" + lag / 1000000 + "ms!");
|
||||||
|
}
|
||||||
|
totalTime += lag;
|
||||||
count++;
|
count++;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
while (e.getCause() != null) {
|
||||||
|
e = e.getCause();
|
||||||
|
}
|
||||||
|
MonitorCommand.lastError = e;
|
||||||
|
PluginKit.sc(prefix + "§6插件 §b" + plugin.getName() + " §6执行 §d" + taskName + " §6任务时发生异常!");
|
||||||
|
PluginKit.sc("§6异常名称: §c" + e.getClass().getName());
|
||||||
|
PluginKit.sc("§6异常说明: §3" + e.getMessage());
|
||||||
|
PluginKit.sc("§6简易错误信息如下:");
|
||||||
|
final int l = e.getStackTrace().length > 5 ? 5 : e.getStackTrace().length;
|
||||||
|
for (int i = 0; i < l; i++) {
|
||||||
|
final StackTraceElement ste = e.getStackTrace()[i];
|
||||||
|
PluginKit.sc(" §e位于 §c" + ste.getClassName() + "." + ste.getMethodName() + "(§4" + ste.getFileName() + ":" + ste.getLineNumber() + "§c)");
|
||||||
|
}
|
||||||
|
if (MonitorCommand.debug) {
|
||||||
|
PluginKit.sc("§c开发人员调试信息如下:");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
############################
|
############################
|
||||||
|
|
||||||
#配置版本号 请勿修改!!!
|
#配置版本号 请勿修改!!!
|
||||||
Version: 2.2
|
Version: 2.3
|
||||||
|
|
||||||
#是否只允许控制台执行插件仓库命令
|
#是否只允许控制台执行插件仓库命令
|
||||||
onlyCommandConsole: false
|
onlyCommandConsole: false
|
||||||
#是否只允许控制台执行插件网络管理命令
|
#是否只允许控制台执行插件网络管理命令
|
||||||
onlyNetCommandConsole: false
|
onlyNetCommandConsole: false
|
||||||
#是否只允许控制台执行插件文件管理命令
|
#是否只允许控制台执行插件文件管理命令
|
||||||
onlyFileCommandConsole: true
|
onlyFileCommandConsole: false
|
||||||
#禁止rm -rf的文件夹列表
|
#禁止rm -rf的文件夹列表
|
||||||
blacklist:
|
blacklist:
|
||||||
- 'plugins'
|
- 'plugins'
|
||||||
@ -22,3 +22,4 @@ ignorelist:
|
|||||||
- 'iConomy'
|
- 'iConomy'
|
||||||
- 'GroupManager'
|
- 'GroupManager'
|
||||||
- 'PermissionsEx'
|
- 'PermissionsEx'
|
||||||
|
- 'Essentials'
|
@ -3,10 +3,12 @@
|
|||||||
############################
|
############################
|
||||||
|
|
||||||
#配置版本号 请勿修改!!!
|
#配置版本号 请勿修改!!!
|
||||||
Version: 1.1
|
Version: 1.2
|
||||||
|
|
||||||
#是否开启
|
#是否开启
|
||||||
Enable: true
|
Enable: true
|
||||||
|
#是否显示开发人员信息
|
||||||
|
Debug: false
|
||||||
#忽略检测列表
|
#忽略检测列表
|
||||||
Ignore:
|
Ignore:
|
||||||
- Essentials
|
- PluginHelper
|
Loading…
Reference in New Issue
Block a user