日志
Neo4j 提供用于监控目的的日志。日志存储在 logs 目录中。如果您想使用自定义目录,请在 neo4j.conf 文件中使用参数 server.directories.logs 设置该目录的路径。
日志文件
下表描述了 Neo4j 中可用的日志文件及其默认配置。哪些日志处于启用或禁用状态,是在 neo4j.conf 文件中进行配置的。
| 文件名 | 描述 | 配置 | 默认 |
|---|---|---|---|
neo4j.log |
记录有关 Neo4j 的一般信息。对于 Debian 和 RPM 软件包,请运行 |
|
|
debug.log |
Neo4j 客户支持调查问题所需的日志信息。强烈建议保持其启用状态,且不要更改 debug.log 的格式。如果您需要其他格式的 debug.log 消息,请创建额外的 Appender。从 Neo4j 2025.01 版本开始,默认格式为 JSON。 |
|
|
http.log |
记录有关 HTTP API 的信息。 |
|
|
gc.log |
记录 JVM 提供的信息。 详情请参阅 配置垃圾回收日志。 |
|
|
query.log |
企业版 记录执行时间超过指定阈值的查询的相关信息。必须设为
详情请参阅 配置查询日志。 |
|
|
security.log |
企业版 记录有关安全事件的信息。 |
|
|
service-out.log |
Windows 安装或运行 Windows 服务时的控制台输出日志。 |
||
service-error.log |
Windows 记录安装或运行 Windows 服务时遇到的错误信息。 |
||
neo4j-admin-exception-trace-yyyy-MM-dd.HH.mm.ss.log |
2025.01 引入 在单独的日志文件中记录执行 |
||
neo4j-admin-import-yyyy-MM-dd.HH.mm.ss.log [1] |
2025.01 引入 在单独的日志文件中记录使用 2026.03 修改 在 2026.03 版本中,导入日志的名称和路径更新为 |
||
默认日志配置
Neo4j 使用 Log4j 2 进行日志记录。日志配置位于 conf 目录中,由两个文件组成
-
user-logs.xml — 提供 neo4j.log 的配置。
-
server-logs.xml — 提供 debug.log、http.log、query.log 和 security.log 的配置。
gc.log 由 Java 虚拟机 (JVM) 处理,并使用 JVM 参数进行配置。详情请参阅 配置垃圾回收日志。
|
从 Neo4j 2025.01 版本开始,默认配置文件位于 server.directories.configuration=conf 目录中。因此,配置文件的默认路径为 <home>/conf/user-logs.xml 和 <home>/conf/server-logs.xml。如果您为 Log4j 配置文件使用了自定义目录,请在 neo4j.conf 文件中更新 XML 文件的路径,使其依赖于 <conf> 而不是 <home>。例如: |
每个配置文件包含两个主要元素:Appenders(附加器)和 Loggers(记录器)。
- 在 Appenders 元素内,您可以定义:
-
-
输出位置,例如文件、控制台、网络套接字等。
-
输出的格式,例如纯文本、JSON、CSV 等。
-
何时轮转文件,以及在删除前保留多少历史文件。
-
发布哪些日志事件以及如何发布。
-
- 在 Loggers 元素内,您可以定义:
-
-
捕获哪些日志事件并发送到哪些 Appenders。
-
要捕获的日志事件的级别。
-
日志事件是否应转发给其他 Loggers。
-
更多详情,请参阅 Log4j 2 官方配置文档。
以下示例展示了 user-logs.xml 文件的默认配置。
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) "Neo4j"
Neo4j Sweden AB [https://neo4j.com.cn]
This file is a commercial add-on to Neo4j Enterprise Edition.
-->
<!--
This is a log4j 2 configuration file that provides maximum flexibility.
All configuration values can be queried with the lookup prefix "config:". You can, for example, resolve
the path to your neo4j home directory with ${config:dbms.directories.neo4j_home}.
Please consult https://logging.apache.ac.cn/log4j/2.x/manual/configuration.html for instructions and
available configuration options.
-->
<Configuration status="ERROR" monitorInterval="30" packages="org.neo4j.logging.log4j"> \ (1)
<Appenders> \ (2)
<RollingRandomAccessFile name="Neo4jLog" fileName="${config:server.directories.logs}/neo4j.log" (3)
filePattern="$${config:server.directories.logs}/neo4j.log.%02i"> (4)
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p %m%n"/> (6)
<Policies> \ (7)
<SizeBasedTriggeringPolicy size="20 MB"/> \ (8)
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="7"/> \ (9)
</RollingRandomAccessFile>
<!-- Only used by "neo4j console", will be ignored otherwise -->
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p %m%n"/>
</Console>
</Appenders>
<Loggers> \ (10)
<!-- Log level for the neo4j log. One of DEBUG, INFO, WARN, ERROR or OFF -->
<Root level="INFO"> \ (11)
<AppenderRef ref="Neo4jLog"/>
<AppenderRef ref="ConsoleAppender"/>
</Root>
</Loggers>
</Configuration>
以下示例展示了 server-logs.xml 文件的默认配置。
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) "Neo4j"
Neo4j Sweden AB [https://neo4j.com.cn]
This file is a commercial add-on to Neo4j Enterprise Edition.
-->
<!--
This is a log4j 2 configuration file.
Please keep the original "debug.log" as is, to make sure enough data is captured in of case errors
in a format that neo4j support engineers and developers can work with. Changing the "debug.log" format
can interfere with neo4j's ability to offer customer support and invalidate your support warranty.
If you require the "debug.log" messages in a different format you can copy the Appender and change the
filename. See Neo4j documentation.
All configuration values can be queried with the lookup prefix "config:". You can for example, resolve
the path to your neo4j home directory with ${config:dbms.directories.neo4j_home}.
Please consult https://logging.apache.ac.cn/log4j/2.x/manual/configuration.html for instructions and
available configuration options.
-->
<Configuration status="ERROR" monitorInterval="30" packages="org.neo4j.logging.log4j"> \ (1)
<Appenders> \ (2)
<!-- Neo4j debug.log, do not change. Required by Neo4j customer support. -->
<RollingRandomAccessFile name="DebugLog" fileName="${config:server.directories.logs}/debug.log" \ (3)
filePattern="$${config:server.directories.logs}/debug.log.%02i"> \ (4)
<!-- JSON format -->
<JsonTemplateLayout eventTemplateUri="classpath:org/neo4j/logging/StructuredLayoutWithMessage.json"/> \ (5)
<!-- Text format -->
<!-- <Neo4jDebugLogLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p [%c{1.}] %m%n"/> --> \ (6)
<Policies> \ (7)
<SizeBasedTriggeringPolicy size="20 MB"/> \ (8)
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="7"/> \ (9)
</RollingRandomAccessFile>
<RollingRandomAccessFile name="HttpLog" fileName="${config:server.directories.logs}/http.log"
filePattern="$${config:server.directories.logs}/http.log.%02i">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="5"/>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="QueryLog" fileName="${config:server.directories.logs}/query.log"
filePattern="$${config:server.directories.logs}/query.log.%02i">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="7"/>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="SecurityLog" fileName="${config:server.directories.logs}/security.log"
filePattern="$${config:server.directories.logs}/security.log.%02i">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="7"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers> \ #10>
<!-- Log levels. One of DEBUG, INFO, WARN, ERROR or OFF -->
<!-- The debug log is used as the root logger to catch everything -->
<Root level="INFO"> \ (11)
<AppenderRef ref="DebugLog"/> <!-- Keep this -->
</Root>
<!-- The query log, must be named "QueryLogger" -->
<Logger name="QueryLogger" level="INFO" additivity="false"> \ (12)
<AppenderRef ref="QueryLog"/>
</Logger>
<!-- The http request log, must be named "HttpLogger" -->
<Logger name="HttpLogger" level="INFO" additivity="false">
<AppenderRef ref="HttpLog"/>
</Logger>
<!-- The security log, must be named "SecurityLogger" -->
<Logger name="SecurityLogger" level="INFO" additivity="false">
<AppenderRef ref="SecurityLog"/>
</Logger>
</Loggers>
</Configuration>
| 1 | 带有 monitorInterval 为 30 秒和包命名空间 org.neo4j.logging.log4j 的配置标签。监视间隔告诉 Log4j 定期检查 XML 文件是否有更改,如果检测到更改则重新加载文件。 包命名空间允许通过 ${config:<setting>} 访问 Neo4j 配置查找。 |
| 2 | Appenders 用于定义将日志消息写入何处。Appender 的 name 必须是唯一的,因为 Logger 在引用它时会使用该名称。Neo4j 默认的 Appenders 将日志写入 debug.log、http.log、query.log 和 security.log。 |
| 3 | 默认情况下,Neo4j 使用 <RollingRandomAccessFile> appender,因为它始终写入缓冲区,性能极高。但是,如果服务器崩溃,最后的一些日志消息可能会丢失。如果您不能接受这一点,请改用 <RollingFile> appender。有关更多信息,请参阅 Appenders。 |
| 4 | filePattern 指定文件轮转时要使用的文件模式。当文件达到定义的触发条件时,该模式会将文件重命名为 debug.log.01 和 http.log.01 等。 |
| 5 | JsonTemplateLayout 布局用于将日志消息格式化为 JSON。从 Neo4j 2025.01 开始,debug.log 的默认格式为 JSON,强烈建议保持其启用以确保最佳支持。如果您需要其他格式的 debug.log 消息,请创建额外的 Appender,因为默认的 Appender 是由 Neo4j 支持团队使用的。如果您需要使用文本格式,可以取消注释条目 <6>。 |
| 6 | PatternLayout 定义了 appender 的布局,在本例中使用了 GMT+2 时区。请注意,这是在 5.x 系列中使用的,目前默认处于禁用状态。有关更多信息,请参阅 日志布局。 |
| 7 | Policies 元素定义了何时轮转文件,以及在删除前保留多少历史文件。 |
| 8 | SizeBasedTriggeringPolicy 定义了何时轮转文件。在本例中,当文件大小达到 20 MB 时,文件会根据 filePattern 进行重命名,日志文件将重新开始。在 Neo4j 4.0 中,这是通过参数 dbms.logs.user.rotation.size 配置的。 |
| 9 | DefaultRolloverStrategy 定义了保留多少历史文件。fileIndex=min 意味着最小/最低的编号是最新的文件。max 属性定义了删除前要保留的历史文件数量,在本例中为 7 个文件。在 Neo4j 4.0 中,这是通过参数 dbms.logs.user.rotation.keep_number 配置的。 |
| 10 | Loggers 用于定义日志级别以及日志消息使用的 appender。Loggers 通过 name 属性引用。有关更多信息,请参阅 Loggers。 |
| 11 | 根记录器(Root logger)是一个“包罗万象”的记录器,它会捕获所有其他记录器未捕获的内容,并将其发送到 AppenderRef 元素中指定的 appender。根记录器由 Root 元素引用。它可以设置为 DEBUG、INFO、WARN、ERROR 或 OFF。默认日志级别为 INFO。 |
| 12 | 您还可以定义自定义记录器来捕获特定日志事件,并将其发送到 AppenderRef 元素中指定的 appender。例如,QueryLogger 记录器(在 server-logs.xml 中配置)用于捕获日志级别为 INFO 或更高的日志事件,并将其发送到 QueryLog appender。设置 additivity="false" 可以完全消耗日志事件,而不将其发送到根记录器。如果设置了 additivity="true"(默认值),日志事件也会发送到根记录器。 |
高级日志配置
默认的日志配置是一个很好的起点,但您可能需要根据自己的需求对其进行自定义。以下章节描述了一些 Log4j 配置元素以及如何使用它们来自定义日志配置。有关其他信息和更高级的自定义(例如过滤和扩展),请参阅 Log4j 官方配置文档。
|
如果 Neo4j 嵌入在您的 Java 应用程序中,您必须提供一个 |
Appenders(附加器)
所有 Log4j 标准 appender 都可在 Neo4j 中使用。有关更多详细信息,请参阅 Log4j 官方 appender 文档。
一些最常用的 appender 是 <RollingRandomAccessFile>、<RollingFile> 和 <Console>。
<RollingRandomAccessFile> appender
<RollingRandomAccessFile> 是 Neo4j 中的默认 appender。它性能极高,对系统影响很小,因为它总是写入缓冲区。但是,日志事件可能不会立即显示,并且如果服务器崩溃,最后的一些日志消息可能会丢失。此 appender 使用 filePattern 属性进行配置,该属性指定了文件轮转时要使用的模式。当达到定义的触发器时,模式会将文件重命名为 debug.log.01 和 http.log.01 等。
可能的触发器包括 SizeBasedTriggeringPolicy 和 TimeBasedTriggeringPolicy。SizeBasedTriggeringPolicy 定义了何时轮转文件,在本例中为文件大小达到 20 MB 时。TimeBasedTriggeringPolicy 基于时间定义轮转,在本例中为每天轮转。
DefaultRolloverStrategy 定义了保留多少历史文件,以及使用哪个文件作为最新文件。fileIndex=min 意味着最小/最低编号的文件是最新的。max 属性定义了删除前保留的历史文件数量,本例中为 7 个。
有关更多信息,请参阅 Log4j 官方 RollingRandomAccessFile Appender 文档。
<RollingFile> appender
<RollingFile> appender 与 <RollingRandomAccessFile> 非常相似,但它将日志事件写入文件。当满足特定条件时,它会进行轮转。一种标准方案是每天保留一个日志文件,或者在达到特定大小时轮转日志文件。
<RollingFile name="myLog" fileName="${config:server.directories.logs}/my.log"
filePattern="${config:server.directories.logs}/my-%d{yyyy-MM-dd}.log">
<!-- Layout -->
<Policies>
<TimeBasedTriggeringPolicy />
</Policies>
</RollingFile>
轮转功能还支持对已轮转的文件进行压缩。向 filePattern 属性添加 .gz、.zip、.bz2、.deflate 或 .pack200 作为后缀,会导致文件使用相应的压缩方案进行压缩。
<RollingFile name="myLog" fileName="${config:server.directories.logs}/my.log"
filePattern="${config:server.directories.logs}/my.%i.log.zip">
<!-- Layout -->
<Policies>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
</RollingFile>
日志布局
日志文件可以用多种方式写入,这称为布局(layout)。Neo4j 捆绑了 Log4j 2 的所有默认布局,以及一些 Neo4j 特定的布局。有关默认 Log4j 2 布局的更多详情,请参阅 Log4j 官方文档。
<PatternLayout>
<PatternLayout> 是最常见的布局。它是一种灵活的布局,可通过 pattern 属性指定的模式字符串进行配置。例如
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p [%c{1.}] %m%n"/>
pattern 由以 % 为前缀的不同转换器组成。转换器会被替换为日志事件中相应的值。
| 转换器 | 描述 |
|---|---|
|
日志事件的日期。时区是可选的。如果省略,则使用系统时间。 |
|
事件的日志级别。可以是 |
|
日志事件来源的类名。在后面添加 |
|
日志事件的消息。 |
|
系统特定的换行符。 |
有关所有可用转换器,请参阅 Log4j 2 模式布局文档。
<JsonTemplateLayout>
<JsonTemplateLayout> 等同于模式布局,用于将日志消息格式化为 JSON。
|
从 Neo4j 2025.01 开始,JSON 是 debug.log 的默认格式。强烈建议不要更改 debug.log 的格式,因为 Neo4j 客户支持需要它来调查问题。如果您需要其他格式的 debug.log 消息,请创建额外的 Appender。 |
有两种配置 JSON 模板布局的方法。
-
您可以指定一个 JSON 事件模板文件,布局将使用该文件。JSON 模板文件可以位于文件系统上。
<JsonTemplateLayout eventTemplateUri="file://path/to/template.json"/> -
JSON 事件模板文件可以嵌入到 XML 配置中
<JsonTemplateLayout> <eventTemplate> <![CDATA[ { "time": { "$resolver": "timestamp", "pattern": { "format": "yyyy-MM-dd HH:mm:ss.SSSZ", "timeZone": "UTC" } }, "level": { "$resolver": "level", "field": "name" }, "message": { "$resolver": "message" }, "includeFullMap": { "$resolver": "map", "flatten": true }, "stacktrace": { "$resolver": "exception", "field": "message" } } ]]> </eventTemplate> </JsonTemplateLayout>
类路径中还有一些内置模板可用,例如
<JsonTemplateLayout eventTemplateUri="classpath:org/neo4j/logging/StructuredJsonLayout.json"/>
| eventTemplateUri | 描述 |
|---|---|
|
用于记录 JSON 消息的通用布局。可用于任何日志文件。 |
|
向后兼容的 JSON 布局,与 Neo4j 4.x 查询日志匹配。 |
|
|
|
Graylog 扩展日志格式 (GELF) 有效载荷规范,带有额外的 |
|
Google 云平台结构化日志记录,带有额外的 |
|
与功能较少的 |
有关更多信息,请参阅 Log4j 官方文档。
<Neo4jDebugLogLayout>
<Neo4jDebugLogLayout> 布局本质上与 PatternLayout 相同。主要区别在于在日志文件开头注入了一个标题,其中包含对 Neo4j 开发人员有用的诊断信息。此布局通常只应使用于 debug.log 文件。
<Neo4jDebugLogLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p [%c{1.}] %m%n"/>
过滤器(Filters)
您还可以配置过滤器来确定是否发布日志事件、发布哪些事件以及如何发布。有关详情,请参阅 Log4j 官方文档。
插件(Plugins)
您还可以通过将插件放入 plugin 目录来将插件添加到 Log4j。有关详情,请参阅 Log4j 官方插件文档。
记录器(Loggers)
记录器将日志事件转发到 appender。可以有任意数量的 <Logger> 元素,但只能有一个 <Root> 记录器元素。记录器具有可加性(additive)。可加性记录器将日志事件转发到其 appender,然后将日志事件传递给下一个匹配的记录器。非可加性记录器将日志事件转发到其 appender,然后丢弃该事件。根记录器是一个匹配所有内容的特殊记录器,因此如果其他记录器没有拾取日志事件,根记录器将会拾取。因此,最佳实践始终包含一个根记录器,以免遗漏任何日志事件。
<Configuration>
<!-- Appenders -->
<Loggers>
<Root level="WARN">
<AppenderRef ref="DebugLog"/>
</Root>
<Logger name="HttpLogger" level="INFO" additivity="false">
<AppenderRef ref="HttpLog"/>
</Logger>
</Loggers>
</Configuration>
记录器具有一个过滤日志事件的 level。一个级别也可以包含不同严重性的级别。例如,级别为 level="INFO" 的记录器会转发 INFO、WARN 和 ERROR 级别的日志事件。级别为 level="WARN" 的记录器仅记录 WARN 和 ERROR 事件。
下表列出了 Neo4j 提出的所有日志级别及其严重性级别
| 消息类型 | 严重性级别 | 描述 |
|---|---|---|
|
低严重性 |
报告关于所引发错误的详细信息和可能的解决方案。 |
|
低严重性 |
报告状态信息和非严重的错误。 |
|
低严重性 |
报告需要关注但非严重的错误。 |
|
高严重性 |
报告阻止 Neo4j 服务器运行的错误,必须立即解决。 |
有关记录器的更多详情,请参阅 Log4j 官方文档 → 配置记录器。
配置垃圾回收日志
垃圾回收日志(简称 GC 日志)很特殊,无法使用 Log4j 2 进行配置。GC 日志由 Java 虚拟机 (JVM) 处理,必须直接传递到命令行。为了简化此过程,Neo4j 在 neo4j.conf 中公开了以下设置
| 垃圾回收日志配置 | 默认值 | 描述 |
|---|---|---|
|
启用垃圾回收日志记录。 |
|
|
垃圾回收日志记录选项。有关可用选项,请咨询所使用的 JVM 发行版的文档。 |
|
|
垃圾回收日志的历史文件最大数量。 |
|
|
垃圾回收日志的轮转阈值大小。 |
配置安全日志
Neo4j 提供安全事件日志记录,记录所有安全事件。当配置 dbms.security.auth_enabled 设置为 true(默认值)时,安全日志会自动启用。它确保所有对 Neo4j 的请求都经过身份验证。有关安全日志的其他配置,请参阅 <NEO4J_HOME>/conf/server-logs.xml。
对于本地用户管理,会记录以下操作
-
登录尝试 —— 默认情况下,成功和不成功的登录都会被记录。
-
针对
system数据库运行的所有 管理命令。 -
基于角色的访问控制引发的授权失败。
如果使用 LDAP 作为身份验证方法,某些 LDAP 配置错误以及 LDAP 服务器通信事件和失败也会被记录。
如果预期会有大量的程序化交互,建议通过在 neo4j.conf 文件中设置 dbms.security.log_successful_authentication 参数来禁用成功登录的记录。
dbms.security.log_successful_authentication=false
安全日志可以使用 JSON 布局。要更改格式,必须将 SecurityLogger 的布局从使用 PatternLayout 更改
<RollingRandomAccessFile name="SecurityLog" fileName="${config:server.directories.logs}/security.log"
filePattern="$${config:server.directories.logs}/security.log.%02i">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="7"/>
</RollingRandomAccessFile>
为使用 JsonTemplateLayout
<RollingRandomAccessFile name="SecurityLog" fileName="${config:server.directories.logs}/security.log"
filePattern="$${config:server.directories.logs}/security.log.%02i">
<JsonTemplateLayout eventTemplateUri="classpath:org/neo4j/logging/StructuredJsonLayout.json"/>
<Policies>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="7"/>
</RollingRandomAccessFile>
另请参阅 <JsonTemplateLayout> 和 默认日志配置。
JSON 格式提供以下信息
| 名称 | 描述 |
|---|---|
|
日志消息的时间戳。 |
|
日志级别。 |
|
始终为 |
|
连接详情。 |
|
执行命令的数据库名称。此字段是可选的,因此不会针对所有安全事件进行填充。 |
|
连接到安全事件的用户。此字段已被 |
|
触发安全事件的用户名称。要么与 |
|
已通过身份验证并连接到安全事件的用户名称。 |
|
日志消息。 |
|
如果日志消息关联有堆栈跟踪,则包含在内。 |
纯格式的安全日志示例
2019-12-09 13:45:00.796+0000 INFO [johnsmith]: logged in
2019-12-09 13:47:53.443+0000 ERROR [johndoe]: failed to log in: invalid principal or credentials
2019-12-09 13:48:28.566+0000 INFO [johnsmith]: CREATE USER janedoe SET PASSWORD '********' CHANGE REQUIRED
2019-12-09 13:48:32.753+0000 INFO [johnsmith]: CREATE ROLE custom
2019-12-09 13:49:11.880+0000 INFO [johnsmith]: GRANT ROLE custom TO janedoe
2019-12-09 13:49:34.979+0000 INFO [johnsmith]: GRANT TRAVERSE ON GRAPH * NODES A, B (*) TO custom
2019-12-09 13:49:37.053+0000 INFO [johnsmith]: DROP USER janedoe
2019-12-09 13:52:24.685+0000 INFO [johnsmith:alice]: impersonating user alice logged in
配置查询日志
查询日志记录默认启用,并由设置 db.logs.query.enabled 控制。它有助于分析长时间运行的查询,且不会影响系统性能。默认行为是记录所有查询,但建议仅记录超过特定阈值的查询。
配置设置
参数 db.logs.query.enabled 有以下可用值
| 选项 | 描述 |
|---|---|
|
完全禁用日志记录。 |
|
在查询结束时进行记录,无论查询成功还是失败。 |
|
默认 在查询开始和结束时记录所有查询,无论 |
查询日志记录提供以下配置设置
| 查询日志配置 | 默认值 | 描述 | ||||
|---|---|---|---|---|---|---|
|
在不混淆密码的情况下记录查询文本和参数。这允许在开始解析之前更早地记录查询。 |
|||||
|
记录已执行的查询。 |
|||||
|
此配置选项允许您设置包含在日志中的最大参数长度。超过此长度的参数将被截断并附加 |
|||||
|
如果设置为 建议在生产环境中将此设置设为
|
|||||
2026.01 引入 |
|
如果设置为 建议在生产环境中将此设置设为
|
||||
|
记录已执行查询的参数。如果您不想显示敏感信息,可以禁用此配置设置。 |
|||||
|
此配置选项允许您记录每个查询的查询计划。查询计划显示为描述表,对调试非常有用。每当运行 Cypher 查询时,它都会生成并使用一个执行代码的计划。生成的计划可能会受到数据库更改的影响(例如添加新索引)。因此,无法历史性地查看原始查询执行时使用了什么计划。
|
|||||
|
如果查询执行时间超过此阈值,查询将在完成后被记录(前提是查询日志设置为 |
|||||
|
在查询日志中跟踪事务的开始和结束。日志条目被写入 query log。它们包括特定查询的事务 ID 以及事务的开始和结束。您还可以选择日志级别( |
|||||
|
如果事务打开的时间超过此阈值(时长),则在完成后记录该事务,前提是事务日志记录设置为 |
配置简单查询日志记录
在此示例中,查询日志记录设置为 INFO,所有其他查询日志参数均为默认值。
db.logs.query.enabled=INFO
以下是具有此基本配置的查询日志示例
2017-11-22 14:31 ... INFO 9 ms: bolt-session bolt johndoe neo4j-javascript/1.4.1 client/127.0.0.1:59167 ...
2017-11-22 14:31 ... INFO 0 ms: bolt-session bolt johndoe neo4j-javascript/1.4.1 client/127.0.0.1:59167 ...
2017-11-22 14:32 ... INFO 3 ms: server-session http 127.0.0.1 /db/data/cypher neo4j - CALL dbms.procedures() - {}
2017-11-22 14:32 ... INFO 1 ms: server-session http 127.0.0.1 /db/data/cypher neo4j - CALL dbms.showCurrentUs...
2017-11-22 14:32 ... INFO 0 ms: bolt-session bolt johndoe neo4j-javascript/1.4.1 client/127.0.0.1:59167 ...
2017-11-22 14:32 ... INFO 0 ms: bolt-session bolt johndoe neo4j-javascript/1.4.1 client/127.0.0.1:59167 ...
2017-11-22 14:32 ... INFO 2 ms: bolt-session bolt johndoe neo4j-javascript/1.4.1 client/127.0.0.1:59261 ...
配置带更多细节的查询日志记录
在此示例中,启用了查询日志以及一些额外的日志记录
db.logs.query.enabled=INFO
db.logs.query.parameter_logging_enabled=true
db.logs.query.threshold=<appropriate value>
以下示例查询在 Movies 数据库上运行
MATCH (n:Person {name:'Tom Hanks'})-[:ACTED_IN]->(n1:Movie)<-[:DIRECTED]-(n2:Person {name:"Tom Hanks"}) RETURN n1.title
<.file>query.log 中相应的查询日志为
2017-11-23 12:44:56.973+0000 INFO 1550 ms: (planning: 20, cpu: 920, waiting: 10) - 13792 B - 15 page hits, 0 page faults - bolt-session bolt neo4j neo4j-javascript/1.4.1 client/127.0.0.1:58189 server/127.0.0.1:7687> neo4j - match (n:Person {name:'Tom Hanks'})-[:ACTED_IN]->(n1:Movie)<-[:DIRECTED]-(n2:Person {name:"Tom Hanks"}) return n1.title; - {} - {}
在检查特定查询的参数时,一个显而易见但至关重要的注意事项是确保您仅分析与该特定查询计划相关的条目,而不是例如序列中每个日志条目的 CPU、时间、字节等。
以下是与上述查询对应的资源使用参数的分解及描述
2017-11-23 12:44:56.973+0000-
日志时间戳。
INFO-
日志类别。
1550 毫秒-
查询执行中花费的总经过墙上时间(Cumulative wall time)。它是规划时间 + CPU + 等待 + 任何其他处理时间(例如获取执行线程所花费的时间)的总和。此数字对于 CPU 线程工作于执行查询的每次时间都是累积的。
规划(Planning)-
指 Cypher 引擎创建查询计划所花费的时间。重复查询的计划可能会被缓存,因此,此类查询的规划时间将比之前未规划的查询短。在此示例中,这为 1550 毫秒的总执行时间贡献了 20 毫秒。
CPU 时间-
指执行查询的各个线程所花费的时间。例如,查询于 08:00 提交。它使用了 720 毫秒的 CPU,但随后 CPU 切换到另一个查询,因此第一个查询不再使用 CPU。然后,100 毫秒后,它再次获取/使用 CPU 200 毫秒(更多结果被加载,由客户端通过驱动程序请求),然后查询于 08:01:30 完成,因此总时长为 1550 毫秒(包括 2 次往返的一些往返时间),CPU 为 720+200=920 毫秒。
等待(Waiting)-
查询在执行前等待的时间(以毫秒为单位),例如,如果现有查询持有锁,而新查询必须等待该锁释放。在此示例中,这为 1550 毫秒的总执行时间贡献了 10 毫秒。
重要的一点是,客户端仅在记录缓冲区为空时才会向服务器请求数据(来自服务器的一次往返可能会产生多个记录),如果客户端没有及时读取数据,服务器将停止将数据推送到输出缓冲区。因此,这取决于结果集的大小。如果它相对较小并适合单次往返,客户端会一次性收到所有结果,服务器会在没有任何客户端副作用的情况下完成处理。同时,如果结果集较大,客户端处理时间将影响总体时间,因为它与何时从服务器请求新数据直接相关。 13792 B-
已执行查询记录的分配字节数。这是查询生命周期内使用的 HEAP 内存量。记录的数字在查询持续时间内是累积的,即对于内存密集型或长时间运行的查询,该值可能大于当前的内存分配。
15 次页面命中-
页面命中意味着结果是从页面缓存返回的,而不是从磁盘返回的。在此示例中,页面缓存被命中 15 次。
0 次页面错误-
页面错误意味着查询结果数据不在
dbms.memory.pagecache中,因此必须从文件系统中获取。在此示例中,查询结果完全从上述 8 次页面缓存命中中返回,因此不需要磁盘命中。 bolt-session-
会话类型。
bolt-
查询使用的浏览器 ←→ 数据库通信协议。
neo4j-
进程 ID。
neo4j-javascript/1.4.1-
驱动程序版本。
client/127.0.0.1:52935-
使用的查询客户端出站
IP:port。 server/127.0.0.1:7687>-
使用的服务器侦听
IP:port。 neo4j-
执行查询的用户名。
match (n:Person {name:'Tom Hanks'})-[:ACTED_IN]→(n1:Movie)←[:DIRECTED]-(n2:Person {name:"Tom Hanks"}) return n1.title-
执行的查询。
最后两个括号
{}{}用于查询参数和txMetaData。
将元数据附加到事务
您可以将元数据附加到事务,并使用内置过程 tx.setMetaData 将其打印在查询日志中。
|
Neo4j 驱动程序也支持将元数据附加到事务。有关更多信息,请参阅相应驱动程序的手册。 |
每个图形应用程序都应遵循一种约定,用于传递发送到 Neo4j 的查询元数据
{
app: "neo4j-browser_v4.4.0", (1)
type: "system" (2)
}
| 1 | app 可以是用户代理风格的名称加版本。 |
| 2 | type 可以是以下之一
|
这通常是程序化完成的,但也可以与 Neo4j 开发工具一起使用。
通常,您在用户数据库上启动一个事务,并通过调用 tx.setMetaData 将元数据列表附加到它。您还可以使用过程 CALL tx.getMetaData() 来显示当前事务的元数据。这些示例使用预装的 Neo4j 浏览器指南中的 Movie Graph 数据集。
cypher-shell,将元数据附加到事务| Cypher Shell 默认总是添加遵循约定的元数据。在此示例中,默认值被覆盖。 |
neo4j@neo4j> :begin
neo4j@neo4j# CALL tx.setMetaData({app: 'neo4j-cypher-shell_v.4.4.0', type: 'user-direct', user: 'jsmith'});
0 rows
ready to start consuming query after 2 ms, results consumed after another 0 ms
neo4j@neo4j# CALL tx.getMetaData();
+--------------------------------------------------------------------------+
| metadata |
+--------------------------------------------------------------------------+
| {app: "neo4j-cypher-shell_v.4.4.0", type: "user-direct", user: "jsmith"} |
+--------------------------------------------------------------------------+
1 row
ready to start consuming query after 37 ms, results consumed after another 2 ms
neo4j@neo4j# MATCH (n:Person) RETURN n LIMIT 5;
+----------------------------------------------------+
| n |
+----------------------------------------------------+
| (:Person {name: "Keanu Reeves", born: 1964}) |
| (:Person {name: "Carrie-Anne Moss", born: 1967}) |
| (:Person {name: "Laurence Fishburne", born: 1961}) |
| (:Person {name: "Hugo Weaving", born: 1960}) |
| (:Person {name: "Lilly Wachowski", born: 1967}) |
+----------------------------------------------------+
5 rows
ready to start consuming query after 2 ms, results consumed after another 1 ms
neo4j@neo4j# :commit
2021-07-30 14:43:17.176+0000 INFO id:225 - 2 ms: 136 B - bolt-session bolt neo4j-cypher-shell/v4.4.0 client/127.0.0.1:54026 server/127.0.0.1:7687> neo4j - neo4j -
MATCH (n:Person) RETURN n LIMIT 5; - {} - runtime=pipelined - {app: 'neo4j-cypher-shell_v.4.4.0', type: 'user-direct', user: 'jsmith'}
CALL tx.setMetaData({app: 'neo4j-browser_v.4.4.0', type: 'user-direct', user: 'jsmith'})
MATCH (n:Person) RETURN n LIMIT 5
2021-07-30 14:51:39.457+0000 INFO Query started: id:328 - 0 ms: 0 B - bolt-session bolt neo4j-browser/v4.4.0 client/127.0.0.1:53666 server/127.0.0.1:7687> neo4j - neo4j - MATCH (n:Person) RETURN n LIMIT 5 - {} - runtime=null - {type: 'system', app: 'neo4j-browser_v4.4.0'}
CALL tx.setMetaData({app: 'neo4j-browser_v.1.7.0', type: 'user-direct', user: 'jsmith'})
MATCH (n:Person) RETURN n LIMIT 5
2021-07-30 15:09:54.048+0000 INFO id:95 - 1 ms: 72 B - bolt-session bolt neo4j-bloom/v1.7.0 client/127.0.0.1:54693 server/127.0.0.1:11003> neo4j - neo4j - RETURN TRUE - {} - runtime=pipelined - {app: 'neo4j-bloom_v1.7.0', type: 'system'}
|
在 Neo4j Browser 和 Bloom 中,用户提供的元数据总是被系统元数据替换。 |
使用 JSON 格式进行查询日志记录
查询日志可以使用 JSON 布局。要更改格式,必须将 QueryLogger 的布局从使用 PatternLayout 更改
<RollingRandomAccessFile name="QueryLog" fileName="${config:server.directories.logs}/query.log"
filePattern="${config:server.directories.logs}/query.log.%02i">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="7"/>
</RollingRandomAccessFile>
为使用 JsonTemplateLayout
<RollingRandomAccessFile name="QueryLog" fileName="${config:server.directories.logs}/query.log"
filePattern="${config:server.directories.logs}/query.log.%02i">
<JsonTemplateLayout eventTemplateUri="classpath:org/neo4j/logging/QueryLogJsonLayout.json"/>
<Policies>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="7"/>
</RollingRandomAccessFile>
另请参阅 <JsonTemplateLayout> 和 默认日志配置。
JSON 格式日志条目
QueryLogJsonLayout.json 模板模仿了 4.x 布局,并包含以下信息
| 名称 | 描述 |
|---|---|
|
日志消息的时间戳。 |
|
日志级别。 |
|
有效选项为 |
|
当日志消息关联有堆栈跟踪时包含。 |
如果日志条目的类型是 query,则可以使用这些附加字段
| 名称 | 描述 |
|---|---|
|
有效选项为 |
|
查询 ID。ID 是增量的,从 1 开始,并在每次 Neo4j 重启时重置。当 |
|
以毫秒为单位的经过时间。 |
|
花费在规划上的毫秒数。 |
|
在 CPU 上主动执行花费的毫秒数。 |
|
等待锁或其他查询而非主动运行此查询花费的毫秒数。 |
|
查询分配的字节数。 |
|
页面命中数。 |
|
页面错误数。 |
|
连接详情。 |
|
运行查询的数据库名称。如果查询无法解析并路由到数据库,此字段将为 |
|
执行查询的用户名称。要么与 |
|
已通过身份验证并正在执行查询的用户名称。 |
|
查询文本。 |
|
查询参数。当 |
|
用于运行查询的运行时。 |
|
附加到事务的元数据。 |
|
失败原因。在适当时包含。由 |
|
以 JSON 对象形式提供的 GQL 错误信息。有关 |
|
正在运行的查询的事务 ID。 |
|
查询计划。当 |
|
用于缓存执行计划的缓存键的 32 位哈希值。它是十六进制编码整数值的 8 字符固定长度字符串。默认仅在 JSON 格式中启用。如果多个查询执行使用相同的缓存执行计划,则其哈希值应匹配。对于 |
|
Cypher 版本:有效选项为 |
如果日志条目的类型是 transaction,则可以使用以下附加字段
| 名称 | 描述 |
|---|---|
|
有效选项为 |
|
运行事务的数据库名称。 |
|
连接到事务的用户名称。要么与 |
|
已通过身份验证并连接到事务的用户名称。 |
|
事务的 ID。 |
GQL 错误信息
查询日志在 errorInfo JSON 对象下包含 GQL 错误信息。errorInfo 可以包含以下元素
-
GQLSTATUS— 一个 5 字符长的字母数字代码,用于标识错误。 -
statusDescription— 描述错误的消息。 -
classification— 错误的类型,表示客户端错误、临时错误和数据库错误的划分。 -
position— 查询中发生此错误的位置(包含column、offset和line字段的 JSON 对象)。 -
cause— 一个 JSON 对象,包含当前errorInfoJSON 对象的引发原因的errorInfoJSON 对象。
|
当异常没有 GQL 状态对象时,返回默认的 GQLSTATUS 代码 50N42。因此,切勿依赖此默认代码,因为未来的 Neo4j 版本可能会通过向异常添加适当的 GQL 对象来更改它。此外,外部过程的 GQL 代码尚不稳定。 |
以下是 errorInfo JSON 对象的示例
errorInfo JSON 对象...
"errorInfo": {
"GQLSTATUS": "51N66",
"statusDescription": "error: system configuration or operation exception - resource exhaustion. Insufficient resources to complete the request.",
"cause": {
"GQLSTATUS": "51N55",
"statusDescription": "error: system configuration or operation exception - cannot create additional database. Failed to create the database `db10`. The limit of databases is reached. Either increase the limit using the config setting dbms.max_databases or drop a database.",
"classification": "DATABASE_ERROR"
},
"classification": "DATABASE_ERROR"
},
...
errorInfo JSON 对象...
"errorInfo": {
"GQLSTATUS": "42N62",
"statusDescription": "error: syntax error or access rule violation - variable not defined. Variable `m` not defined.",
"position": {
"column": 18,
"offset": 17,
"line": 1
},
"classification": "CLIENT_ERROR"
},
"query": "MATCH (n) RETURN m",
...