Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a6517ff
[feature:redis-slowlog] add redis slow query monitor; update doc for …
YxYL6125 Jun 18, 2025
fc050f9
[feature:redis-slowlog] fix doc format
YxYL6125 Jun 19, 2025
6dbe833
[feature:redis-slowlog] fix ut
YxYL6125 Jun 19, 2025
e1293d4
Merge branch 'master' into feature-redis-slowlog
YxYL6125 Jun 19, 2025
03dbbea
[feature:redis-slowlog] fix ut
YxYL6125 Jun 19, 2025
9d05478
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 19, 2025
cc331cb
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 19, 2025
6a3c2cf
Merge branch 'master' into feature-redis-slowlog
YxYL6125 Jun 20, 2025
6a74662
[feature:redis-slowlog] fix e2e test
YxYL6125 Jun 20, 2025
b57544b
Merge remote-tracking branch 'origin/feature-redis-slowlog' into feat…
YxYL6125 Jun 20, 2025
47d252c
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 20, 2025
e88235a
Merge branch 'master' into feature-redis-slowlog
tomsun28 Jun 21, 2025
4615edd
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 21, 2025
7b40217
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 21, 2025
1b15af5
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 22, 2025
c74b485
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 23, 2025
ab54a72
Merge branch 'master' into feature-redis-slowlog
Calvin979 Jun 23, 2025
b3f7cde
Merge branch 'master' into feature-redis-slowlog
lynx009 Jun 24, 2025
d0dbb4f
[feature:redis-slowlog] add more log for e2e test
YxYL6125 Jun 25, 2025
b069fc5
Merge branch 'master' into feature-redis-slowlog
YxYL6125 Jun 25, 2025
0d09107
Merge branch 'master' into feature-redis-slowlog
YxYL6125 Jun 26, 2025
687d13d
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 27, 2025
36073f8
Merge branch 'master' into feature-redis-slowlog
Calvin979 Jun 27, 2025
d161cd9
Merge branch 'master' into feature-redis-slowlog
YxYL6125 Jun 28, 2025
309ec86
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 28, 2025
8d15452
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 28, 2025
077e98b
Merge branch 'master' into feature-redis-slowlog
Calvin979 Jun 29, 2025
a168472
Merge branch 'master' into feature-redis-slowlog
Aias00 Jun 29, 2025
5996844
Merge branch 'master' into feature-redis-slowlog
Aias00 Jul 1, 2025
a97ba1e
Merge branch 'master' into feature-redis-slowlog
Aias00 Jul 1, 2025
ddf2176
Merge branch 'master' into feature-redis-slowlog
Aias00 Jul 2, 2025
cff87cd
Merge branch 'master' into feature-redis-slowlog
tomsun28 Jul 6, 2025
0e1e36a
Merge branch 'master' into feature-redis-slowlog
Aias00 Jul 10, 2025
9d77751
Merge branch 'master' into feature-redis-slowlog
yuluo-yx Jul 12, 2025
d57c1a3
Merge branch 'master' into feature-redis-slowlog
tomsun28 Aug 9, 2025
94be138
Merge branch 'master' into feature-redis-slowlog
tomsun28 Sep 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.collector.collect.common.cache.AbstractConnection;
Expand Down Expand Up @@ -71,6 +72,8 @@ public class RedisCommonCollectImpl extends AbstractCollect {

private static final String UNIQUE_IDENTITY = "identity";

private static final String SLOW_LOG = "slowlog";

private final ClientResources defaultClientResources;
private final GlobalConnectionCache connectionCache = GlobalConnectionCache.getInstance();

Expand All @@ -90,7 +93,15 @@ public void preCheck(Metrics metrics) throws IllegalArgumentException{
@Override
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
try {
if (Objects.nonNull(metrics.getRedis().getPattern()) && Objects.equals(metrics.getRedis().getPattern(), CLUSTER)) {
if (Objects.equals(metrics.getName(), SLOW_LOG)) {
if (Objects.nonNull(metrics.getRedis().getPattern()) && Objects.equals(metrics.getRedis().getPattern(), CLUSTER)) {
List<Map<String, String>> redisSlowLogList = getClusterRedisSlowLog(metrics);
doMetricsDataList(builder, redisSlowLogList, metrics);
} else {
List<Map<String, String>> redisSlowLog = getSingleRedisSlowLog(metrics);
doMetricsDataList(builder, redisSlowLog, metrics);
}
} else if (Objects.nonNull(metrics.getRedis().getPattern()) && Objects.equals(metrics.getRedis().getPattern(), CLUSTER)) {
List<Map<String, String>> redisInfoList = getClusterRedisInfo(metrics);
doMetricsDataList(builder, redisInfoList, metrics);
} else {
Expand Down Expand Up @@ -371,4 +382,93 @@ public String supportProtocol() {
return DispatchConstants.PROTOCOL_REDIS;
}

/**
* Get slow log data from a single Redis instance
* @param metrics metrics config
* @return data
*/
private List<Map<String, String>> getSingleRedisSlowLog(Metrics metrics) throws GeneralSecurityException, IOException {
StatefulRedisConnection<String, String> connection = getSingleConnection(metrics.getRedis());
// Get the last 100 slow logs by default
List<Object> slowLogs = connection.sync().slowlogGet(100);

return parseSlowLogs(slowLogs);
}

/**
* Get slow log data from Redis cluster nodes
* @param metrics metrics config
* @return data
*/
private List<Map<String, String>> getClusterRedisSlowLog(Metrics metrics) throws GeneralSecurityException, IOException {
Map<String, StatefulRedisClusterConnection<String, String>> connectionMap = getConnectionList(metrics.getRedis());
List<Map<String, String>> allSlowLogs = new ArrayList<>();

connectionMap.forEach((identity, connection) -> {
// Get the last 100 slow logs by default
List<Object> slowLogs = connection.sync().slowlogGet(100);
List<Map<String, String>> parsedLogs = parseSlowLogs(slowLogs);

// Add node identity to each log entry
parsedLogs.forEach(log -> log.put(UNIQUE_IDENTITY, identity));

allSlowLogs.addAll(parsedLogs);
});

return allSlowLogs;
}

/**
* Parse Redis slow log response into a list of maps
* @param slowLogs raw slow log data from Redis
* @return parsed slow logs
*/
private List<Map<String, String>> parseSlowLogs(List<Object> slowLogs) {
List<Map<String, String>> result = new ArrayList<>();

if (Objects.isNull(slowLogs) || slowLogs.isEmpty()) {
return result;
}

for (Object entry : slowLogs) {
if (entry instanceof List) {
List<?> logEntry = (List<?>) entry;
if (logEntry.size() >= 4) {
Map<String, String> logMap = new HashMap<>();

// ID
logMap.put("id", String.valueOf(logEntry.get(0)));

// Timestamp
logMap.put("timestamp", String.valueOf(logEntry.get(1)));

// Execution time in microseconds
logMap.put("execution_time", String.valueOf(logEntry.get(2)));

// Command and arguments
if (logEntry.get(3) instanceof List) {
List<?> cmdArgs = (List<?>) logEntry.get(3);
String command = cmdArgs.stream()
.map(String::valueOf)
.collect(Collectors.joining(" "));
logMap.put("command", command);
}

// Client IP and name (if available)
if (logEntry.size() > 4 && logEntry.get(4) instanceof String) {
logMap.put("client_ip", String.valueOf(logEntry.get(4)));
}

if (logEntry.size() > 5 && logEntry.get(5) instanceof String) {
logMap.put("client_name", String.valueOf(logEntry.get(5)));
}

result.add(logMap);
}
}
}

return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class RedisCommonCollectE2eTest extends AbstractCollectE2eTest {
private static final String HOST = "127.0.0.1";
private static final int REDIS_PORT = 6379;
private static final String REDIS_PATTERN = "1";
private static final List<String> ALLOW_EMPTY_WHITE_LIST = Arrays.asList("server", "errorstats", "commandstats", "keyspace");
private static final List<String> ALLOW_EMPTY_WHITE_LIST = Arrays.asList("server", "errorstats", "commandstats", "keyspace", "slowlog");

private static GenericContainer<?> redisContainer;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ protected CollectRep.MetricsData validateMetricsCollection(Metrics metricsDef, S
String.format("%s metrics values should not be empty, detail: %s", metricName, metricsData.getMsg()));

for (CollectRep.ValueRow valueRow : metricsData.getValuesList()) {
log.info("valueRow: {}", valueRow);
for (int i = 0; i < valueRow.getColumnsCount(); i++) {
log.info("valueRow.getColumns(i): {}", valueRow.getColumns(i));
Assertions.assertFalse(valueRow.getColumns(i).isEmpty(),
String.format("%s metric column %d should not be empty", metricName, i));
if (!allowEmpty) {
Expand Down
58 changes: 58 additions & 0 deletions hertzbeat-manager/src/main/resources/define/app-redis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1656,3 +1656,61 @@ metrics:
privateKey: ^_^sshPrivateKey^_^
privateKeyPassphrase: ^_^sshPrivateKeyPassphrase^_^
shareConnection: ^_^sshShareConnection^_^

# metrics - slowlog
- name: slowlog
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
priority: 9
i18n:
zh-CN: 慢查询日志
en-US: Slow Query Log
# collect metrics content
fields:
- field: id
type: 0
i18n:
zh-CN: ID
en-US: ID
- field: timestamp
type: 0
i18n:
zh-CN: 时间戳
en-US: Timestamp
- field: execution_time
type: 0
unit: μs
i18n:
zh-CN: 执行时间
en-US: Execution Time
- field: command
type: 1
i18n:
zh-CN: 命令
en-US: Command
- field: client_ip
type: 1
i18n:
zh-CN: 客户端IP
en-US: Client IP
- field: client_name
type: 1
i18n:
zh-CN: 客户端名称
en-US: Client Name
protocol: redis
redis:
host: ^_^host^_^
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
timeout: ^_^timeout^_^
sshTunnel:
enable: ^_^enableSshTunnel^_^
host: ^_^sshHost^_^
port: ^_^sshPort^_^
timeout: ^_^sshTimeout^_^
username: ^_^sshUsername^_^
password: ^_^sshPassword^_^
privateKey: ^_^sshPrivateKey^_^
privateKeyPassphrase: ^_^sshPrivateKeyPassphrase^_^
shareConnection: ^_^sshShareConnection^_^
17 changes: 17 additions & 0 deletions home/docs/help/redis.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,20 @@ keywords: [ open source monitoring tool, open source Redis monitoring tool, moni
| cmdstat_lpop | none | lpop command stat |
| cmdstat_rpop | none | rpop command stat |
| cmdstat_llen | none | llen command stat |

#### Metric set:slowlog

| Metric name | Metric unit | Metric help description |
|---------------------------|----------|-----------------------------------------------------------------------------------------------|
| id | none | Unique progressive identifier for every slow log entry |
| timestamp | none | Unix timestamp at which the logged command was processed |
| execution_time | μs | The amount of time needed for its execution, in microseconds |
| command | none | The command and its arguments |
| client_ip | none | Client IP address (available for Redis 4.0 or higher) |
| client_name | none | Client name if set via the CLIENT SETNAME command (available for Redis 4.0 or higher) |

> Note: To configure Redis slow log settings, use the following Redis commands:
>
> - `CONFIG SET slowlog-log-slower-than 10000` - Log commands that take longer than 10,000 microseconds (10ms)
> - `CONFIG SET slowlog-max-len 128` - Keep the last 128 slow log entries
> - The slow log metrics are displayed in real-time and updated automatically.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ sidebar_label: Redis 数据库
keywords: [开源监控系统, 开源数据库监控, Redis数据库监控]
---

> 对REDIS数据库的通用性能指标进行采集监控。支持REDIS1.0+。
> 对REDIS数据库的通用性能指标(包括慢查询日志)进行采集监控。支持REDIS1.0+。

### 配置参数

Expand Down Expand Up @@ -237,3 +237,20 @@ keywords: [开源监控系统, 开源数据库监控, Redis数据库监控]
| cmdstat_lpop | 无 | lpop命令的统计信息 |
| cmdstat_rpop | 无 | rpop命令的统计信息 |
| cmdstat_llen | 无 | llen命令的统计信息 |

#### 指标集合:slowlog

| 指标名称 | 指标单位 | 指标帮助描述 |
|---------------------------|----------|-----------------------------------------------------------------------------------------------|
| id | 无 | 慢查询日志的唯一递增标识符 |
| timestamp | 无 | 记录命令被处理时的Unix时间戳 |
| execution_time | μs | 命令执行所需的时间(微秒) |
| command | 无 | 执行的命令及其参数 |
| client_ip | 无 | 客户端IP地址(Redis 4.0或更高版本可用) |
| client_name | 无 | 客户端名称,如果通过CLIENT SETNAME命令设置(Redis 4.0或更高版本可用) |

> 注意:要配置Redis慢查询日志设置,请使用以下Redis命令:
>
> - `CONFIG SET slowlog-log-slower-than 10000` - 记录执行时间超过10,000微秒(10毫秒)的命令
> - `CONFIG SET slowlog-max-len 128` - 保留最近128条慢查询日志条目
> - 慢查询日志指标会实时显示并自动更新。
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ sidebar_label: Redis 数据库
keywords: [开源监控系统, 开源数据库监控, Redis数据库监控]
---

> 对REDIS数据库的通用性能指标进行采集监控。支持REDIS1.0+。
> 对REDIS数据库的通用性能指标(包括慢查询日志)进行采集监控。支持REDIS1.0+。

### 配置参数

Expand Down Expand Up @@ -237,3 +237,20 @@ keywords: [开源监控系统, 开源数据库监控, Redis数据库监控]
| cmdstat_lpop | 无 | lpop命令的统计信息 |
| cmdstat_rpop | 无 | rpop命令的统计信息 |
| cmdstat_llen | 无 | llen命令的统计信息 |

#### 指标集合:slowlog

| 指标名称 | 指标单位 | 指标帮助描述 |
|---------------------------|----------|-----------------------------------------------------------------------------------------------|
| id | 无 | 慢查询日志的唯一递增标识符 |
| timestamp | 无 | 记录命令被处理时的Unix时间戳 |
| execution_time | μs | 命令执行所需的时间(微秒) |
| command | 无 | 执行的命令及其参数 |
| client_ip | 无 | 客户端IP地址(Redis 4.0或更高版本可用) |
| client_name | 无 | 客户端名称,如果通过CLIENT SETNAME命令设置(Redis 4.0或更高版本可用) |

> 注意:要配置Redis慢查询日志设置,请使用以下Redis命令:
>
> - `CONFIG SET slowlog-log-slower-than 10000` - 记录执行时间超过10,000微秒(10毫秒)的命令
> - `CONFIG SET slowlog-max-len 128` - 保留最近128条慢查询日志条目
> - 慢查询日志指标会实时显示并自动更新。
19 changes: 18 additions & 1 deletion home/versioned_docs/version-v1.6.x/help/redis.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ sidebar_label: REDIS
keywords: [ open source monitoring tool, open source Redis monitoring tool, monitoring Redis metrics ]
---

> Collect and monitor the general performance Metrics of Redis database. Support REDIS1.0+.
> Collect and monitor the general performance Metrics of Redis database including slow query logs. Support REDIS1.0+.

### Configuration parameter

Expand Down Expand Up @@ -232,3 +232,20 @@ keywords: [ open source monitoring tool, open source Redis monitoring tool, moni
| cmdstat_lpop | none | lpop command stat |
| cmdstat_rpop | none | rpop command stat |
| cmdstat_llen | none | llen command stat |

#### Metric set:slowlog

| Metric name | Metric unit | Metric help description |
|---------------------------|----------|-----------------------------------------------------------------------------------------------|
| id | none | Unique progressive identifier for every slow log entry |
| timestamp | none | Unix timestamp at which the logged command was processed |
| execution_time | μs | The amount of time needed for its execution, in microseconds |
| command | none | The command and its arguments |
| client_ip | none | Client IP address (available for Redis 4.0 or higher) |
| client_name | none | Client name if set via the CLIENT SETNAME command (available for Redis 4.0 or higher) |

> Note: To configure Redis slow log settings, use the following Redis commands:
>
> - `CONFIG SET slowlog-log-slower-than 10000` - Log commands that take longer than 10,000 microseconds (10ms)
> - `CONFIG SET slowlog-max-len 128` - Keep the last 128 slow log entries
> - The slow log metrics are displayed in real-time and updated automatically.
Loading