跳到主要内容

DebugInOut 插件

提示

使用场景推荐

  • 开发阶段

介绍

DebugInOut 是控制台输出插件,主要关注点

  1. 快速导航到请求处理的业务代码中(执行的 action )
  2. 当前发起请求的用户(玩家)
  3. 玩家当前所使用的连接方式(webSocket、Tcp、udp)
  4. 执行 action 的线程
  5. 执行 action 耗时情况
  6. 路由、类信息、方法信息等
  7. action 接收的请求参数
  8. action 响应给玩家的数据(响应结果)

当 action 处理请求时,会在控制台打印上述相关信息。 这意味着即使有新人加入到项目中,也能快速知道每个请求所对应的 action , 从而快速熟悉项目的整体业务逻辑。

当访问 action 业务方法时,控制台将会打印的日志输出如下

┏━━ Debug.(HallAction.java:18) ━━ [UserMessage loginVerify(String jwt)] ━━ [31-1] ━━ [tag:HallLogicServer, serverId:5656645] ━━━━
┣ userId: 1378604058
┣ RequestParam: Michael Jackson
┣ ResponseData: UserMessage(id=1378604058, nickname=Jack)
┣ ExecutionTime: 1 ms
┗━━ [ionetVersion] ━━ [Thread:User-8-1] ━━ [ConnectionWay:WebSocket] ━━ [traceId:1761556037925] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

控制台打印说明

  • code 1:
    • [Debug.(HallAction.java:18)] : 表示执行业务的是 HallAction 类,18 表示业务方法所在的代码行数。 在工具中点击控制台的 HallAction.java:18 这条信息,就可以跳转到对应的代码中(快速导航到对应的代码),这是一个开发良好体验的开始!
    • [UserMessage loginVerify(String jwt)] : 表示执行的方法,并列出了方法的参数及返回值。
    • [31-1] : 本次请求的路由。
    • [tag:HallLogicServer] : 执行请求的逻辑服信息。
  • code 2: 当前发起请求的 userId。
  • code 3: 请求参数,由请求端传入的值。
  • code 4: 响应值,框架会把这个返回值推送到请求端。
  • code 5: 执行业务方法总耗时,我们可根据该值来优化业务。
  • code 6:
    • [ionetVersion] : 当前框架的版本。
    • [Thread:User-8-1] : 当前执行 action 所使用的线程。
    • [ConnectionWay:WebSocket] : 用户所在对外服的连接方式。
    • [traceId] : 全链路调用日志跟踪 id。(该特性在分布式下非常实用)。

有了以上信息,开发者可以很快的定位问题。 如果没有可视化的信息,开发中会浪费很多时间在前后端的沟通上。问题包括:

  • 是否传参问题 (请求端说传了)
  • 是否响应问题(后端说返回了)
  • 业务执行时长问题 (请求端说没收到响应, 后端说早就响应了)

其中代码导航可以让开发者快速的跳转到业务类对应代码中, 在多人合作的项目中可以快速的知道业务经过了哪些方法的执行,使得我们可以快速的进行阅读或修改。

如何使用

BarSkeletonBuilder builder = ...;
builder.addInOut(new DebugInOut());

最小触发打印时间

插件可以设置最小触发打印时间,默认是 0 表示打印所有请求。 我们可以设置一个最小触发打印时间,当设置 50 ms 时,只有请求超过这个时间的请求才进行打印。

BarSkeletonBuilder builder = ...;
builder.addInOut(new DebugInOut(50));

如何忽略打印

有时我们需要避免某些 action 打印 debug 信息。 可以通过 DebugInOut.setPrintConsumer 方法来做自定义打印设置。


通过硬编码的方式

code 9,当路由为 1-3 时,不打印 debug

public class MyLogicServer implements LogicServer {
@Override
public void settingBarSkeletonBuilder(BarSkeletonBuilder builder) {
var debugInOut = new DebugInOut();
builder.addInOut(debugInOut);

debugInOut.setPrintConsumer((message, flowContext) -> {
CmdInfo cmdInfo = flowContext.getCmdInfo();
if (cmdInfo.getCmd() == 1 && cmdInfo.getSubCmd() == 3) {
return;
}

System.out.println(message);
});
}
}

通过自定义注解

  • code 9,不打印 DebugInOut 日志。
  • code 21,自定义注解。
public class MyLogicServer implements LogicServer {
@Override
public void settingBarSkeletonBuilder(BarSkeletonBuilder builder) {
var debugInOut = new DebugInOut();
builder.addInOut(debugInOut);

debugInOut.setPrintConsumer((message, flowContext) -> {
ActionCommand actionCommand = flowContext.getActionCommand();
if (actionCommand.containAnnotation(IgnoreDebugInout.class)) {
return;
}

System.out.println(message);
});
}
}

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IgnoreDebugInout {
}

使用

@ActionController(1)
public class DemoAction {
@ActionMethod(3)
@IgnoreDebugInout
public String hello() {
return "hello";
}
}