日志记录
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 |
2025.01 版新增 将使用 |
默认日志配置
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 元素中,您可以定义
-
-
哪些日志事件将被捕获并发送到哪个 Appender。
-
要捕获的日志事件的日志级别。
-
日志事件是否转发到其他 Loggers。
-
详情请参见 Log4j 2 官方配置文档。
以下示例显示了 user-logs.xml 文件的默认配置。
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) "Neo4j"
Neo4j Sweden AB [https://neo4j.ac.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.ac.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 在引用 appender 时使用。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。logger 通过 name 属性引用。有关更多信息,请参见Loggers。 |
11 | 根 logger 是一个“全捕获”logger,它捕获所有未被其他 logger 捕获的内容,并将其发送到 AppenderRef 元素中指定的 appender。根 logger 由 Root 元素引用。它可以设置为 DEBUG 、INFO 、WARN 、ERROR 或 OFF 。默认日志级别是 INFO 。 |
12 | 您还可以定义自定义 logger 以捕获特定的日志事件并将其发送到 AppenderRef 元素中指定的 appender。例如,QueryLogger logger(在 server-logs.xml 中配置)用于捕获日志级别为 INFO 或更高的日志事件,并将其发送到 QueryLog appender。additivity="false" 设置为完全消费日志事件,不将其发送到根 logger。如果设置了 additivity="true" (这是默认值),日志事件也会发送到根 logger。 |
高级日志配置
默认日志配置是一个很好的起点,但您可能希望根据自己的需求进行自定义。以下部分描述了一些 Log4j 配置元素以及如何使用它们来自定义日志配置。有关更多信息和更高级的自定义,例如过滤和扩展,请参见 Log4j 官方配置文档。
Appenders
所有 Log4j 标准 appenders 在 Neo4j 中都可用。有关更多详细信息,请参见 Log4j 官方 appenders 文档。
最常见的几个 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>
滚动还支持已滚动文件的压缩。将 .gz
、.zip
、.bz2
、.deflate
或 .pack200
中的一个作为后缀添加到 filePattern
属性中,将使文件使用相应的压缩方案进行压缩。
<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>
日志布局
日志文件可以通过多种不同的方式写入,这些方式被称为布局。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>
还有一些内置模板可从 classpath 中获得,例如
<JsonTemplateLayout eventTemplateUri="classpath:org/neo4j/logging/StructuredJsonLayout.json"/>
eventTemplateUri | 描述 |
---|---|
|
结构化日志消息的布局。仅适用于 query.log 和 security.log。 |
|
用于记录 JSON 消息的通用布局。可用于任何日志文件。 |
|
向后兼容的 JSON 布局,将匹配 Neo4j 4.x 查询日志。 |
|
|
|
Graylog 扩展日志格式 (GELF) 有效负载规范,带额外的 |
|
Google Cloud Platform 结构化日志记录,带额外的 |
|
与灵活性较低的 |
有关更多信息,请参见 Log4j 官方文档。
<Neo4jDebugLogLayout>
<Neo4jDebugLogLayout>
布局与 PatternLayout
基本相同。主要区别在于日志文件开头会注入一个包含对 Neo4j 开发者有用的诊断信息的头部。此布局通常仅用于 debug.log 文件。
<Neo4jDebugLogLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSSZ}{GMT+0} %-5p [%c{1.}] %m%n"/>
过滤器
您还可以配置过滤器以确定是否发布以及如何发布日志事件。详情请参见 Log4j 官方文档。
插件
您还可以通过将插件放入 plugin 目录来将它们添加到 Log4j。详情请参见 Log4j 官方插件文档。
Loggers
Loggers 将日志事件转发到 appenders。可以有任意数量的 <Logger>
元素,但只有一个 <Root>
logger 元素。Loggers 可以是叠加的。一个叠加的 logger 将日志事件转发到其 appender(s) 并将日志事件传递给下一个匹配的 logger。一个非叠加的 logger 将日志事件转发到其 appender(s) 然后丢弃该事件。根 logger 是一个特殊的 logger,它匹配所有内容,因此如果另一个 logger 没有捕获日志事件,根 logger 将会捕获。因此,最佳实践是始终包含一个根 logger,以确保不会遗漏任何日志事件。
<Configuration>
<!-- Appenders -->
<Loggers>
<Root level="WARN">
<AppenderRef ref="DebugLog"/>
</Root>
<Logger name="HttpLogger" level="INFO" additivity="false">
<AppenderRef ref="HttpLog"/>
</Logger>
</Loggers>
</Configuration>
logger 有一个 level
用于过滤日志事件。一个级别还可以包括不同严重程度的级别。例如,level="INFO"
的 logger 会转发 INFO
、WARN
和 ERROR
级别的日志事件。level="WARN"
的 logger 只会记录 WARN
和 ERROR
事件。
下表列出了 Neo4j 引发的所有日志级别及其严重性级别
消息类型 | 严重性级别 | 描述 |
---|---|---|
|
低严重性 |
报告引发错误的详细信息和可能的解决方案。 |
|
低严重性 |
报告状态信息和不严重的错误。 |
|
低严重性 |
报告需要关注但不严重的错误。 |
|
高严重性 |
报告阻止 Neo4j 服务器运行且必须立即解决的错误。 |
有关 loggers 的更多详细信息,请参见 Log4j 官方文档 → 配置 Loggers。
配置垃圾回收日志
垃圾回收日志,简称 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>
以下信息以 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
可用的值如下
选项 | 描述 |
---|---|
|
完全禁用日志记录。 |
|
在成功或失败的查询结束时记录日志。 |
|
默认记录所有查询的开始和结束,无论 |
查询日志记录的以下配置设置可用
查询日志配置 | 默认值 | 描述 | ||||
---|---|---|---|---|---|---|
|
记录查询文本和参数,不混淆密码。这允许在解析开始之前更早地记录查询。 |
|||||
|
记录已执行的查询。 |
|||||
|
此配置选项允许您设置日志中包含的最大参数长度。超过此长度的参数将被截断并附加 |
|||||
|
如果为
|
|||||
|
记录正在日志记录的已执行查询的参数。如果您不想显示敏感信息,可以禁用此配置设置。 |
|||||
|
此配置选项允许您记录每个查询的查询计划。查询计划以描述表的形式显示,对调试很有用。每次运行 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 毫秒
-
查询执行中花费的总累计实际时间。它是规划时间 + CPU + 等待时间 + 任何其他处理时间(例如,获取执行线程所需的时间)的总和。此数字是 CPU 线程每次执行查询时累积的。
规划
-
指 Cypher 引擎创建查询计划所需的时间。对于重复查询,计划可能会被缓存,因此,此类查询的规划时间将比以前未规划的查询短。在示例中,这为 1550 毫秒的总执行时间贡献了 20 毫秒。
CPU 时间
-
指执行查询的各个线程所花费的时间,例如,在 08:00 提交一个查询。它使用 CPU 720 毫秒,但随后 CPU 切换到另一个查询,因此第一个查询不再使用 CPU。然后,在 100 毫秒后,它再次获取/使用 CPU 200 毫秒(更多结果需要加载,由客户端通过驱动程序请求),然后查询在 08:01:30 完成,因此总持续时间为 1550 毫秒(包括两次往返的一些往返时间),CPU 时间为 720+200=920 毫秒。
等待
-
查询在执行前等待的时间(以毫秒为单位),例如,如果现有查询有一个锁,新查询必须等待该锁释放。在示例中,这为 1550 毫秒的总执行时间贡献了 10 毫秒。
重要的是要注意,客户端仅在其记录缓冲区为空时(从服务器进行一次往返可能最终得到多条记录)才从服务器请求数据,并且如果客户端没有及时读取传出缓冲区中的数据,服务器会停止将数据推送到传出缓冲区。因此,这取决于结果集的大小。如果它相对较小并适合一次往返,客户端会一次性接收所有结果,并且服务器完成处理而不会产生任何客户端副作用。同时,如果结果集很大,客户端处理时间将影响总时间,因为它直接与何时从服务器请求新数据相关。 13792 B
-
已执行查询的已记录分配字节。这是查询生命周期中使用的堆内存量。记录的数字是查询持续时间内的累积值,即,对于内存密集型或长时间运行的查询,该值可能大于当前内存分配。
15 页命中
-
页命中表示结果从页面缓存返回,而不是从磁盘返回。在这种情况下,页面缓存命中了 15 次。
0 页错误
-
页错误表示查询结果数据不在
dbms.memory.pagecache
中,因此必须从文件系统获取。在这种情况下,查询结果完全从上面提到的 8 次页面缓存命中返回,因此不需要进行 0 次磁盘命中。 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 浏览器指南中的 MovieGraph 数据集。
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 浏览器和 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>
JSON 格式日志条目
QueryLogJsonLayout.json
模板模仿 4.x 布局并包含以下信息
名称 | 描述 |
---|---|
|
日志消息的时间戳。 |
|
日志级别。 |
|
有效选项为 |
|
如果日志消息关联有堆栈跟踪,则包含此字段。 |
如果日志条目类型为 query
,则以下附加字段可用
名称 | 描述 |
---|---|
|
有效选项为 |
|
查询 ID。ID 是递增的,从 1 开始,并在每次 Neo4j 重启时重置。当 |
|
经过的时间(毫秒)。 |
|
花费在规划上的毫秒数。 |
|
CPU 上主动执行所花费的毫秒数。 |
|
等待锁或其他查询所花费的毫秒数,而不是主动运行此查询。 |
|
查询分配的字节数。 |
|
页命中数。 |
|
页错误数。 |
|
连接详情。 |
|
运行查询的数据库名称。如果查询无法解析并路由到数据库,此字段将为 |
|
执行查询的用户名。与 |
|
已验证身份并正在执行查询的用户名。 |
|
查询文本。 |
|
查询参数。当 |
|
运行查询所使用的运行时。 |
|
附加到事务的元数据。 |
|
失败原因。适用时包含。已被 |
|
GQL 错误信息以 JSON 对象形式提供。有关 |
|
正在运行查询的事务 ID。 |
|
查询计划。当 |
|
用于缓存执行计划的缓存键的 32 位哈希值。它是一个固定长度的 8 字符十六进制编码整数值字符串。默认仅在 JSON 格式中启用。如果多个查询执行使用相同的缓存执行计划,它们的哈希值应匹配。对于 |
|
查询字符串是否匹配缓存的执行计划。 |
|
Cypher 版本。 |
如果日志条目类型为 transaction
,则以下附加字段可用
名称 | 描述 |
---|---|
|
有效选项为 |
|
运行事务的数据库名称。 |
|
连接到事务的用户名称。与 |
|
已验证身份并连接到事务的用户名。 |
|
事务 ID。 |
GQL 错误信息
查询日志在 JSON 对象 errorInfo
下包含 GQL 错误信息。errorInfo
可以包含以下元素
-
GQLSTATUS
— 一个 5 个字符长的字母数字代码,用于标识错误。 -
statusDescription
— 描述错误的消息。 -
classification
— 表示客户端、瞬态和数据库错误分类的错误类型。 -
position
— 查询中发生此错误的位置(一个包含column
、offset
和line
字段的 JSON 对象)。 -
cause
— 一个 JSON 对象,包含当前errorInfo
JSON 对象的根源errorInfo
JSON 对象。
当异常没有 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",
...