本帖最后由 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