Skip to content

Commit

Permalink
[monitor] support jmx protocol, add tomcat monitor type (#239)
Browse files Browse the repository at this point in the history
* [monitor] feature support jmx protocol (#232)

* feat: [manager,collertor,common]feature: Preliminary implementation of JMX protocol #wqh

* feat: [manager,collertor,common]feature: Implementation of tomcat jmx protocol on memory and basic information monitoring #wqh

* [monitor] review

* feat: [collertor]feature: JMX link, reuse code optimization #wqh

* feat: [collertor]feature: code optimization #wqh

* feat: [manager]feature: tomcat thread configuration details #wqh

* feat: [manager]feature: tomcat thread configuration details #wqh

Co-authored-by: tomsun28 <tomsun28@outlook.com>

* [collector, manager]update tomcat monitor

Co-authored-by: 会编程的王学长 <71161318+wang1027-wqh@users.noreply.github.com>
  • Loading branch information
tomsun28 and wang1027-wqh committed Aug 9, 2022
1 parent 350981d commit 5c75af2
Show file tree
Hide file tree
Showing 9 changed files with 583 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import com.usthe.common.entity.job.Metrics;
import com.usthe.common.entity.message.CollectRep;

import java.io.IOException;

/**
* Specific indicator group collection implementation abstract class
* 具体的指标组采集实现抽象类
Expand All @@ -40,5 +42,5 @@ public abstract class AbstractCollect {
* @param metrics Metric group configuration 指标组配置
* return response builder
*/
public abstract void collect(CollectRep.MetricsData.Builder builder, long appId, String app, Metrics metrics);
public abstract void collect(CollectRep.MetricsData.Builder builder, long appId, String app, Metrics metrics) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.usthe.collector.collect.common.cache;

import lombok.extern.slf4j.Slf4j;

import javax.management.remote.JMXConnector;

/**
* jmx链接销毁管理
*
* @Author huacheng
* @Date 2022/7/3 14:58
**/
@Slf4j
public class JmxConnect implements CacheCloseable {

private JMXConnector connection;

public JmxConnect(JMXConnector connection) {
this.connection = connection;
}


@Override
public void close() {
try {
if (connection != null) {
connection.close();
}
} catch (Exception e) {
log.error("close redis connect error: {}", e.getMessage());
}
}

@Override
protected void finalize() throws Throwable {
close();
super.finalize();
}

public JMXConnector getConnection() {
return connection;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.usthe.collector.collect.jmx;

import com.usthe.collector.collect.AbstractCollect;
import com.usthe.collector.collect.common.cache.CacheIdentifier;
import com.usthe.collector.collect.common.cache.CommonCache;
import com.usthe.collector.collect.common.cache.JmxConnect;
import com.usthe.common.entity.job.Metrics;
import com.usthe.common.entity.job.protocol.JmxProtocol;
import com.usthe.common.entity.message.CollectRep;
import com.usthe.common.util.CommonConstants;
import lombok.extern.slf4j.Slf4j;

import javax.management.*;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.remote.*;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
* jmx 协议采集实现 - jmx
* jmx protocol acquisition implementation
*
* @author huacheng
* @date 2022/6/21 15:09
*/
@Slf4j
public class JmxCollectImpl extends AbstractCollect {

private static final String JMX_URL_PREFIX = "service:jmx:rmi:///jndi/rmi://";

private static final String JMX_URL_SUFFIX = "/jmxrmi";

private JmxCollectImpl() {
}

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

@Override
public void collect(CollectRep.MetricsData.Builder builder, long appId, String app, Metrics metrics) throws IOException {
//Get the address and port from the jmx carried by Metrics
//从Metrics携带的jmx中拿到地址 端口

try {
JmxProtocol jmxProtocol = metrics.getJmx();

//Create a jndi remote connection
//创建一个jndi远程连接
JMXConnector conn = getConnectSession(jmxProtocol);

MBeanServerConnection jmxBean = conn.getMBeanServerConnection();
ObjectName objectName = new ObjectName(jmxProtocol.getObjectName());
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();

//Whether there is a second level of nesting
//是否存在二级嵌套
if (jmxProtocol.getAttributeName() != null) {
String attributeName = jmxProtocol.getAttributeName();
Object attribute = jmxBean.getAttribute(objectName, attributeName);
CompositeDataSupport support = null;
if (attribute instanceof CompositeDataSupport) {
support = (CompositeDataSupport) attribute;
}
CompositeDataSupport finalSupport = support;
metrics.getFields().forEach(field -> {
assert finalSupport != null;
Object fieldValue = finalSupport.get(field.getField());
if (fieldValue != null) {
valueRowBuilder.addColumns(fieldValue.toString());
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
});
} else {
String[] attributes = new String[metrics.getAliasFields().size()];
attributes = metrics.getAliasFields().toArray(attributes);
AttributeList attributeList = jmxBean.getAttributes(objectName, attributes);
Map<String, Object> map = attributeList.asList().stream().collect(Collectors.toMap(Attribute::getName, Attribute::getValue));
for (String attribute : attributes) {
Object attributeValue = map.get(attribute);
valueRowBuilder.addColumns(attributeValue != null ? attributeValue.toString() : CommonConstants.NULL_VALUE);
}
}
builder.addValues(valueRowBuilder.build());
} catch (IOException exception) {
log.error("JMX IOException :{}", exception.getMessage());
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg(exception.getMessage());
} catch (Exception e) {
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(e.getMessage());
log.error("JMX Error :{}", e.getMessage());
}
}

private JMXConnector getConnectSession(JmxProtocol jmxProtocol) throws IOException {
CacheIdentifier identifier = CacheIdentifier.builder().ip(jmxProtocol.getHost())
.port(jmxProtocol.getPort()).username(jmxProtocol.getUsername())
.password(jmxProtocol.getPassword()).build();
Optional<Object> cacheOption = CommonCache.getInstance().getCache(identifier, true);
JMXConnector conn = null;
if (cacheOption.isPresent()) {
JmxConnect jmxConnect = (JmxConnect) cacheOption.get();
conn = jmxConnect.getConnection();
try {
conn.getMBeanServerConnection();
} catch (Exception e) {
conn = null;
CommonCache.getInstance().removeCache(identifier);
}
}
if (conn != null) {
return conn;
}
String url;
if (jmxProtocol.getUrl() != null) {
url = jmxProtocol.getUrl();
} else {
url = JMX_URL_PREFIX + jmxProtocol.getHost() + ":" + jmxProtocol.getPort() + JMX_URL_SUFFIX;
}
JMXServiceURL jmxServiceUrl = new JMXServiceURL(url);
conn = JMXConnectorFactory.connect(jmxServiceUrl);
CommonCache.getInstance().addCache(identifier, new JmxConnect(conn));
return conn;
}

private static class Singleton {
private static final JmxCollectImpl INSTANCE = new JmxCollectImpl();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ public interface DispatchConstants {
* protocol redis
*/
String PROTOCOL_REDIS = "redis";
/**
* protocol jmx
*/
String PROTOCOL_JMX = "jmx";
/**
* protocol snmp
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,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.jmx.JmxCollectImpl;
import com.usthe.collector.collect.redis.RedisSingleCollectImpl;
import com.usthe.collector.collect.snmp.SnmpCollectImpl;
import com.usthe.collector.collect.ssh.SshCollectImpl;
Expand Down Expand Up @@ -159,6 +160,9 @@ public void run() {
case DispatchConstants.PROTOCOL_SNMP:
abstractCollect = SnmpCollectImpl.getInstance();
break;
case DispatchConstants.PROTOCOL_JMX:
abstractCollect = JmxCollectImpl.getInstance();
break;
default:
break;
}
Expand Down
16 changes: 8 additions & 8 deletions common/src/main/java/com/usthe/common/entity/job/Metrics.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,7 @@

package com.usthe.common.entity.job;

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.SnmpProtocol;
import com.usthe.common.entity.job.protocol.SshProtocol;
import com.usthe.common.entity.job.protocol.TcpUdpProtocol;
import com.usthe.common.entity.job.protocol.TelnetProtocol;
import com.usthe.common.entity.job.protocol.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand Down Expand Up @@ -118,6 +111,13 @@ public class Metrics {
* 使用公共的redis协议的监控配置信息
*/
private RedisProtocol redis;

/**
* Get monitoring configuration information using public JMX protocol
* 使用公共JMX协议获取监控配置信息
*/
private JmxProtocol jmx;

/**
* Monitoring configuration information using the public snmp protocol
* 使用公共的snmp协议的监控配置信息
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.usthe.common.entity.job.protocol;

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

/**
* Jmx协议 Jmx protocol
*
* @ClassName JmxProtocol
* @Description
* @Author huacheng
* @Date 2022/6/21 15:45
* @Version 1.0
**/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class JmxProtocol {
/**
* JMX host ip or domain name
* JMX主机ip或域名
*/
private String host;

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

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

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

/**
* jmx protocol custom collection indicator address
* jmx协议自定义收集指标地址
*/
private String url;

/**
* The name of the type where the outer layer of the jmx indicator is located
* jmx指标外层所在类型名称
*/
private String objectName;

/**
* Jmx indicator name
* jmx指标名称
*/
private String attributeName;

}
Loading

0 comments on commit 5c75af2

Please sign in to comment.