4

我正在尝试调试我正在编写的 Neo4J Server 插件中的问题。有我可以输出的日志吗?在哪里或如何做到这一点并不明显。

4

2 回答 2

5

好问题。我认为您可以使用Java Logging?这应该被路由到正常的日志记录系统。

于 2012-07-29T18:18:18.243 回答
2

只需注入org.neo4j.logging.Log包含 Neo4j 存储过程实现的类即可。

public class YourProcedures {

    @Context
    public Transaction tx;

    @Context
    public Log log;

    @Procedure(value = "yourProcedure", mode = Mode.READ)
    public Stream<YourResult> yourProcedure(@Name("input") String input) {
       log.debug("something");
    }
}

然后将日志转储到标准 Neo4j 日志文件中。级别由GraphDatabaseSettings.store_internal_log_level配置控制。级别也可以在运行时更改。只需注入DependencyResolverbean 并定义这个管理过程。(该框架有监听器连接到重新配置内部日志框架的配置更改。这是我能找到的最简单的解决方案。)

@Context
public DependencyResolver dependencyResolver;

@Procedure(value = "setLogLevel", mode = Mode.DBMS)
@Description("Runtime change of logging level")
public void setLogLevel(@Name("level") String level) {
    Config config = dependencyResolver.resolveDependency(Config.class);
    config.set(GraphDatabaseSettings.store_internal_log_level, Level.valueOf(level));
}

更新:

这个 ^ 解决方案有效,但是当想要使用 Log4j 中通常的日志记录方式时它是不够的 - 不同的记录器按层次结构组织,每个记录器都有自己的级别。该org.neo4j.logging.Log组件只是GlobalProcedures该类的 Log4j 记录器的包装器。此记录器只是层次结构中的许多记录器之一。事实上,包装器阻止了对底层框架更丰富特性的访问。(不幸的是,@Context Log在类中定义由某些注释限定记录器区分的多个字段YourProcedures也是不可能的,因为字段注入是由驱动的,因此根据字段类型,Map<Class,instance>对于任何带注释的字段只有一个可能的实例注入。)@Context-

解决方案 1: 在接受的答案中使用 JUL。缺点是,JUL 无论如何都会将日志事件重定向到底层 Log4j,因此如果在 JUL 中定义了记录器层次结构,则必须将 Log4j 设置为尽可能低的级别,以使 JUL 级别敏感。

解决方案2: 直接使用Log4j(即public static final Logger logger = LogManager.getLogger("some.identifier.in.hierarchy")YourProcedures)。尽管有可能以编程方式重新定义配置存在一些问题,但我放弃了这个解决方案只是因为我在非 docker 环境中部署这个解决方案时遇到了一些问题。

解决方案 3:(最终选择)我定义了自定义组件LogWithHierarchy(它可以ExtensionFactory使用 s 从自己加载的内容构建ServiceLoader- 我在APOC 配置实现中受到启发)。该组件提供表单等API debug(loggerName, message)info(loggerName, message)该组件知道原始Log,深入到其log4jLoggerContext并将所有日志记录请求重定向到此中的特定记录器LoggerContext。日志消息最终以debug.log. 有了这个解决方案,原始的 log4j 记录器层次结构被充分利用,级别可以在运行时动态更改(setLogLevel必须更改以在上述操作上进行操作LoggerContext),并且仍然使用标准 Neo4j 插件支持来实现所有内容。

于 2021-05-05T15:44:46.670 回答