Skip to content

Commit

Permalink
[monitor] feature: support redis monitor protocol (apache#142)
Browse files Browse the repository at this point in the history
* [manager]feature: refactor DispatchAlarm

* [alerter]bugfix nextEvalInterval npe

* [monitor] 支持Redis监控类型

* [monitor] Redis监控类型参数校验

Co-authored-by: Musk.Chen <[email protected]>
Co-authored-by: tomsun28 <[email protected]>
  • Loading branch information
3 people authored May 22, 2022
1 parent 58f14d9 commit 6b02af0
Show file tree
Hide file tree
Showing 8 changed files with 692 additions and 1 deletion.
5 changes: 5 additions & 0 deletions collector/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@
<artifactId>orai18n</artifactId>
<version>21.5.0.0</version>
</dependency>
<!--redis-->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.usthe.collector.collect.redis;

import com.usthe.collector.collect.AbstractCollect;
import com.usthe.collector.collect.common.cache.CommonCache;
import com.usthe.common.entity.job.Metrics;
import com.usthe.common.entity.job.protocol.RedisProtocol;
import com.usthe.common.entity.message.CollectRep;
import com.usthe.common.util.CommonConstants;
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
* Redis 单机指标收集器
*
* @author <a href="mailto:[email protected]">Musk.Chen</a>
* @version 1.0
* Created by Musk.Chen on 2022/5/17
*/
@Slf4j
public class RedisSingleCollectImpl extends AbstractCollect {

public static RedisSingleCollectImpl getInstance() {
return RedisSingleCollectImpl.Singleton.INSTANCE;
}

@Override
public void collect(CollectRep.MetricsData.Builder builder, long appId, String app, Metrics metrics) {
preCheck(metrics);
RedisClient redisClient = buildClient(metrics.getRedis());

StatefulRedisConnection<String, String> connection = redisClient.connect();

String info = connection.sync().info();
Map<String, String> valueMap = parseInfo(info);
if (log.isDebugEnabled()) {
log.debug("[RedisSingleCollectImpl] fetch redis info");
valueMap.forEach((k, v) -> log.debug("{} : {}", k, v));
}
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
metrics.getAliasFields().forEach(it -> {
if (valueMap.containsKey(it)) {
String fieldValue = valueMap.get(it);
if (fieldValue == null) {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
} else {
valueRowBuilder.addColumns(fieldValue);
}
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
});
builder.addValues(valueRowBuilder.build());

connection.closeAsync();
}

/**
* pre check params
*/
private void preCheck(Metrics metrics) {
if (metrics == null || metrics.getRedis() == null) {
throw new IllegalArgumentException("Redis collect must has redis params");
}
RedisProtocol redisProtocol = metrics.getRedis();
Assert.hasText(redisProtocol.getHost(), "Redis Protocol host is required.");
Assert.hasText(redisProtocol.getPort(), "Redis Protocol port is required.");
}

/**
* build single redis client
*
* @param redisProtocol redis protocol config
* @return redis single client
*/
private RedisClient buildClient(RedisProtocol redisProtocol) {
String uri = String.format("redis://%s:%d", redisProtocol.getHost(), Integer.parseInt(redisProtocol.getPort()));
CommonCache commonCache = CommonCache.getInstance();
return commonCache.getCache(uri, true)
.map(r -> (RedisClient) r)
.orElseGet(() -> {
// create new redis client
RedisClient redisClient = RedisClient.create(uri);
commonCache.addCache(uri, redisClient);
return redisClient;
});
}

/**
* parse redis info
*
* @param info redis info
* @return parsed redis info
*/
private Map<String, String> parseInfo(String info) {
String[] lines = info.split("\n");
Map<String, String> result = new HashMap<>();
Arrays.stream(lines)
.filter(it -> StringUtils.hasText(it) && !it.startsWith("#") && it.contains(":"))
.map(this::removeCR)
.map(r -> r.split(":"))
.forEach(it -> {
if (it.length > 1) {
result.put(it[0], it[1]);
}
});
return result;
}

private String removeCR(String value) {
return value.replace("\r", "");
}

private static class Singleton {
private static final RedisSingleCollectImpl INSTANCE = new RedisSingleCollectImpl();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public interface DispatchConstants {
* protocol 协议 ssh
*/
String PROTOCOL_SSH = "ssh";
/**
* protocol 协议 ssh
*/
String PROTOCOL_REDIS = "redis";
// Protocol type related - end
// 协议类型相关 - end //

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.usthe.collector.collect.database.JdbcCommonCollect;
import com.usthe.collector.collect.http.HttpCollectImpl;
import com.usthe.collector.collect.icmp.IcmpCollectImpl;
import com.usthe.collector.collect.redis.RedisSingleCollectImpl;
import com.usthe.collector.collect.ssh.SshCollectImpl;
import com.usthe.collector.collect.telnet.TelnetCollectImpl;
import com.usthe.collector.dispatch.timer.Timeout;
Expand Down Expand Up @@ -134,7 +135,9 @@ public void run() {
case DispatchConstants.PROTOCOL_SSH:
abstractCollect = SshCollectImpl.getInstance();
break;
// todo
case DispatchConstants.PROTOCOL_REDIS:
abstractCollect = RedisSingleCollectImpl.getInstance();
// todo
default:
break;
}
Expand Down
7 changes: 7 additions & 0 deletions common/src/main/java/com/usthe/common/entity/job/Metrics.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.usthe.common.entity.job.protocol.HttpProtocol;
import com.usthe.common.entity.job.protocol.IcmpProtocol;
import com.usthe.common.entity.job.protocol.JdbcProtocol;
import com.usthe.common.entity.job.protocol.RedisProtocol;
import com.usthe.common.entity.job.protocol.SshProtocol;
import com.usthe.common.entity.job.protocol.TcpUdpProtocol;
import com.usthe.common.entity.job.protocol.TelnetProtocol;
Expand Down Expand Up @@ -96,6 +97,12 @@ public class Metrics {
*/
private SshProtocol ssh;

/**
* Monitoring configuration information using the public redis protocol
* 使用公共的redis协议的监控配置信息
*/
private RedisProtocol redis;

@Override
public boolean equals(Object o) {
if (this == o) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.usthe.common.entity.job.protocol;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* @author <a href="mailto:[email protected]">Musk.Chen</a>
* @version 1.0
* Created by Musk.Chen on 2022/5/17
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RedisProtocol {

/**
* 对端主机ip或域名
*/
private String host;

/**
* 端口号
*/
private String port;

/**
* Redis用户名(可选)
*/
private String username;

/**
* Redis密码(可选)
*/
private String password;

/**
* 超时时间
*/
private String timeout;

}
Loading

0 comments on commit 6b02af0

Please sign in to comment.