本帖最后由 yumc 于 2020-5-13 17:32 编辑 
最近需要拦截服务端日志 做转发
然后折腾了半天没折腾出来
有大佬嘛
目前是对插件的Logger加了一个Filter
但是只能拦截到插件自身的日志直接加到Bukkit的Logger上好像又没啥用
谁有能够全局截获日志的方法
另一个就是 怎么获取 发送给ConsoleSender的消息
看了看具体实现 好像直接怼到 System.out 上面了
问题解决了
通过Arthas 导出了Heapdump 分析了一下引用链
最终在 net.minecraft.server.v1_12_R1.MinecraftServer 下面 找到了一个静态字段 LOGGER
最后获取 parent 就好了
nashorn伪代码 在MiaoScript可以运行
来自群组: 银河系气功协会
最近需要拦截服务端日志 做转发
然后折腾了半天没折腾出来
有大佬嘛
目前是对插件的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);
        }
    }来自群组: 银河系气功协会
mc使用log4j,可以直接拦截log4j的日志(就是从log4j入手)
Karlatemp 发表于 2020-5-13 13:25
mc使用log4j,可以直接拦截log4j的日志(就是从log4j入手)
嗯 那个我写AuthMe的时候用过
但是好像只能拦截插件自己的
我试过设置到Bukkit上 但是好像拦不到
你可以尝试操作一下RootLogger,没记错的话最终都会走Root Logger
Karlatemp 发表于 2020-5-13 13:54
你可以尝试操作一下RootLogger,没记错的话最终都会走Root Logger
比较迷幻的是 我获取 Bukkit.getLogger返回的并不是 log4j 的实例
>mpm run org.bukkit.Bukkit.getLogger()
[14:00:16 INFO]: [MS][PM] 运行脚本: org.bukkit.Bukkit.getLogger()
[14:00:16 INFO]: [MS][PM] 返回结果: java.util.logging.Logger@739cb3a2import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Logger;
public class JavaTest {
public static void test() {
Logger logger = ((Logger) LogManager.getRootLogger());
logger.addAppender(...);
}
}
可以试下
yumc 发表于 2020-5-13 13:55
比较迷幻的是 我获取 Bukkit.getLogger返回的并不是 log4j 的实例
Bukkit.getLogger()获取的是jdk原生日志,属于log4j的一个wrapper通道. 获取Log4j的root logger得用log4j的方法
Karlatemp 发表于 2020-5-13 13:56
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Logger;
Appender 推荐用啥呐
自己实现 还是说 继承某个抽象类
Karlatemp 发表于 2020-5-13 13:59
Bukkit.getLogger()获取的是jdk原生日志,属于log4j的一个wrapper通道. 获取Log4j的root logger得用log4j ...
好像有点问题
我在不同的地方获取 getRootLogger 返回的实例并不是同一个
[15:05:04 INFO]: [MiaoScript] [MiaoConsole] :INFO in 3d7a7912
[15:05:04 INFO]: [MS][PM] 插件 MiaoConsole 重载完成!
[15:05:05 INFO]: [MiaoScript] [MiaoConsole] Netty Channel Pipeline Inject MiaoDetectHandler Successful!
[15:05:10 INFO]: [MS][MiaoConsole] 客户端 /MiaoConsole#87ab59ae 新建连接...
>mpm run Packages.org.apache.logging.log4j.LogManager.getRootLogger()
[15:06:04 INFO]: [MS][PM] 运行脚本: Packages.org.apache.logging.log4j.LogManager.getRootLogger()
[15:06:04 INFO]: [MS][PM] 返回结果: :INFO in 21123a77轻光233 发表于 2020-5-13 18:46
您好
获取控制台所有输出的问题论坛讨论过,我给出过一个详细的答案,可以直接操作
https://www.mcbbs.net/ ...
嗯 已经分析源码解决了
现在在折腾Sponge的日志拦截
有点小问题