You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ScriptEngineManager为GraalVM JS引擎配置自定义日志至Eclipse错误日志

将GraalVM TruffleLogger日志转发到Eclipse错误日志的解决方案

核心结论

  • 无需修改插件A的ScriptEngine初始化代码,即可附加自定义日志器
  • 可以通过程序化方式替换TruffleLogger,将日志转发至Eclipse错误日志

具体实现步骤

1. 获取GraalVM Polyglot Engine实例

GraalVM的JS ScriptEngine本质是JSScriptEngine,可以强制转换后获取底层的Polyglot Engine:

import org.graalvm.js.scriptengine.JSScriptEngine;
import org.graalvm.polyglot.Engine;

// 假设this.scriptEngine是从ScriptEngineManager获取的实例
JSScriptEngine graalScriptEngine = (JSScriptEngine) this.scriptEngine;
Engine polyglotEngine = graalScriptEngine.getPolyglotEngine();

2. 实现自定义TruffleLogger,转发至Eclipse错误日志

实现TruffleLogger接口,将日志事件映射到Eclipse的ILog(错误日志系统):

import org.graalvm.truffle.api.TruffleLogger;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

public class EclipseTruffleLogger implements TruffleLogger {
    private final ILog eclipseLog;
    private final String loggerName;
    private final String pluginId;

    public EclipseTruffleLogger(ILog eclipseLog, String loggerName, String pluginId) {
        this.eclipseLog = eclipseLog;
        this.loggerName = loggerName;
        this.pluginId = pluginId;
    }

    @Override
    public String getName() {
        return loggerName;
    }

    @Override
    public boolean isLogEnabled(Level level) {
        // 根据Eclipse日志配置调整级别过滤逻辑
        return switch (level) {
            case INFO, WARN, ERROR -> true;
            default -> false;
        };
    }

    @Override
    public void log(Level level, String message) {
        if (!isLogEnabled(level)) return;
        eclipseLog.log(createStatus(level, message, null));
    }

    @Override
    public void log(Level level, String message, Throwable thrown) {
        if (!isLogEnabled(level)) return;
        eclipseLog.log(createStatus(level, message, thrown));
    }

    private IStatus createStatus(TruffleLogger.Level level, String message, Throwable thrown) {
        int severity = switch (level) {
            case INFO -> IStatus.INFO;
            case WARN -> IStatus.WARNING;
            case ERROR -> IStatus.ERROR;
            default -> IStatus.INFO;
        };
        return new Status(severity, pluginId, message, thrown);
    }

    // 保留其他默认方法的实现
}

3. 注册自定义日志工厂到Polyglot Engine

将自定义日志器绑定到GraalVM的Engine,替换默认的TruffleLogger:

import org.graalvm.truffle.api.TruffleLoggerFactory;
import org.eclipse.core.runtime.Platform;

// 获取当前插件的Eclipse日志实例
String pluginId = "com.yourcompany.yourplugin"; // 替换为你的插件ID
ILog eclipseLog = Platform.getLog(Platform.getBundle(pluginId));

// 注册自定义日志工厂
polyglotEngine.getOptions().put(
    TruffleLoggerFactory.LOGGER_FACTORY,
    (loggerName) -> new EclipseTruffleLogger(eclipseLog, loggerName, pluginId)
);

备选方案:通过系统属性提前配置

如果无法在ScriptEngine初始化后获取Engine实例,可以在插件启动时提前设置系统属性,指定自定义日志工厂的全类名:

// 在插件激活类的start方法中设置
System.setProperty(
    "org.graalvm.truffle.logger.factory",
    "com.yourcompany.yourplugin.EclipseTruffleLoggerFactory"
);

对应的日志工厂类需要实现TruffleLoggerFactory:

import org.graalvm.truffle.api.TruffleLogger;
import org.graalvm.truffle.api.TruffleLoggerFactory;
import org.eclipse.core.runtime.Platform;

public class EclipseTruffleLoggerFactory implements TruffleLoggerFactory {
    private final ILog eclipseLog;
    private final String pluginId;

    public EclipseTruffleLoggerFactory() {
        this.pluginId = "com.yourcompany.yourplugin";
        this.eclipseLog = Platform.getLog(Platform.getBundle(pluginId));
    }

    @Override
    public TruffleLogger getLogger(String loggerName) {
        return new EclipseTruffleLogger(eclipseLog, loggerName, pluginId);
    }
}

注意事项

  • 确保项目依赖中包含GraalVM JS和Truffle的相关库(org.graalvm.js、org.graalvm.truffle)
  • 替换代码中的pluginId为你实际的Eclipse插件ID
  • 日志级别过滤逻辑可根据需求调整,匹配Eclipse的日志显示规则

内容的提问来源于stack exchange,提问作者Paul-E

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 10:22:44