添加 /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
VERSION = 0.4.1.1
VERSION = 0.4.1.2
# dependencies

View File

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

View File

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

View File

@ -1,11 +1,8 @@
package cc.sukazyo.cono.morny;
import cc.sukazyo.cono.morny.util.CommonFormatUtils;
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;
@ -113,9 +110,7 @@ public class ServerMain {
MornySystem.VERSION,
MornySystem.getJarMd5(),
GradleProjectConfigures.COMPILE_TIMESTAMP,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.ofInstant(
Instant.ofEpochMilli(GradleProjectConfigures.COMPILE_TIMESTAMP),
ZoneId.ofOffset("UTC", ZoneOffset.UTC)))
CommonFormatUtils.formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0)
));
return;

View File

@ -37,14 +37,17 @@ public class InputCommand {
return new InputCommand(cx.length == 1 ? null : cx[1], cx[0], args);
}
@Nullable
public String getTarget () {
return target;
}
@Nonnull
public String getCommand () {
return command;
}
@Nonnull
public String[] getArgs () {
return args;
}
@ -54,6 +57,7 @@ public class InputCommand {
}
@Override
@Nonnull
public String toString() {
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.InputCommand;
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.request.ParseMode;
import com.pengrad.telegrambot.request.SendMessage;
@ -14,12 +15,6 @@ import com.pengrad.telegrambot.request.SendSticker;
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;
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 EXIT_STICKER_ID = "CAACAgEAAxkBAAMoYYYWt8UjvP0N405SAyvg2SQZmokAAkMiAAJ4_MYFw6yZLu06b-MiBA";
private static final String EXIT_403_STICKER_ID = "CAACAgEAAxkBAAMqYYYa_7hpXH6hMOYMX4Nh8AVYd74AAnQnAAJ4_MYFRdmmsQKLDZgiBA";
private static final String NON_COMMAND_QUESTION_STICKER_ID = "CAACAgEAAx0CSQh32gABA966YbRJpbmi2lCHINBDuo1DknSTsbsAAqUoAAJ4_MYFUa8SIaZriAojBA";
@Override
public boolean onMessage (@Nonnull Update event) {
@ -55,12 +51,27 @@ public class OnCommandExecute extends EventListener {
case "/version":
onCommandVersionExec(event);
break;
case "/runtime":
onCommandRuntimeExec(event);
break;
default:
return false; // 无法解析的命令转交事件链后代处理
return nonCommandExecutable(event, command);
}
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) {
MornyCoeur.getAccount().execute(new SendSticker(
event.message().chat().id(),
@ -110,9 +121,50 @@ public class OnCommandExecute extends EventListener {
MornySystem.VERSION,
MornySystem.getJarMd5(),
GradleProjectConfigures.COMPILE_TIMESTAMP,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.ofInstant(
Instant.ofEpochMilli(GradleProjectConfigures.COMPILE_TIMESTAMP),
ZoneId.ofOffset("UTC", ZoneOffset.UTC)))
CommonFormatUtils.formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0)
)
).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));
}

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();
}
}