yumc
本帖最后由 yumc 于 2020-5-13 17:32 编辑

最近需要拦截服务端日志 做转发
然后折腾了半天没折腾出来
有大佬嘛

目前是对插件的Logger加了一个Filter
但是只能拦截到插件自身的日志直接加到Bukkit的Logger上好像又没啥用

enable() {
        try {
            global['logger'].setFilter((record) => {
                this.loggerEvent.emit('log', record.getMessage())
                return true;
            });
        } catch (error) {
            console.error(error);
        }
    }

    disable() {
        try {
            global['logger'].setFilter(null);
            this.loggerEvent.removeAllListeners();
        } catch (error) {
            console.error(error);
        }
    }



谁有能够全局截获日志的方法
另一个就是 怎么获取 发送给ConsoleSender的消息
看了看具体实现 好像直接怼到 System.out 上面了
public class CraftConsoleCommandSender extends ServerCommandSender implements ConsoleCommandSender {

    protected final ConversationTracker conversationTracker = new ConversationTracker();

    protected CraftConsoleCommandSender() {
        super();
    }

    public void sendMessage(String message) {
        sendRawMessage(message);
    }

    public void sendRawMessage(String message) {
        System.out.println(ChatColor.stripColor(message));
    }
}


问题解决了
通过Arthas 导出了Heapdump 分析了一下引用链
最终在 net.minecraft.server.v1_12_R1.MinecraftServer 下面 找到了一个静态字段 LOGGER
最后获取 parent 就好了
nashorn伪代码 在MiaoScript可以运行

enable() {
        try {
            let AbstractAppender = Java.type('org.apache.logging.log4j.core.appender.AbstractAppender');
            let ProxyAppender = Java.extend(AbstractAppender, {
                append: (logEvent) => global.eventCenter.emit('log', logEvent.getMessage().getFormattedMessage())
            })
            Packages.net.minecraft.server.MinecraftServer.field_147145_h
            let logger = Packages.net.minecraft.server.v1_12_R1.MinecraftServer.LOGGER.parent;
            this.tempAppender = new ProxyAppender("ProxyLogger", null, null)
            this.tempAppender.start();
            logger.addAppender(this.tempAppender);
            logger.setAdditive(true);
        } catch (error) {
            console.error(error);
        }
    }

    disable() {
        try {
            let logger = Packages.net.minecraft.server.v1_12_R1.MinecraftServer.LOGGER.parent;
            this.tempAppender.stop();
            logger.removeAppender(this.tempAppender);
        } catch (error) {
            console.error(error);
        }
    }

来自群组: 银河系气功协会

Karlatemp
mc使用log4j,可以直接拦截log4j的日志(就是从log4j入手)

yumc
Karlatemp 发表于 2020-5-13 13:25
mc使用log4j,可以直接拦截log4j的日志(就是从log4j入手)

嗯 那个我写AuthMe的时候用过
但是好像只能拦截插件自己的
我试过设置到Bukkit上 但是好像拦不到

Karlatemp
你可以尝试操作一下RootLogger,没记错的话最终都会走Root Logger

下一页 最后一页