添加 /runtime 命令输出运行时信息,添加 @xx 的无法解析命令的劫持与报错

- 将 /xxx@me 格式的命令不再传递到事件链下层而是在命令层处理为“命令未找到”
- 添加 runtime 命令,将会输出以下信息
  - 系统名与系统版本和CPU核心数量
  - jvm 名称与版本号
  - JVM内存(not 物理内存)
  - 程序版本信息
  - 程序已运行时间
This commit is contained in:
A.C.Sukazyo Eyre 2021-12-11 23:31:24 +08:00
parent ecef73fad4
commit 6c8f311faf
Signed by: Eyre_S
GPG Key ID: EFB47D98FE082FAD
7 changed files with 105 additions and 21 deletions

View File

@ -1,6 +1,6 @@
## Core ## Core
VERSION = 0.4.1.1 VERSION = 0.4.1.2
# dependencies # dependencies

View File

@ -4,6 +4,6 @@ package cc.sukazyo.cono.morny;
* the final field that will be updated by gradle automatically. * the final field that will be updated by gradle automatically.
*/ */
public class GradleProjectConfigures { public class GradleProjectConfigures {
public static final String VERSION = "0.4.1.1"; public static final String VERSION = "0.4.1.2";
public static final long COMPILE_TIMESTAMP = 1639152431845L; public static final long COMPILE_TIMESTAMP = 1639211288142L;
} }

View File

@ -36,6 +36,11 @@ public class MornyCoeur {
* 会根据这里定义的时间戳取消掉比此时间更早的事件链 * 会根据这里定义的时间戳取消掉比此时间更早的事件链
*/ */
public static long latestEventTimestamp; public static long latestEventTimestamp;
/**
* morny 主程序启动时间<br>
* 用于统计数据
*/
public static final long coeurStartTimestamp = System.currentTimeMillis();
/** /**
* bot 启动入口执行 bot 初始化 * bot 启动入口执行 bot 初始化

View File

@ -1,11 +1,8 @@
package cc.sukazyo.cono.morny; package cc.sukazyo.cono.morny;
import cc.sukazyo.cono.morny.util.CommonFormatUtils;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import static cc.sukazyo.cono.morny.Log.logger; import static cc.sukazyo.cono.morny.Log.logger;
@ -113,9 +110,7 @@ public class ServerMain {
MornySystem.VERSION, MornySystem.VERSION,
MornySystem.getJarMd5(), MornySystem.getJarMd5(),
GradleProjectConfigures.COMPILE_TIMESTAMP, GradleProjectConfigures.COMPILE_TIMESTAMP,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.ofInstant( CommonFormatUtils.formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0)
Instant.ofEpochMilli(GradleProjectConfigures.COMPILE_TIMESTAMP),
ZoneId.ofOffset("UTC", ZoneOffset.UTC)))
)); ));
return; return;

View File

@ -37,14 +37,17 @@ public class InputCommand {
return new InputCommand(cx.length == 1 ? null : cx[1], cx[0], args); return new InputCommand(cx.length == 1 ? null : cx[1], cx[0], args);
} }
@Nullable
public String getTarget () { public String getTarget () {
return target; return target;
} }
@Nonnull
public String getCommand () { public String getCommand () {
return command; return command;
} }
@Nonnull
public String[] getArgs () { public String[] getArgs () {
return args; return args;
} }
@ -54,6 +57,7 @@ public class InputCommand {
} }
@Override @Override
@Nonnull
public String toString() { public String toString() {
return String.format("{{%s}@{%s}#{%s}}", command, target, Arrays.toString(args)); return String.format("{{%s}@{%s}#{%s}}", command, target, Arrays.toString(args));
} }

View File

@ -7,6 +7,7 @@ import cc.sukazyo.cono.morny.MornyTrusted;
import cc.sukazyo.cono.morny.bot.api.EventListener; import cc.sukazyo.cono.morny.bot.api.EventListener;
import cc.sukazyo.cono.morny.bot.api.InputCommand; import cc.sukazyo.cono.morny.bot.api.InputCommand;
import cc.sukazyo.cono.morny.bot.event.on_commands.GetUsernameAndId; import cc.sukazyo.cono.morny.bot.event.on_commands.GetUsernameAndId;
import cc.sukazyo.cono.morny.util.CommonFormatUtils;
import com.pengrad.telegrambot.model.Update; import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.model.request.ParseMode; import com.pengrad.telegrambot.model.request.ParseMode;
import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.request.SendMessage;
@ -14,12 +15,6 @@ import com.pengrad.telegrambot.request.SendSticker;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import static cc.sukazyo.cono.morny.Log.logger; import static cc.sukazyo.cono.morny.Log.logger;
public class OnCommandExecute extends EventListener { public class OnCommandExecute extends EventListener {
@ -28,6 +23,7 @@ public class OnCommandExecute extends EventListener {
private static final String HELLO_STICKER_ID = "CAACAgEAAxkBAAMnYYYWKNXO4ibo9dlsmDctHhhV6fIAAqooAAJ4_MYFJJhrHS74xUAiBA"; private static final String HELLO_STICKER_ID = "CAACAgEAAxkBAAMnYYYWKNXO4ibo9dlsmDctHhhV6fIAAqooAAJ4_MYFJJhrHS74xUAiBA";
private static final String EXIT_STICKER_ID = "CAACAgEAAxkBAAMoYYYWt8UjvP0N405SAyvg2SQZmokAAkMiAAJ4_MYFw6yZLu06b-MiBA"; private static final String EXIT_STICKER_ID = "CAACAgEAAxkBAAMoYYYWt8UjvP0N405SAyvg2SQZmokAAkMiAAJ4_MYFw6yZLu06b-MiBA";
private static final String EXIT_403_STICKER_ID = "CAACAgEAAxkBAAMqYYYa_7hpXH6hMOYMX4Nh8AVYd74AAnQnAAJ4_MYFRdmmsQKLDZgiBA"; private static final String EXIT_403_STICKER_ID = "CAACAgEAAxkBAAMqYYYa_7hpXH6hMOYMX4Nh8AVYd74AAnQnAAJ4_MYFRdmmsQKLDZgiBA";
private static final String NON_COMMAND_QUESTION_STICKER_ID = "CAACAgEAAx0CSQh32gABA966YbRJpbmi2lCHINBDuo1DknSTsbsAAqUoAAJ4_MYFUa8SIaZriAojBA";
@Override @Override
public boolean onMessage (@Nonnull Update event) { public boolean onMessage (@Nonnull Update event) {
@ -55,12 +51,27 @@ public class OnCommandExecute extends EventListener {
case "/version": case "/version":
onCommandVersionExec(event); onCommandVersionExec(event);
break; break;
case "/runtime":
onCommandRuntimeExec(event);
break;
default: default:
return false; // 无法解析的命令转交事件链后代处理 return nonCommandExecutable(event, command);
} }
return true; // 命令执行成功标记事件为已处理退出事件链 return true; // 命令执行成功标记事件为已处理退出事件链
} }
private boolean nonCommandExecutable (Update event, InputCommand command) {
if (command.getTarget() == null) return false; // 无法解析的命令转交事件链后代处理
else { // 无法解析的显式命令格式报错找不到命令
MornyCoeur.getAccount().execute(new SendSticker(
event.message().chat().id(),
NON_COMMAND_QUESTION_STICKER_ID
).replyToMessageId(event.message().messageId())
);
return true;
}
}
private void onCommandOnExec (@Nonnull Update event) { private void onCommandOnExec (@Nonnull Update event) {
MornyCoeur.getAccount().execute(new SendSticker( MornyCoeur.getAccount().execute(new SendSticker(
event.message().chat().id(), event.message().chat().id(),
@ -110,9 +121,50 @@ public class OnCommandExecute extends EventListener {
MornySystem.VERSION, MornySystem.VERSION,
MornySystem.getJarMd5(), MornySystem.getJarMd5(),
GradleProjectConfigures.COMPILE_TIMESTAMP, GradleProjectConfigures.COMPILE_TIMESTAMP,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.ofInstant( CommonFormatUtils.formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0)
Instant.ofEpochMilli(GradleProjectConfigures.COMPILE_TIMESTAMP), )
ZoneId.ofOffset("UTC", ZoneOffset.UTC))) ).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
}
private void onCommandRuntimeExec (@Nonnull Update event) {
MornyCoeur.getAccount().execute(new SendMessage(
event.message().chat().id(),
String.format("""
system:
- <code>%s</code>
- <code>%s</code>
- <code>%d</code> cores
java runtime:
- <code>%s</code>
- <code>%s</code>
memory:
- <code>%d</code> / <code>%d</code> MB
morny version:
- <code>%s</code>
- <code>%s</code>
- <code>%s [UTC]</code>
- [<code>%d</code>]
continuous
- <code>%s</code>
- [<code>%d</code>]""",
// system
System.getProperty("os.name"),
System.getProperty("os.version"),
Runtime.getRuntime().availableProcessors(),
// java
System.getProperty("java.vm.name"),
System.getProperty("java.version"),
// memory
Runtime.getRuntime().totalMemory() / 1024 / 1024,
Runtime.getRuntime().maxMemory() / 1024 / 1024,
// version
MornySystem.VERSION,
MornySystem.getJarMd5(),
CommonFormatUtils.formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0),
GradleProjectConfigures.COMPILE_TIMESTAMP,
// continuous
CommonFormatUtils.formatDuration(System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp),
System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp
) )
).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML)); ).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
} }

View File

@ -0,0 +1,28 @@
package cc.sukazyo.cono.morny.util;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class CommonFormatUtils {
public static String formatDate (long timestamp, int utcOffset) {
return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.ofInstant(
Instant.ofEpochMilli(timestamp),
ZoneId.ofOffset("UTC", ZoneOffset.ofHours(utcOffset))
));
}
public static String formatDuration (long duration) {
StringBuilder sb = new StringBuilder();
if (duration > 1000 * 60 * 60 * 24) sb.append(duration / (1000*60*60*24)).append("d ");
if (duration > 1000 * 60 * 60) sb.append(duration / (1000*60*60) % 24).append("h ");
if (duration > 1000 * 60) sb.append(duration / (1000*60) % 60).append("min ");
if (duration > 1000) sb.append(duration / 1000 % 60).append("s ");
sb.append(duration % 1000).append("ms");
return sb.toString();
}
}