在管理多个 SaaS 项目或 WordPress 站点时,手动配置每个项目的日志采集既低效又容易出错。本文将分享如何通过 Redis 作为中间层,利用 Logstash 动态索引 和 Elasticsearch 索引模板,实现一套“零维护”的通用日志采集方案。
1. 核心设计思路
- Redis:作为消息队列,每个项目拥有独立的 Key(如
project_a:logs)。
- Logstash:监听多个 Redis Key,根据来源或 JSON 内容动态生成索引名称。
- Elasticsearch:预设索引模板,匹配所有日志索引并绑定 ILM(生命周期管理) 策略,实现 7 天自动删除。
2. Elasticsearch 配置:自动化与清理策略
首先,我们需要在 Elasticsearch 中创建一个模板。这个模板的作用是:只要新创建的索引名字包含 -logs-,就自动设置分片数为 1,并绑定 7 天删除策略。
步骤 A:创建 7 天删除策略 (ILM)
在 Kibana 的 Dev Tools 中执行:
HTTP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 设定一个7天删除的规则
PUT _ilm/policy/delete-after-7-days
{
"policy": {
"phases": {
"hot": {
"actions": {
"set_priority": {
"priority": 100
}
}
},
"delete": {
"min_age": "7d",
"actions": {
"delete": {}
}
}
}
}
}
|
步骤 B:创建通用索引模板
将所有项目的匹配规则合并到一个模板中。
HTTP
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
|
PUT _index_template/universal-logs-template
{
# "index_patterns": ["*-logs-*"],
"index_patterns": [
"sms-logs-*",
"wordpress-logs-*",
],
"priority": 200,
"template": {
"settings": {
"index": {
"lifecycle": {
"name": "delete-after-7-days"
},
"mode": "standard",
"number_of_shards": "1"
}
},
"mappings": {
"properties": {
"msg": { "type": "text" },
"@timestamp": { "type": "date" },
"level": { "type": "keyword" },
"project": { "type": "keyword" },
"env": { "type": "text" },
"timestamp": { "type": "date" }
}
}
}
}
|
3. Logstash 配置:多项目动态采集
由于部分 Logstash 插件版本不支持在 Redis Key 中使用通配符,我们采用**多输入块(Multiple Inputs)**的方案。这种方式最稳妥,且能精确控制每个项目的 project 标签。
修改 logstash.conf:
Ruby
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
47
48
49
50
51
52
53
|
input {
# 项目 1: bhgoods
redis {
host => "localhost"
port => 6379
password => "your_redis_password"
data_type => "list"
key => "bhgoods:logs"
codec => "json"
add_field => { "project_name" => "bhgoods" }
}
# 项目 2: wpcollege
redis {
host => "localhost"
port => 6379
password => "your_redis_password"
data_type => "list"
key => "wpcollege:logs"
codec => "json"
add_field => { "project_name" => "wpcollege" }
}
}
filter {
# 逻辑:优先使用 JSON 里的 project,若无则使用 add_field 定义的项目名
if ![project] {
mutate {
copy => { "project_name" => "project" }
}
}
# 标准化时间戳:将业务日志里的 datetime 转换为 ES 识别的 @timestamp
if [datetime] {
date {
match => ["datetime", "ISO8601"]
target => "@timestamp"
}
}
}
output {
elasticsearch {
hosts => ["http://your-elasticsearch-url:9200"]
# 动态索引名称:项目名-logs-日期
index => "%{project}-logs-%{+YYYY.MM.dd}"
user => "logstash_writer"
password => "your_password"
}
# 调试模式:建议在博客测试阶段开启,确认 project 字段正确
stdout { codec => rubydebug }
}
|
4. 常用维护与排查命令 (Cheatsheet)
在实际运维中,你可能需要清理旧配置或手动修复索引状态。
模板与索引管理
HTTP
1
2
3
4
5
6
7
8
9
10
11
|
# 删除旧的冗余模板
DELETE _index_template/wpcollege-logs-template
# 查看特定项目的索引列表及创建时间
GET /_cat/indices/oms-logs-*?h=index,creation.date.string
# 查看特定索引是否成功绑定了生命周期策略
GET kongfumall-api-logs-*/_settings?filter_path=*.settings.index.lifecycle
# 查看单个索引的详细信息(如特定日期的索引)
GET _cat/indices/wms-logs-2025.12.18?v
|
手动修复生命周期 (ILM)
如果某些索引创建时没带上策略,或者你想更换策略:
HTTP
1
2
3
4
5
6
7
8
9
10
11
|
# 1. 先移除现有的 ILM 策略
POST wpcollege-logs-*/_ilm/remove
# 2. 重新强制绑定 7 天删除策略
PUT wpcollege-logs-*/_settings
{
"index.lifecycle.name": "delete-after-7-days"
}
# 3. 查看 ILM 执行状态(如果没删除,看这里为什么报错)
GET wpcollege-logs-*/_ilm/explain
|
5. 验证与运维
- 重启 Logstash:查看控制台输出,确认
project 字段是否显示为预期的 bhgoods 或 wpcollege。
- 检查索引生成:在 Elasticsearch 中执行
GET _cat/indices/*-logs-*?v,你应该能看到类似 bhgoods-logs-2026.03.11 的索引已创建。
- 确认生命周期管理:在 Kibana 的 Index Management 中,检查新索引是否已正确关联
delete-after-7-days 策略。
6. 总结
通过这种方案,你实现了:
- 解耦:新增项目只需在 Logstash 的
input 增加几行配置,无需改动全局逻辑。
- 自动化:Elasticsearch 模板确保了所有新索引自动具备清理机制,防止磁盘撑爆。
- 规范化:通过
project 字段在 Kibana 中轻松实现多租户日志隔离查询。
如果你觉得这篇教程有帮助,欢迎在评论区留言讨论!