Solr部署:日志配置与管理完整指南

Solr部署:日志配置与管理完整指南

Solr日志是了解系统状况的关键方式。有多种方法可以调整默认日志配置,满足不同场景的需求。本文将详细介绍Solr的日志配置和管理方法。

临时日志设置

在需要时有多种方法可以临时更改日志级别,无需重启Solr服务。

使用管理界面设置日志

您可以使用管理界面临时更改Solr的日志输出量。在左侧菜单中选择Logging链接。

注意:日志级别将在下次Solr重启时重置。

管理界面操作步骤

  1. 访问日志界面:点击管理界面左侧的”Logging”链接
  2. 选择日志级别:选择 Logging → Level 查看日志级别菜单
  3. 设置级别:点击右列的当前级别,出现日志级别菜单,选择所需级别

界面特点

  • 分层结构:Solr类在左列显示为表示类路径的目录树结构
  • 当前级别:右列显示当前级别
  • 级别继承:未设置的类别将具有其父级的日志级别
  • 批量设置:通过调整父级日志级别可以一次更改多个类别
  • 集群分发:日志级别更改将分发到集群中的所有节点

日志级别详解

级别 结果
ALL 报告所有内容
TRACE 报告除最不重要消息外的所有内容
DEBUG 报告配置错误
INFO 报告除正常状态外的所有内容
WARN 报告所有警告
ERROR 只报告最严重的警告
FATAL 只报告致命事件
OFF 关闭日志记录
UNSET 移除先前的日志设置

允许同时进行多个设置。

日志级别API

也可以通过向admin/info/logging端点发送REST命令来实现相同功能。

V1 API示例

1
curl -X GET "http://localhost:8983/solr/admin/info/logging?set=root:WARN"

V2 API示例

1
2
3
curl -X PUT http://localhost:8983/api/node/logging/levels \
-H 'Content-Type: application/json' \
-d '[{"logger": "root", "level": "WARN"}]'

批量设置示例

1
2
3
4
5
6
7
8
# 设置多个日志级别
curl -X PUT http://localhost:8983/api/node/logging/levels \
-H 'Content-Type: application/json' \
-d '[
{"logger": "org.apache.solr.core", "level": "DEBUG"},
{"logger": "org.apache.solr.search", "level": "INFO"},
{"logger": "org.apache.solr.update", "level": "WARN"}
]'

启动时选择日志级别

您可以在启动Solr时临时选择不同的日志级别,有两种方式:

方式一:环境变量

在启动Solr之前设置SOLR_LOG_LEVEL环境变量,或将相同变量放入bin/solr.in.shbin/solr.in.cmd。变量必须包含支持的日志级别的大写字符串。

1
2
3
4
5
6
# 设置环境变量
export SOLR_LOG_LEVEL=DEBUG
bin/solr start

# 或在配置文件中设置
echo "SOLR_LOG_LEVEL=INFO" >> bin/solr.in.sh

方式二:命令行选项

使用-v-q选项启动Solr:

1
2
3
4
5
# 以详细(DEBUG)日志启动
bin/solr start -f --verbose

# 以安静(WARN)日志启动
bin/solr start -f --quiet

永久日志设置

Solr使用Log4J version 2.x进行日志记录,通过server/resources/log4j2.xml进行配置。建议检查log4j2.xml文件的内容,以便熟悉其结构。

基本配置

默认日志文件位置

默认情况下,Solr日志消息将写入SOLR_LOGS_DIR/solr.log

生产环境配置

准备在生产环境中部署Solr时,设置变量SOLR_LOGS_DIR为您希望Solr写入日志文件的位置:

1
2
# 在solr.in.sh中设置
SOLR_LOGS_DIR="/var/solr/logs"

服务安装配置

如果使用生产环境部署指南中提供的说明将Solr作为服务安装,则应查看/var/solr/log4j2.xml而不是默认的server/resources版本。

日志格式配置

日志消息的格式可以通过修改<PatternLayout/>中使用的模式来更改,或通过更改布局实现 - 例如,可以使用<JsonTemplateLayout/>配置JSON格式的日志文件。

标准格式示例

1
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level (%thread) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n"/>

JSON格式示例

1
<JsonTemplateLayout eventTemplateUri="classpath:EcsLayout.json"/>

日志输出模式

前台运行

使用-f选项在前台启动Solr时,所有日志将发送到控制台和solr.log

后台运行

在后台启动Solr时,它会将所有stdoutstderr输出写入solr-<port>-console.log中的日志文件,并自动禁用log4j2.xml中配置的CONSOLE logger,效果与手动从rootLogger中删除CONSOLE appender相同。

日志轮换配置

应用日志轮换

如果生产服务器的默认日志轮换大小阈值32MB太小,则应将其增加到更大的值(如100MB或更多):

1
<SizeBasedTriggeringPolicy size="100 MB"/>

GC日志轮换

Java垃圾收集日志在大小达到20M时由JVM轮换,最多9代。

自动轮换

Solr每次启动或重启时,log4j2都会执行日志轮换。

完整log4j2.xml配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<!-- 控制台输出 -->
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level (%thread) %c{1.} %m%n"/>
</Console>

<!-- 文件输出 -->
<RollingFile name="MainLogFile" fileName="${sys:solr.log.dir}/solr.log"
filePattern="${sys:solr.log.dir}/solr.log.%i">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level (%thread) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>

<!-- 慢查询日志 -->
<RollingFile name="SlowFile" fileName="${sys:solr.log.dir}/solr_slow_requests.log"
filePattern="${sys:solr.log.dir}/solr_slow_requests.log.%i">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level (%thread) %c{1.} %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="50 MB"/>
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>
</Appenders>

<Loggers>
<!-- 特定组件日志级别 -->
<Logger name="org.apache.solr.update" level="INFO"/>
<Logger name="org.apache.solr.search" level="INFO"/>
<Logger name="org.apache.solr.core" level="INFO"/>

<!-- 慢查询日志 -->
<Logger name="org.apache.solr.core.SolrCore.SlowRequest" level="WARN" additivity="false">
<AppenderRef ref="SlowFile"/>
</Logger>

<Root level="INFO">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="MainLogFile"/>
</Root>
</Loggers>
</Configuration>

慢查询日志

对于高容量搜索应用程序,记录每个查询可能生成大量日志,并根据容量可能影响性能。

慢查询配置

如果您只关心与请求相关的警告和错误消息,可以将日志详细级别设置为WARN。但是,这带来了一个潜在问题,即您不知道是否有任何查询很慢,因为慢查询仍在INFO级别记录。

Solr提供了一种方法,可以将日志详细阈值设置为WARN,并能够设置延迟阈值,超过该阈值的请求被视为”慢”请求,并在WARN级别记录该请求,以帮助您识别应用程序中的慢查询。

solrconfig.xml配置

solrconfig.xmlquery部分配置<slowQueryThresholdMillis>元素:

1
<slowQueryThresholdMillis>1000</slowQueryThresholdMillis>

慢查询日志特点

  • 阈值控制:任何超过指定阈值的查询都将在WARN级别记录为”慢”查询
  • 独立文件:慢查询记录在solr_slow_requests.log文件中
  • 文件位置:位于SOLR_LOGS_DIR目录中

自定义慢查询配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 不同查询类型的不同阈值 -->
<requestHandler name="/select" class="solr.SearchHandler">
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
</lst>
<slowQueryThresholdMillis>2000</slowQueryThresholdMillis>
</requestHandler>

<requestHandler name="/browse" class="solr.SearchHandler">
<lst name="defaults">
<str name="echoParams">explicit</str>
</lst>
<slowQueryThresholdMillis>5000</slowQueryThresholdMillis>
</requestHandler>

记录选择请求参数

除了上述日志选项外,还可以使用名为logParamsList的附加请求参数仅记录选择的请求参数列表(如查询发送的参数)。

使用方法

1
2
3
4
5
# 只记录特定参数
curl "http://localhost:8983/solr/collection1/select?q=*:*&logParamsList=q,fq,sort"

# 记录所有参数
curl "http://localhost:8983/solr/collection1/select?q=*:*&logParamsList=*"

常用参数示例

1
2
3
4
5
6
7
8
# 搜索相关参数
logParamsList=q,fq,sort,start,rows,fl

# 分面相关参数
logParamsList=q,facet,facet.field,facet.query

# 高亮相关参数
logParamsList=q,hl,hl.fl,hl.simple.pre,hl.simple.post

SolrCore选择性日志

Solr使用o.a.s.c.SolrCore.Request在INFO级别记录所有核心请求。可以通过将这些logger的级别更改为WARN或ERROR来完全禁用此功能,或通过在log4j2.xml中对请求路径使用MarkerFilter来更有选择地禁用。

配置示例

1
2
3
4
5
6
7
<Logger name="org.apache.solr.core.SolrCore.Request" level="info">
<Filters>
<MarkerFilter marker="/get" onMatch="DENY" onMismatch="NEUTRAL"/>
<MarkerFilter marker="/replication" onMatch="DENY" onMismatch="NEUTRAL"/>
<MarkerFilter marker="/admin/ping" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
</Logger>

高级过滤配置

1
2
3
4
5
6
7
8
9
10
11
<!-- 根据查询类型过滤 -->
<Logger name="org.apache.solr.core.SolrCore.Request" level="info">
<Filters>
<!-- 忽略健康检查请求 -->
<MarkerFilter marker="/admin/ping" onMatch="DENY" onMismatch="NEUTRAL"/>
<!-- 忽略metrics请求 -->
<MarkerFilter marker="/admin/metrics" onMatch="DENY" onMismatch="NEUTRAL"/>
<!-- 忽略系统查询 -->
<RegexFilter regex=".*q=.*\*:\*.*rows=0.*" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
</Logger>

请求日志

每个传入的HTTP(s)请求默认以标准NCSA格式记录在名为$SOLR_LOG_DIR/<yyyy_mm_dd>.request.log的文件中,每天轮换。默认情况下,保留3天的请求日志。

请求日志配置

禁用请求日志

1
2
3
4
5
# 通过环境变量禁用
export SOLR_REQUESTLOG_ENABLED=false

# 或在配置文件中设置
echo "SOLR_REQUESTLOG_ENABLED=false" >> solr.in.sh

更改保留天数

1
2
# 保留7天的请求日志
-Dsolr.log.requestlog.retaindays=7

自定义请求日志格式

可以在Jetty配置中自定义请求日志格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- server/etc/jetty-requestlog.xml -->
<Set name="requestLog">
<New id="RequestLogImpl" class="org.eclipse.jetty.server.CustomRequestLog">
<Arg name="writer">
<New class="org.eclipse.jetty.server.RequestLogWriter">
<Arg name="filename"><Property name="solr.log.dir" default="." />/yyyy_mm_dd.request.log</Arg>
<Set name="filenameDateFormat">yyyy_MM_dd</Set>
<Set name="retainDays">7</Set>
<Set name="append">true</Set>
</New>
</Arg>
<Arg name="format">%{client}a - %u %t "%r" %s %O "%{Referer}i" "%{User-Agent}i" %D</Arg>
</New>
</Set>

生产环境最佳实践

1. 日志级别策略

分层级别设置

1
2
3
4
5
6
7
8
# 生产环境推荐日志级别
ROOT: INFO
org.apache.solr.core: INFO
org.apache.solr.search: INFO
org.apache.solr.update: WARN
org.apache.solr.handler: INFO
org.apache.solr.cloud: INFO
org.apache.zookeeper: WARN

调试时临时调整

1
2
3
4
# 临时开启DEBUG级别调试特定问题
curl -X PUT http://localhost:8983/api/node/logging/levels \
-H 'Content-Type: application/json' \
-d '[{"logger": "org.apache.solr.search.SolrIndexSearcher", "level": "DEBUG"}]'

2. 日志文件管理

目录结构规划

1
2
3
4
5
6
7
/var/solr/logs/
├── solr.log # 主日志文件
├── solr.log.1 # 轮换的日志文件
├── solr_slow_requests.log # 慢查询日志
├── 2025_04_13.request.log # 请求日志
├── solr-8983-console.log # 控制台输出
└── gc.log # GC日志

自动清理脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
# solr-log-cleanup.sh

LOG_DIR="/var/solr/logs"
DAYS_TO_KEEP=7

# 清理旧的应用日志
find $LOG_DIR -name "solr.log.*" -mtime +$DAYS_TO_KEEP -delete

# 清理旧的请求日志
find $LOG_DIR -name "*.request.log" -mtime +$DAYS_TO_KEEP -delete

# 清理旧的GC日志
find $LOG_DIR -name "gc.log.*" -mtime +$DAYS_TO_KEEP -delete

# 压缩较大的日志文件
find $LOG_DIR -name "*.log" -size +100M -not -name "solr.log" -exec gzip {} \;

echo "Log cleanup completed on $(date)"

3. 监控和告警

日志监控脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/bash
# solr-log-monitor.sh

LOG_FILE="/var/solr/logs/solr.log"
ERROR_THRESHOLD=10
WARN_THRESHOLD=50

# 检查错误数量
ERROR_COUNT=$(grep -c "ERROR" $LOG_FILE)
WARN_COUNT=$(grep -c "WARN" $LOG_FILE)

if [ $ERROR_COUNT -gt $ERROR_THRESHOLD ]; then
echo "ALERT: High error count: $ERROR_COUNT errors found"
# 发送告警
grep "ERROR" $LOG_FILE | tail -5
fi

if [ $WARN_COUNT -gt $WARN_THRESHOLD ]; then
echo "WARNING: High warning count: $WARN_COUNT warnings found"
fi

# 检查OutOfMemoryError
if grep -q "OutOfMemoryError" $LOG_FILE; then
echo "CRITICAL: OutOfMemoryError detected"
fi

# 检查磁盘空间不足
if grep -q "No space left" $LOG_FILE; then
echo "CRITICAL: Disk space issue detected"
fi

Logstash配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# logstash-solr.conf
input {
file {
path => "/var/solr/logs/solr.log"
start_position => "beginning"
codec => multiline {
pattern => "^\d{4}-\d{2}-\d{2}"
negate => true
what => "previous"
}
}
}

filter {
grok {
match => {
"message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} \(%{DATA:thread}\) \[%{DATA:collection} %{DATA:shard} %{DATA:replica} %{DATA:core}\] %{DATA:class} %{GREEDYDATA:log_message}"
}
}

date {
match => [ "timestamp", "yyyy-MM-dd HH:mm:ss.SSS" ]
}
}

output {
elasticsearch {
hosts => ["localhost:9200"]
index => "solr-logs-%{+YYYY.MM.dd}"
}
}

4. 性能优化

异步日志配置

1
2
3
4
<!-- 启用异步日志提升性能 -->
<AsyncLogger name="org.apache.solr" level="INFO" additivity="false">
<AppenderRef ref="MainLogFile"/>
</AsyncLogger>

缓冲配置

1
2
3
4
5
6
7
8
9
<RollingFile name="MainLogFile" fileName="${sys:solr.log.dir}/solr.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %c{1.} %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
<!-- 添加缓冲提升性能 -->
<bufferSize>8192</bufferSize>
</RollingFile>

5. 故障排查工具

日志分析脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/bin/bash
# solr-log-analysis.sh

LOG_FILE="/var/solr/logs/solr.log"

echo "=== Solr Log Analysis Report ==="
echo "Analysis time: $(date)"
echo ""

# 错误统计
echo "Error Summary:"
grep "ERROR" $LOG_FILE | cut -d' ' -f6- | sort | uniq -c | sort -rn | head -10

echo ""

# 警告统计
echo "Warning Summary:"
grep "WARN" $LOG_FILE | cut -d' ' -f6- | sort | uniq -c | sort -rn | head -10

echo ""

# 慢查询统计
echo "Slow Query Summary:"
if [ -f "/var/solr/logs/solr_slow_requests.log" ]; then
wc -l /var/solr/logs/solr_slow_requests.log
echo "Recent slow queries:"
tail -5 /var/solr/logs/solr_slow_requests.log
fi

echo ""

# JVM内存使用
echo "Memory Usage Patterns:"
grep -i "memory\|gc\|heap" $LOG_FILE | tail -5

echo ""

# 最近的重要事件
echo "Recent Important Events:"
grep -E "(Starting|Stopping|ERROR|WARN)" $LOG_FILE | tail -10

总结

通过本指南,您应该能够全面掌握Solr的日志配置和管理。关键要点包括:

  1. 灵活的日志级别控制:支持临时和永久的日志级别调整
  2. 慢查询监控:配置慢查询阈值,识别性能问题
  3. 选择性日志记录:通过过滤器控制特定请求的日志记录
  4. 完善的轮换机制:自动管理日志文件大小和数量
  5. 生产环境优化:合理的日志级别、存储和清理策略

在生产环境中,建议:

  • 设置合适的日志级别,平衡信息完整性和性能
  • 配置日志轮换和自动清理,避免磁盘空间问题
  • 建立日志监控和告警机制,及时发现问题
  • 使用日志分析工具,深入了解系统运行状况

良好的日志配置是Solr运维的基础,能够显著提升问题排查效率和系统可维护性。

© 2025 Solr Community of China All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero