From 5031301b8966babf0224945847d4e31d1cc614fa Mon Sep 17 00:00:00 2001 From: ga-ram Date: Thu, 31 Aug 2023 16:45:27 +0900 Subject: [PATCH] [#10299] Adding network information for Pinpoint inspector --- .../resources/profiles/local/pinpoint.config | 8 + .../profiles/release/pinpoint.config | 8 + .../handler/grpc/GrpcAgentEventHandler.java | 3 +- .../metric/AgentProfilerMetricHandler.java | 77 ++++++ .../stat/GrpcAgentProfilerMetricMapper.java | 57 ++++ .../receiver/StatDispatchHandler.java | 2 +- .../receiver/grpc/service/StatService.java | 4 + .../collector/service/AgentStatService.java | 3 + .../service/HBaseAgentStatService.java | 6 + .../service/SendAgentStatService.java | 6 + .../common/server/bo/stat/AgentStatType.java | 3 +- .../server/bo/stat/ProfilerMetricBo.java | 91 +++++++ grpc/grpc-idl | 2 +- .../inspector/collector/dao/AgentStatDao.java | 1 + .../dao/pinot/DefaultAgentStatDao.java | 8 +- .../dao/pinot/PinotDaoConfiguration.java | 7 + .../dao/pinot/ProfilerMetricDao.java | 63 +++++ .../collector/model/kafka/AgentStat.java | 12 +- .../model/kafka/AgentStatModelConverter.java | 98 ++++--- .../service/PinotAgentStatService.java | 12 +- .../inspector/web/inspector-definition.yml | 132 ++++++++- profiler/pom.xml | 5 + .../GrpcProfilerMetricMessageConverter.java | 64 +++++ .../grpc/GrpcStatMessageConverter.java | 41 +-- .../module/ApplicationContextModule.java | 6 +- .../module/DefaultApplicationContext.java | 5 + .../monitor/config/DefaultMonitorConfig.java | 30 ++ .../context/monitor/config/MonitorConfig.java | 8 + .../monitor/DefaultNetworkStatMonitor.java | 94 +++++++ .../monitor/NetworkMetricCollectingJob.java | 257 ++++++++++++++++++ .../profiler/monitor/NetworkStatMonitor.java | 23 ++ .../monitor/metric/profilermetric/Field.java | 27 ++ .../metric/profilermetric/NetworkMetric.java | 95 +++++++ .../metric/profilermetric/ProfilerMetric.java | 6 + .../sender/grpc/StatGrpcDataSender.java | 9 +- .../thrift/io/DefaultTBaseLocator.java | 3 + 36 files changed, 1185 insertions(+), 91 deletions(-) create mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/metric/AgentProfilerMetricHandler.java create mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/mapper/grpc/stat/GrpcAgentProfilerMetricMapper.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/ProfilerMetricBo.java create mode 100644 inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/ProfilerMetricDao.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcProfilerMetricMessageConverter.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultNetworkStatMonitor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/NetworkMetricCollectingJob.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/NetworkStatMonitor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/Field.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/NetworkMetric.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/ProfilerMetric.java diff --git a/agent/src/main/resources/profiles/local/pinpoint.config b/agent/src/main/resources/profiles/local/pinpoint.config index 5d5c786f57f5..84ab1a1cad88 100644 --- a/agent/src/main/resources/profiles/local/pinpoint.config +++ b/agent/src/main/resources/profiles/local/pinpoint.config @@ -1374,3 +1374,11 @@ profiler.kotlin.coroutines.record.threadName=false #This is important information to check whether the developer's intention and the behavior of the coroutine match. #Recommend that you use it in the development environment and not in the production environment. profiler.kotlin.coroutines.record.cancel=false + +########################################################### +# Network Metric # +########################################################### +profiler.network.metric.enable=false +profiler.network.metric.enable.udpstats=false +profiler.network.metric.enable.tcpstats=false +profiler.network.metric.collect.interval=5000 \ No newline at end of file diff --git a/agent/src/main/resources/profiles/release/pinpoint.config b/agent/src/main/resources/profiles/release/pinpoint.config index 952e6e5541d4..3a55814c4b5b 100644 --- a/agent/src/main/resources/profiles/release/pinpoint.config +++ b/agent/src/main/resources/profiles/release/pinpoint.config @@ -1399,3 +1399,11 @@ profiler.kotlin.coroutines.record.threadName=false #This is important information to check whether the developer's intention and the behavior of the coroutine match. #Recommend that you use it in the development environment and not in the production environment. profiler.kotlin.coroutines.record.cancel=false + +########################################################### +# Network Metric # +########################################################### +profiler.network.metric.enable=false +profiler.network.metric.enable.udpstats=false +profiler.network.metric.enable.tcpstats=false +profiler.network.metric.collect.interval=5000 \ No newline at end of file diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcAgentEventHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcAgentEventHandler.java index ad98cf0981dc..f5eaa0e4fd88 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcAgentEventHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcAgentEventHandler.java @@ -31,6 +31,7 @@ import com.navercorp.pinpoint.grpc.trace.PAgentStat; import com.navercorp.pinpoint.grpc.trace.PAgentStatBatch; import com.navercorp.pinpoint.grpc.trace.PAgentUriStat; +import com.navercorp.pinpoint.grpc.trace.PProfilerMetric; import com.navercorp.pinpoint.io.request.ServerRequest; import io.grpc.Status; import org.apache.logging.log4j.Logger; @@ -73,7 +74,7 @@ public void handleSimple(ServerRequest serverRequest) { handleAgentStat((PAgentStat) data); } else if (data instanceof PAgentStatBatch) { handleAgentStatBatch((PAgentStatBatch) data); - } else if (data instanceof PAgentUriStat) { + } else if ((data instanceof PAgentUriStat) || (data instanceof PProfilerMetric)) { // do nothing } else { logger.warn("Invalid request type. serverRequest={}", serverRequest); diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/metric/AgentProfilerMetricHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/metric/AgentProfilerMetricHandler.java new file mode 100644 index 000000000000..99e52624c90e --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/metric/AgentProfilerMetricHandler.java @@ -0,0 +1,77 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.collector.handler.grpc.metric; + +import com.google.protobuf.GeneratedMessageV3; +import com.navercorp.pinpoint.collector.handler.grpc.GrpcMetricHandler; +import com.navercorp.pinpoint.collector.mapper.grpc.stat.GrpcAgentProfilerMetricMapper; +import com.navercorp.pinpoint.collector.service.AgentStatService; +import com.navercorp.pinpoint.common.server.bo.stat.ProfilerMetricBo; +import com.navercorp.pinpoint.grpc.MessageFormatUtils; +import com.navercorp.pinpoint.grpc.trace.PProfilerMetric; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +@Service +public class AgentProfilerMetricHandler implements GrpcMetricHandler { + private final Logger logger = LogManager.getLogger(this.getClass()); + private final GrpcAgentProfilerMetricMapper agentProfilerMetricMapper; + private final AgentStatService[] agentStatServiceList; + + public AgentProfilerMetricHandler(GrpcAgentProfilerMetricMapper agentProfilerMetricMapper, + AgentStatService[] agentStatServiceList) { + this.agentProfilerMetricMapper = Objects.requireNonNull(agentProfilerMetricMapper, "agentProfilerMetricMapper"); + this.agentStatServiceList = Objects.requireNonNull(agentStatServiceList, "agentStatServiceList"); + + for (AgentStatService service : this.agentStatServiceList) { + logger.info("{}:{}", AgentStatService.class.getSimpleName(), service.getClass().getSimpleName()); + } + } + + @Override + public boolean accept(GeneratedMessageV3 message) { + return message instanceof PProfilerMetric; + } + + @Override + public void handle(GeneratedMessageV3 message) { + if (logger.isDebugEnabled()) { + logger.debug("Handle PProfilerMetric={}", MessageFormatUtils.debugLog(message)); + } + + final PProfilerMetric profilerMetric = (PProfilerMetric) message; + final ProfilerMetricBo profilerMetricBo = this.agentProfilerMetricMapper.map(profilerMetric); + if (profilerMetricBo == null) { + return; + } + + handleProfilerMetric(profilerMetricBo); + } + + private void handleProfilerMetric(ProfilerMetricBo profilerMetricBo) { + for (AgentStatService agentStatService : agentStatServiceList) { + try { + agentStatService.save(profilerMetricBo); + } catch (Exception e) { + logger.warn("Failed to handle service={}, AgentStatBo={}", agentStatService, profilerMetricBo, e); + } + } + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/grpc/stat/GrpcAgentProfilerMetricMapper.java b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/grpc/stat/GrpcAgentProfilerMetricMapper.java new file mode 100644 index 000000000000..0e42594b19b3 --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/grpc/stat/GrpcAgentProfilerMetricMapper.java @@ -0,0 +1,57 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.collector.mapper.grpc.stat; + +import com.navercorp.pinpoint.common.server.bo.stat.ProfilerMetricBo; +import com.navercorp.pinpoint.grpc.Header; +import com.navercorp.pinpoint.grpc.server.ServerContext; +import com.navercorp.pinpoint.grpc.trace.PProfilerMetric; +import com.navercorp.pinpoint.grpc.trace.PProfilerMetricField; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class GrpcAgentProfilerMetricMapper { + + public ProfilerMetricBo map(PProfilerMetric profilerMetric) { + if (profilerMetric == null) { + return null; + } + + final Header agentInfo = ServerContext.getAgentInfo(); + final String agentId = agentInfo.getAgentId(); + final long startTimestamp = agentInfo.getAgentStartTime(); + + final ProfilerMetricBo profilerMetricBo = new ProfilerMetricBo(); + profilerMetricBo.setAgentId(agentId); + profilerMetricBo.setStartTimestamp(startTimestamp); + profilerMetricBo.setTimestamp(profilerMetric.getTimestamp()); + profilerMetricBo.setMetricName(profilerMetric.getName()); + + List tags = profilerMetric.getTagsList(); + for (PProfilerMetricField tag : tags) { + profilerMetricBo.addTags(tag.getName(), tag.getStringValue()); + } + + List fields = profilerMetric.getFieldsList(); + for (PProfilerMetricField field : fields) { + profilerMetricBo.addValues(field.getName(), field.getLongValue()); + } + + return profilerMetricBo; + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/StatDispatchHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/StatDispatchHandler.java index 6072a852a8e7..c7cd0c55d484 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/StatDispatchHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/StatDispatchHandler.java @@ -45,7 +45,7 @@ private SimpleHandler getSimpleHandler(Header header) { // To change below code to switch table make it a little bit faster. // FIXME (2014.08) Legacy - TAgentStats should not be sent over the wire. final short type = header.getType(); - if (type == DefaultTBaseLocator.AGENT_STAT || type == DefaultTBaseLocator.AGENT_STAT_BATCH || type == DefaultTBaseLocator.AGENT_URI_STAT) { + if (type == DefaultTBaseLocator.AGENT_STAT || type == DefaultTBaseLocator.AGENT_STAT_BATCH || type == DefaultTBaseLocator.AGENT_URI_STAT || type == DefaultTBaseLocator.AGENT_PROFILER_STAT) { return new SimpleDualHandler<>(agentStatHandler, agentEventHandler); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/StatService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/StatService.java index cc275fa515fd..be3a4539d657 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/StatService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/StatService.java @@ -25,6 +25,7 @@ import com.navercorp.pinpoint.grpc.trace.PAgentStatBatch; import com.navercorp.pinpoint.grpc.trace.PAgentUriStat; import com.navercorp.pinpoint.grpc.trace.PStatMessage; +import com.navercorp.pinpoint.grpc.trace.PProfilerMetric; import com.navercorp.pinpoint.grpc.trace.StatGrpc; import com.navercorp.pinpoint.io.header.Header; import com.navercorp.pinpoint.io.header.HeaderEntity; @@ -79,6 +80,9 @@ public void onNext(PStatMessage statMessage) { } else if (statMessage.hasAgentUriStat()) { final Message message = newMessage(statMessage.getAgentUriStat(), DefaultTBaseLocator.AGENT_URI_STAT); send(message, responseObserver); + } else if (statMessage.hasProfilerMetric()) { + final Message message = newMessage(statMessage.getProfilerMetric(), DefaultTBaseLocator.AGENT_PROFILER_STAT); + send(message, responseObserver); } else { if (isDebug) { logger.debug("Found empty stat message {}", MessageFormatUtils.debugLog(statMessage)); diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/service/AgentStatService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/service/AgentStatService.java index 7cf876a48344..5d9cb03af22e 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/service/AgentStatService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/service/AgentStatService.java @@ -16,6 +16,7 @@ package com.navercorp.pinpoint.collector.service; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatBo; +import com.navercorp.pinpoint.common.server.bo.stat.ProfilerMetricBo; import javax.validation.Valid; @@ -24,4 +25,6 @@ */ public interface AgentStatService { void save(@Valid AgentStatBo agentStatBo); + + void save(@Valid ProfilerMetricBo profilerMetricBo); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/service/HBaseAgentStatService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/service/HBaseAgentStatService.java index dcbaecf9a965..4733faf9d376 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/service/HBaseAgentStatService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/service/HBaseAgentStatService.java @@ -17,6 +17,7 @@ import com.navercorp.pinpoint.collector.dao.AgentStatDao; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatBo; +import com.navercorp.pinpoint.common.server.bo.stat.ProfilerMetricBo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Service; @@ -55,4 +56,9 @@ public void save(@Valid AgentStatBo agentStatBo) { } } + @Override + public void save(ProfilerMetricBo profilerMetricBo) { + // Does nothing + } + } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/service/SendAgentStatService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/service/SendAgentStatService.java index 14afe93f87bd..a3fc58dcb92b 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/service/SendAgentStatService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/service/SendAgentStatService.java @@ -18,6 +18,7 @@ import com.navercorp.pinpoint.collector.config.FlinkProperties; import com.navercorp.pinpoint.collector.mapper.flink.TFAgentStatBatchMapper; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatBo; +import com.navercorp.pinpoint.common.server.bo.stat.ProfilerMetricBo; import com.navercorp.pinpoint.thrift.dto.flink.TFAgentStatBatch; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -51,4 +52,9 @@ public void save(@Valid AgentStatBo agentStatBo) { TFAgentStatBatch tFAgentStatBatch = tFAgentStatBatchMapper.map(agentStatBo); flinkService.sendData(tFAgentStatBatch); } + + @Override + public void save(ProfilerMetricBo profilerMetricBo) { + // does nothing + } } diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/AgentStatType.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/AgentStatType.java index 5ff9d4f55cd1..9c55b8c927bb 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/AgentStatType.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/AgentStatType.java @@ -35,7 +35,8 @@ public enum AgentStatType { FILE_DESCRIPTOR((byte) 9, "FileDescriptor", "fileDescriptor"), DIRECT_BUFFER((byte) 10, "DirectBuffer", "directBuffer"), TOTAL_THREAD((byte) 11, "Total Thread Count", "totalThreadCount"), - LOADED_CLASS((byte) 12, "Loaded Class", "loadedClass"); + LOADED_CLASS((byte) 12, "Loaded Class", "loadedClass"), + PROFILER_METRIC((byte) 13, "Profiler Metric", "profilerMetric"); public static final int TYPE_CODE_BYTE_LENGTH = 1; diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/ProfilerMetricBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/ProfilerMetricBo.java new file mode 100644 index 000000000000..98f3387c2fc4 --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/ProfilerMetricBo.java @@ -0,0 +1,91 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.common.server.bo.stat; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class ProfilerMetricBo implements AgentStatDataPoint { + + public static final long UNCOLLECTED_VALUE = -1; + + private String agentId; + private long startTimestamp; + private long timestamp; + private String metricName; // is this necessary? + private final Map tags = new HashMap<>(); + private final Map values = new HashMap<>(); + + @Override + public String getAgentId() { + return agentId; + } + + @Override + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + @Override + public long getStartTimestamp() { + return startTimestamp; + } + + @Override + public void setStartTimestamp(long startTimestamp) { + this.startTimestamp = startTimestamp; + } + + @Override + public long getTimestamp() { + return timestamp; + } + + @Override + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + @Override + public AgentStatType getAgentStatType() { + return AgentStatType.PROFILER_METRIC; + } + + public void addTags(String name, String value) { + tags.put(name, value); + } + + public Map getTags() { + return tags; + } + + public void addValues(String name, double value) { + values.put(name, value); + } + + public Map getValues() { + return values; + } + + public void setMetricName(String metricName) { + this.metricName = Objects.requireNonNull(metricName); + } + + public String getMetricName() { + return metricName; + } +} \ No newline at end of file diff --git a/grpc/grpc-idl b/grpc/grpc-idl index caaabb738e9a..e68bc3963e7b 160000 --- a/grpc/grpc-idl +++ b/grpc/grpc-idl @@ -1 +1 @@ -Subproject commit caaabb738e9a53994b5ac58f9ff9e9c129bef94d +Subproject commit e68bc3963e7ba6f5c7e33f380f45111fddaaf938 diff --git a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/AgentStatDao.java b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/AgentStatDao.java index aca01994a8e4..91d2d454098b 100644 --- a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/AgentStatDao.java +++ b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/AgentStatDao.java @@ -18,6 +18,7 @@ import com.navercorp.pinpoint.common.server.bo.stat.AgentStatBo; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatDataPoint; +import com.navercorp.pinpoint.common.server.bo.stat.ProfilerMetricBo; import org.springframework.stereotype.Repository; import java.util.List; diff --git a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/DefaultAgentStatDao.java b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/DefaultAgentStatDao.java index fd0d7a63ff2a..a3f4d0b07967 100644 --- a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/DefaultAgentStatDao.java +++ b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/DefaultAgentStatDao.java @@ -35,13 +35,13 @@ public class DefaultAgentStatDao implements Agent private final Logger logger = LogManager.getLogger(DefaultAgentStatDao.class.getName()); - private final Function> dataPointFunction; + private final Function> agentStatBoDataPointFunction; private final Function, List> convertToKafkaModelFunction; private final KafkaTemplate kafkaAgentStatTemplate; private final String topic; - public DefaultAgentStatDao(Function> dataPointFunction, KafkaTemplate kafkaAgentStatTemplate, Function, List> convertToKafkaModelFunction, String topic) { - this.dataPointFunction = Objects.requireNonNull(dataPointFunction, "dataPointFunction"); + public DefaultAgentStatDao(Function> agentStatBoDataPointFunction, KafkaTemplate kafkaAgentStatTemplate, Function, List> convertToKafkaModelFunction, String topic) { + this.agentStatBoDataPointFunction = Objects.requireNonNull(agentStatBoDataPointFunction, "dataPointFunction"); this.kafkaAgentStatTemplate = Objects.requireNonNull(kafkaAgentStatTemplate, "kafkaAgentStatTemplate"); this.convertToKafkaModelFunction = convertToKafkaModelFunction; this.topic = topic; @@ -64,7 +64,7 @@ private List convertDataToKafkaModel(List AgentStatDataPointList) @Override public void dispatch(AgentStatBo agentStatBo) { Objects.requireNonNull(agentStatBo, "agentStatBo"); - List dataPointList = this.dataPointFunction.apply(agentStatBo); + List dataPointList = this.agentStatBoDataPointFunction.apply(agentStatBo); insert(agentStatBo.getAgentId(), dataPointList); } diff --git a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/PinotDaoConfiguration.java b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/PinotDaoConfiguration.java index e6e78410355a..4f9c4d6db2a0 100644 --- a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/PinotDaoConfiguration.java +++ b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/PinotDaoConfiguration.java @@ -30,6 +30,7 @@ import com.navercorp.pinpoint.common.server.bo.stat.ResponseTimeBo; import com.navercorp.pinpoint.common.server.bo.stat.TotalThreadCountBo; import com.navercorp.pinpoint.common.server.bo.stat.TransactionBo; +import com.navercorp.pinpoint.common.server.bo.stat.ProfilerMetricBo; import com.navercorp.pinpoint.inspector.collector.dao.AgentStatDao; import com.navercorp.pinpoint.inspector.collector.model.kafka.AgentStat; import com.navercorp.pinpoint.inspector.collector.model.kafka.AgentStatModelConverter; @@ -131,4 +132,10 @@ public AgentStatDao getPinotDataSourceListDao() { Function, List> convertToAgentStat = AgentStatModelConverter::convertDataSourceToAgentStat; return newAgentStatDao(AgentStatBo::getDataSourceListBos, convertToAgentStat); } + + @Bean + public ProfilerMetricDao getPinotProfilerMetricDao() { + Function> convertToAgentStat = AgentStatModelConverter::convertProfilerMetricToAgentStat; + return new ProfilerMetricDao(kafkaAgentStatTemplate, convertToAgentStat, topic); + } } diff --git a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/ProfilerMetricDao.java b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/ProfilerMetricDao.java new file mode 100644 index 000000000000..ad969a2f1fb6 --- /dev/null +++ b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/dao/pinot/ProfilerMetricDao.java @@ -0,0 +1,63 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.inspector.collector.dao.pinot; + +import com.navercorp.pinpoint.common.server.bo.stat.ProfilerMetricBo; +import com.navercorp.pinpoint.inspector.collector.model.kafka.AgentStat; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.kafka.core.KafkaTemplate; + +import java.util.List; +import java.util.Objects; +import java.util.function.Function; + +public class ProfilerMetricDao { + private final Logger logger = LogManager.getLogger(DefaultAgentStatDao.class.getName()); + private final Function> convertToKafkaModelFunction; + private final KafkaTemplate kafkaAgentStatTemplate; + private final String topic; + + public ProfilerMetricDao(KafkaTemplate kafkaAgentStatTemplate, Function> convertToKafkaModelFunction, String topic) { + this.kafkaAgentStatTemplate = Objects.requireNonNull(kafkaAgentStatTemplate, "kafkaAgentStatTemplate"); + this.convertToKafkaModelFunction = convertToKafkaModelFunction; + this.topic = topic; + } + + public void dispatch(ProfilerMetricBo profilerMetricBo) { + Objects.requireNonNull(profilerMetricBo, "profilerMetricBo"); + insert(profilerMetricBo.getAgentId(), profilerMetricBo); + } + + private void insert(String agentId, ProfilerMetricBo profilerMetricBo) { + List agentStatList = convertToKafkaModelFunction.apply(profilerMetricBo); + + for (AgentStat agentStat : agentStatList) { + String kafkaKey = generateKafkaKey(agentStat); + kafkaAgentStatTemplate.send(topic, kafkaKey, agentStat); + } + } + + private String generateKafkaKey(AgentStat agentStat) { + StringBuilder sb = new StringBuilder(); + sb.append(agentStat.getApplicationName()); + sb.append("_"); + sb.append(agentStat.getAgentId()); + sb.append("_"); + sb.append(agentStat.getMetricName()); + return sb.toString(); + } +} diff --git a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/model/kafka/AgentStat.java b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/model/kafka/AgentStat.java index 40cb9c04333b..539747f3c272 100644 --- a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/model/kafka/AgentStat.java +++ b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/model/kafka/AgentStat.java @@ -30,6 +30,7 @@ public class AgentStat { private final String tenantId; + private final String serviceName; private final String applicationName; private final String agentId; @@ -40,12 +41,13 @@ public class AgentStat { private final long eventTime; - public AgentStat(String tenantId, String applicationName, String agentId, String metricName, String fieldName, double fieldValue, long eventTime) { - this(tenantId, applicationName, agentId, metricName, fieldName, fieldValue, eventTime, Collections.emptyList()); + public AgentStat(String tenantId, String serviceName, String applicationName, String agentId, String metricName, String fieldName, double fieldValue, long eventTime) { + this(tenantId, serviceName, applicationName, agentId, metricName, fieldName, fieldValue, eventTime, Collections.emptyList()); } - public AgentStat(String tenantId, String applicationName, String agentId, String metricName, String fieldName, double fieldValue, long eventTime, List tags) { + public AgentStat(String tenantId, String serviceName, String applicationName, String agentId, String metricName, String fieldName, double fieldValue, long eventTime, List tags) { this.tenantId = tenantId; + this.serviceName = serviceName; this.applicationName = applicationName; this.agentId = agentId; this.metricName = metricName; @@ -59,6 +61,10 @@ public String getTenantId() { return tenantId; } + public String getServiceName() { + return serviceName; + } + public String getApplicationName() { return applicationName; } diff --git a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/model/kafka/AgentStatModelConverter.java b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/model/kafka/AgentStatModelConverter.java index efb585522bb9..fb79df602d90 100644 --- a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/model/kafka/AgentStatModelConverter.java +++ b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/model/kafka/AgentStatModelConverter.java @@ -31,8 +31,10 @@ import com.navercorp.pinpoint.common.server.bo.stat.ResponseTimeBo; import com.navercorp.pinpoint.common.server.bo.stat.TotalThreadCountBo; import com.navercorp.pinpoint.common.server.bo.stat.TransactionBo; +import com.navercorp.pinpoint.common.server.bo.stat.ProfilerMetricBo; import com.navercorp.pinpoint.metric.common.model.Tag; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -46,10 +48,10 @@ public class AgentStatModelConverter { public static List convertCpuLoadToAgentStat(List cpuLoadBoList) { List agentStatList = cpuLoadBoList.stream() .flatMap(cpuLoadBo -> { - AgentStat jvmCpuLoad = new AgentStat("defaultTenantId", "applicationName", cpuLoadBo.getAgentId(), + AgentStat jvmCpuLoad = new AgentStat("defaultTenantId", "", "applicationName", cpuLoadBo.getAgentId(), AgentStatType.CPU_LOAD.getChartType(), AgentStatField.CPU_LOAD_JVM.getFieldName(), cpuLoadBo.getJvmCpuLoad(), cpuLoadBo.getTimestamp()); - AgentStat systemCpuLoad = new AgentStat("defaultTenantId", "applicationName", cpuLoadBo.getAgentId(), + AgentStat systemCpuLoad = new AgentStat("defaultTenantId", "", "applicationName", cpuLoadBo.getAgentId(), AgentStatType.CPU_LOAD.getChartType(), AgentStatField.CPU_LOAD_SYSTEM.getFieldName(), cpuLoadBo.getSystemCpuLoad(), cpuLoadBo.getTimestamp()); @@ -63,16 +65,16 @@ public static List convertCpuLoadToAgentStat(List cpuLoadB public static List convertActiveTraceToAgentStat(List activeTraceBoList) { List agentStatList = activeTraceBoList.stream() .flatMap(activeTraceBo -> { - AgentStat fastCount = new AgentStat("defaultTenantId", "applicationName", activeTraceBo.getAgentId(), + AgentStat fastCount = new AgentStat("defaultTenantId", "", "applicationName", activeTraceBo.getAgentId(), AgentStatType.ACTIVE_TRACE.getChartType(), AgentStatField.ACTIVE_TRACE_FAST_COUNT.getFieldName(), activeTraceBo.getActiveTraceHistogram().getFastCount(), activeTraceBo.getTimestamp()); - AgentStat normalCount = new AgentStat("defaultTenantId", "applicationName", activeTraceBo.getAgentId(), + AgentStat normalCount = new AgentStat("defaultTenantId", "", "applicationName", activeTraceBo.getAgentId(), AgentStatType.ACTIVE_TRACE.getChartType(), AgentStatField.ACTIVE_TRACE_NORNAL_COUNT.getFieldName(), activeTraceBo.getActiveTraceHistogram().getNormalCount(), activeTraceBo.getTimestamp()); - AgentStat slowCount = new AgentStat("defaultTenantId", "applicationName", activeTraceBo.getAgentId(), + AgentStat slowCount = new AgentStat("defaultTenantId", "", "applicationName", activeTraceBo.getAgentId(), AgentStatType.ACTIVE_TRACE.getChartType(), AgentStatField.ACTIVE_TRACE_SLOW_COUNT.getFieldName(), activeTraceBo.getActiveTraceHistogram().getSlowCount(), activeTraceBo.getTimestamp()); - AgentStat verySlowCount = new AgentStat("defaultTenantId", "applicationName", activeTraceBo.getAgentId(), + AgentStat verySlowCount = new AgentStat("defaultTenantId", "", "applicationName", activeTraceBo.getAgentId(), AgentStatType.ACTIVE_TRACE.getChartType(), AgentStatField.ACTIVE_TRACE_VERY_SLOW_COUNT.getFieldName(), activeTraceBo.getActiveTraceHistogram().getVerySlowCount(), activeTraceBo.getTimestamp()); return Stream.of(fastCount, normalCount, slowCount, verySlowCount); @@ -85,25 +87,25 @@ public static List convertActiveTraceToAgentStat(List public static List convertJvmGcToAgentStat(List jvmGcBoList) { List agentStatList = jvmGcBoList.stream() .flatMap(jvmGcBo -> { - AgentStat gcType = new AgentStat("defaultTenantId", "applicationName", jvmGcBo.getAgentId(), + AgentStat gcType = new AgentStat("defaultTenantId", "", "applicationName", jvmGcBo.getAgentId(), AgentStatType.JVM_GC.getChartType(), AgentStatField.JVM_GC_TYPE.getFieldName(), jvmGcBo.getGcType().getTypeCode(), jvmGcBo.getTimestamp()); - AgentStat heapUsed = new AgentStat("defaultTenantId", "applicationName", jvmGcBo.getAgentId(), + AgentStat heapUsed = new AgentStat("defaultTenantId", "", "applicationName", jvmGcBo.getAgentId(), AgentStatType.JVM_GC.getChartType(), AgentStatField.JVM_GC_HEAP_USED.getFieldName(), jvmGcBo.getHeapUsed(), jvmGcBo.getTimestamp()); - AgentStat heapMax = new AgentStat("defaultTenantId", "applicationName", jvmGcBo.getAgentId(), + AgentStat heapMax = new AgentStat("defaultTenantId", "", "applicationName", jvmGcBo.getAgentId(), AgentStatType.JVM_GC.getChartType(), AgentStatField.JVM_GC_HEAP_MAX.getFieldName(), jvmGcBo.getHeapMax(), jvmGcBo.getTimestamp()); - AgentStat nonHeapUsed = new AgentStat("defaultTenantId", "applicationName", jvmGcBo.getAgentId(), + AgentStat nonHeapUsed = new AgentStat("defaultTenantId", "", "applicationName", jvmGcBo.getAgentId(), AgentStatType.JVM_GC.getChartType(), AgentStatField.JVM_GC_NONHEAP_USED.getFieldName(), jvmGcBo.getNonHeapUsed(), jvmGcBo.getTimestamp()); - AgentStat nonHeapMax = new AgentStat("defaultTenantId", "applicationName", jvmGcBo.getAgentId(), + AgentStat nonHeapMax = new AgentStat("defaultTenantId", "", "applicationName", jvmGcBo.getAgentId(), AgentStatType.JVM_GC.getChartType(), AgentStatField.JVM_GC_NONHEAP_MAX.getFieldName(), jvmGcBo.getNonHeapMax(), jvmGcBo.getTimestamp()); - AgentStat gcOldCount = new AgentStat("defaultTenantId", "applicationName", jvmGcBo.getAgentId(), + AgentStat gcOldCount = new AgentStat("defaultTenantId", "", "applicationName", jvmGcBo.getAgentId(), AgentStatType.JVM_GC.getChartType(), AgentStatField.JVM_GC_NONHEAP_GC_OLD_COUNT.getFieldName(), jvmGcBo.getGcOldCount(), jvmGcBo.getTimestamp()); - AgentStat gcOldTime = new AgentStat("defaultTenantId", "applicationName", jvmGcBo.getAgentId(), + AgentStat gcOldTime = new AgentStat("defaultTenantId", "", "applicationName", jvmGcBo.getAgentId(), AgentStatType.JVM_GC.getChartType(), AgentStatField.JVM_GC_NONHEAP_GC_OLD_TIME.getFieldName(), jvmGcBo.getGcOldTime(), jvmGcBo.getTimestamp()); return Stream.of(gcType, heapUsed, heapMax, nonHeapUsed, @@ -119,28 +121,28 @@ public static List convertJvmGCDetailedToAgentStat(List agentStatList = jvmGcDetailedBoList .stream() .flatMap(jvmGcDetailedBo -> { - AgentStat newGcCount = new AgentStat("defaultTenantId", "applicationName", jvmGcDetailedBo.getAgentId(), + AgentStat newGcCount = new AgentStat("defaultTenantId", "", "applicationName", jvmGcDetailedBo.getAgentId(), AgentStatType.JVM_GC_DETAILED.getChartType(), AgentStatField.JVM_GC_DETAILED_GC_NEW_COUNT.getFieldName(), jvmGcDetailedBo.getGcNewCount(), jvmGcDetailedBo.getTimestamp()); - AgentStat newGcTime = new AgentStat("defaultTenantId", "applicationName", jvmGcDetailedBo.getAgentId(), + AgentStat newGcTime = new AgentStat("defaultTenantId", "", "applicationName", jvmGcDetailedBo.getAgentId(), AgentStatType.JVM_GC_DETAILED.getChartType(), AgentStatField.JVM_GC_DETAILED_GC_NEW_TIME.getFieldName(), jvmGcDetailedBo.getGcNewTime(), jvmGcDetailedBo.getTimestamp()); - AgentStat codeCacheUsed = new AgentStat("defaultTenantId", "applicationName", jvmGcDetailedBo.getAgentId(), + AgentStat codeCacheUsed = new AgentStat("defaultTenantId", "", "applicationName", jvmGcDetailedBo.getAgentId(), AgentStatType.JVM_GC_DETAILED.getChartType(), AgentStatField.JVM_GC_DETAILED_CODE_CACHE_USED.getFieldName(), jvmGcDetailedBo.getCodeCacheUsed(), jvmGcDetailedBo.getTimestamp()); - AgentStat newGenUsed = new AgentStat("defaultTenantId", "applicationName", jvmGcDetailedBo.getAgentId(), + AgentStat newGenUsed = new AgentStat("defaultTenantId", "", "applicationName", jvmGcDetailedBo.getAgentId(), AgentStatType.JVM_GC_DETAILED.getChartType(), AgentStatField.JVM_GC_DETAILED_NEW_GEN_USED.getFieldName(), jvmGcDetailedBo.getNewGenUsed(), jvmGcDetailedBo.getTimestamp()); - AgentStat oldGenUsed = new AgentStat("defaultTenantId", "applicationName", jvmGcDetailedBo.getAgentId(), + AgentStat oldGenUsed = new AgentStat("defaultTenantId", "", "applicationName", jvmGcDetailedBo.getAgentId(), AgentStatType.JVM_GC_DETAILED.getChartType(), AgentStatField.JVM_GC_DETAILED_OLD_GEN_USED.getFieldName(), jvmGcDetailedBo.getOldGenUsed(), jvmGcDetailedBo.getTimestamp()); - AgentStat survivorSpaceUsed = new AgentStat("defaultTenantId", "applicationName", jvmGcDetailedBo.getAgentId(), + AgentStat survivorSpaceUsed = new AgentStat("defaultTenantId", "", "applicationName", jvmGcDetailedBo.getAgentId(), AgentStatType.JVM_GC_DETAILED.getChartType(), AgentStatField.JVM_GC_DETAILED_SURVIVOR_SPACE_USED.getFieldName(), jvmGcDetailedBo.getSurvivorSpaceUsed(), jvmGcDetailedBo.getTimestamp()); - AgentStat permGenUsed = new AgentStat("defaultTenantId", "applicationName", jvmGcDetailedBo.getAgentId(), + AgentStat permGenUsed = new AgentStat("defaultTenantId", "", "applicationName", jvmGcDetailedBo.getAgentId(), AgentStatType.JVM_GC_DETAILED.getChartType(), AgentStatField.JVM_GC_DETAILED_PERM_GEN_USED.getFieldName(), jvmGcDetailedBo.getPermGenUsed(), jvmGcDetailedBo.getTimestamp()); - AgentStat metaspaceUsed = new AgentStat("defaultTenantId", "applicationName", jvmGcDetailedBo.getAgentId(), + AgentStat metaspaceUsed = new AgentStat("defaultTenantId", "", "applicationName", jvmGcDetailedBo.getAgentId(), AgentStatType.JVM_GC_DETAILED.getChartType(), AgentStatField.JVM_GC_DETAILED_METASPACE_USED.getFieldName(), jvmGcDetailedBo.getMetaspaceUsed(), jvmGcDetailedBo.getTimestamp()); @@ -157,25 +159,25 @@ public static List convertJvmGCDetailedToAgentStat(List convertTransactionToAgentStat(List transactionBoList) { List agentStatList = transactionBoList.stream() .flatMap(transactionBo -> { - AgentStat collectInterval = new AgentStat("defaultTenantId", "applicationName", transactionBo.getAgentId(), + AgentStat collectInterval = new AgentStat("defaultTenantId", "", "applicationName", transactionBo.getAgentId(), AgentStatType.TRANSACTION.getChartType(), AgentStatField.TRANSACTION_COLLECT_INTERVAL.getFieldName(), transactionBo.getCollectInterval(), transactionBo.getTimestamp()); - AgentStat sampledNewCount = new AgentStat("defaultTenantId", "applicationName", transactionBo.getAgentId(), + AgentStat sampledNewCount = new AgentStat("defaultTenantId", "", "applicationName", transactionBo.getAgentId(), AgentStatType.TRANSACTION.getChartType(), AgentStatField.TRANSACTION_SAMPLED_NEW_COUNT.getFieldName(), transactionBo.getSampledNewCount(), transactionBo.getTimestamp()); - AgentStat sampledContinuationCount = new AgentStat("defaultTenantId", "applicationName", transactionBo.getAgentId(), + AgentStat sampledContinuationCount = new AgentStat("defaultTenantId", "", "applicationName", transactionBo.getAgentId(), AgentStatType.TRANSACTION.getChartType(), AgentStatField.TRANSACTION_SAMPLED_CONTINUATION_COUNT.getFieldName(), transactionBo.getSampledContinuationCount(), transactionBo.getTimestamp()); - AgentStat unsampledNewCount = new AgentStat("defaultTenantId", "applicationName", transactionBo.getAgentId(), + AgentStat unsampledNewCount = new AgentStat("defaultTenantId", "", "applicationName", transactionBo.getAgentId(), AgentStatType.TRANSACTION.getChartType(), AgentStatField.TRANSACTION_UNSAMPLED_NEW_COUNT.getFieldName(), transactionBo.getUnsampledNewCount(), transactionBo.getTimestamp()); - AgentStat unsampledContinuationCount = new AgentStat("defaultTenantId", "applicationName", transactionBo.getAgentId(), + AgentStat unsampledContinuationCount = new AgentStat("defaultTenantId", "", "applicationName", transactionBo.getAgentId(), AgentStatType.TRANSACTION.getChartType(), AgentStatField.TRANSACTION_UNSAMPLED_CONTINUATION_COUNT.getFieldName(), transactionBo.getUnsampledContinuationCount(), transactionBo.getTimestamp()); - AgentStat skippedNewSkipCount = new AgentStat("defaultTenantId", "applicationName", transactionBo.getAgentId(), + AgentStat skippedNewSkipCount = new AgentStat("defaultTenantId", "", "applicationName", transactionBo.getAgentId(), AgentStatType.TRANSACTION.getChartType(), AgentStatField.TRANSACTION_SKIPPED_NEW_SKIP_COUNT.getFieldName(), transactionBo.getSkippedNewSkipCount(), transactionBo.getTimestamp()); - AgentStat skippedContinuationCount = new AgentStat("defaultTenantId", "applicationName", transactionBo.getAgentId(), + AgentStat skippedContinuationCount = new AgentStat("defaultTenantId", "", "applicationName", transactionBo.getAgentId(), AgentStatType.TRANSACTION.getChartType(), AgentStatField.TRANSACTION_SKIPPED_CONTINUATION_COUNT.getFieldName(), transactionBo.getSkippedContinuationCount(), transactionBo.getTimestamp()); @@ -192,10 +194,10 @@ public static List convertResponseTimeToAgentStat(List agentStatList = reponseTimeBoList.stream() .flatMap(responseTimeBo -> { - AgentStat avg = new AgentStat("defaultTenantId", "applicationName", responseTimeBo.getAgentId(), + AgentStat avg = new AgentStat("defaultTenantId", "", "applicationName", responseTimeBo.getAgentId(), AgentStatType.RESPONSE_TIME.getChartType(), AgentStatField.RESPONSE_TIME_AVG.getFieldName(), responseTimeBo.getAvg(), responseTimeBo.getTimestamp()); - AgentStat max = new AgentStat("defaultTenantId", "applicationName", responseTimeBo.getAgentId(), + AgentStat max = new AgentStat("defaultTenantId", "", "applicationName", responseTimeBo.getAgentId(), AgentStatType.RESPONSE_TIME.getChartType(), AgentStatField.RESPONSE_TIME_MAX.getFieldName(), responseTimeBo.getMax(), responseTimeBo.getTimestamp()); @@ -209,7 +211,7 @@ public static List convertResponseTimeToAgentStat(List convertDeadlockThreadCountToAgentStat(List deadlockThreadCountBoList) { List agentStatList = deadlockThreadCountBoList.stream() .flatMap(deadlockThreadCountBo -> { - AgentStat deadlockedThreadCount = new AgentStat("defaultTenantId", "applicationName", deadlockThreadCountBo.getAgentId(), + AgentStat deadlockedThreadCount = new AgentStat("defaultTenantId", "", "applicationName", deadlockThreadCountBo.getAgentId(), AgentStatType.DEADLOCK.getChartType(), AgentStatField.DEADLOCK_THREAD_COUNT.getFieldName(), deadlockThreadCountBo.getDeadlockedThreadCount(), deadlockThreadCountBo.getTimestamp()); @@ -223,7 +225,7 @@ public static List convertDeadlockThreadCountToAgentStat(List convertFileDescriptorToAgentStat(List fileDescriptorBoList) { List agentStatList = fileDescriptorBoList.stream() .flatMap(fileDescriptorBo -> { - AgentStat openFileDescriptorCount = new AgentStat("defaultTenantId", "applicationName", fileDescriptorBo.getAgentId(), + AgentStat openFileDescriptorCount = new AgentStat("defaultTenantId", "", "applicationName", fileDescriptorBo.getAgentId(), AgentStatType.FILE_DESCRIPTOR.getChartType(), AgentStatField.OPEN_FILE_DESCRIPTOR_COUNT.getFieldName(), fileDescriptorBo.getOpenFileDescriptorCount(), fileDescriptorBo.getTimestamp()); @@ -237,16 +239,16 @@ public static List convertFileDescriptorToAgentStat(List convertDirectBufferToAgentStat(List directBufferBoList) { List agentStatList = directBufferBoList.stream() .flatMap(directBufferBo -> { - AgentStat directCount = new AgentStat("defaultTenantId", "applicationName", directBufferBo.getAgentId(), + AgentStat directCount = new AgentStat("defaultTenantId", "", "applicationName", directBufferBo.getAgentId(), AgentStatType.DIRECT_BUFFER.getChartType(), AgentStatField.DIRECT_BUFFER_DIRECT_COUNT.getFieldName(), directBufferBo.getDirectCount(), directBufferBo.getTimestamp()); - AgentStat directMemoryUsed = new AgentStat("defaultTenantId", "applicationName", directBufferBo.getAgentId(), + AgentStat directMemoryUsed = new AgentStat("defaultTenantId", "", "applicationName", directBufferBo.getAgentId(), AgentStatType.DIRECT_BUFFER.getChartType(), AgentStatField.DIRECT_BUFFER_DIRECT_MEMORY_USED.getFieldName(), directBufferBo.getDirectMemoryUsed(), directBufferBo.getTimestamp()); - AgentStat mappedCount = new AgentStat("defaultTenantId", "applicationName", directBufferBo.getAgentId(), + AgentStat mappedCount = new AgentStat("defaultTenantId", "", "applicationName", directBufferBo.getAgentId(), AgentStatType.DIRECT_BUFFER.getChartType(), AgentStatField.DIRECT_BUFFER_MAPPED_COUNT.getFieldName(), directBufferBo.getMappedCount(), directBufferBo.getTimestamp()); - AgentStat mappedMemoryUsed = new AgentStat("defaultTenantId", "applicationName", directBufferBo.getAgentId(), + AgentStat mappedMemoryUsed = new AgentStat("defaultTenantId", "", "applicationName", directBufferBo.getAgentId(), AgentStatType.DIRECT_BUFFER.getChartType(), AgentStatField.DIRECT_BUFFER_MAPPED_MEMORY_USED.getFieldName(), directBufferBo.getMappedMemoryUsed(), directBufferBo.getTimestamp()); @@ -261,7 +263,7 @@ public static List convertDirectBufferToAgentStat(List convertTotalThreadCountToAgentStat(List totalThreadCountBoList) { List agentStatList = totalThreadCountBoList.stream() .flatMap(totalThreadCountBo -> { - AgentStat totalThreadCount = new AgentStat("defaultTenantId", "applicationName", totalThreadCountBo.getAgentId(), + AgentStat totalThreadCount = new AgentStat("defaultTenantId", "", "applicationName", totalThreadCountBo.getAgentId(), AgentStatType.TOTAL_THREAD.getChartType(), AgentStatField.TOTAL_THREAD_COUNT.getFieldName(), totalThreadCountBo.getTotalThreadCount(), totalThreadCountBo.getTimestamp()); @@ -277,10 +279,10 @@ public static List convertTotalThreadCountToAgentStat(List convertLoadedClassToAgentStat(List loadedClassBoList) { List agentStatList = loadedClassBoList.stream() .flatMap(loadedClassBo -> { - AgentStat loadedClassCount = new AgentStat("defaultTenantId", "applicationName", loadedClassBo.getAgentId(), + AgentStat loadedClassCount = new AgentStat("defaultTenantId", "", "applicationName", loadedClassBo.getAgentId(), AgentStatType.LOADED_CLASS.getChartType(), AgentStatField.CLASS_COUNT_LOAD.getFieldName(), loadedClassBo.getLoadedClassCount(), loadedClassBo.getTimestamp()); - AgentStat unloadedClassCount = new AgentStat("defaultTenantId", "applicationName", loadedClassBo.getAgentId(), + AgentStat unloadedClassCount = new AgentStat("defaultTenantId", "", "applicationName", loadedClassBo.getAgentId(), AgentStatType.LOADED_CLASS.getChartType(), AgentStatField.CLASS_COUNT_UN_LOADED.getFieldName(), loadedClassBo.getUnloadedClassCount(), loadedClassBo.getTimestamp()); @@ -306,11 +308,11 @@ public static List convertDataSourceToAgentStat(List convertDataSourceToAgentStat(List convertProfilerMetricToAgentStat(ProfilerMetricBo profilerMetricBo) { + List agentStats = new ArrayList<>(); + List tags = new ArrayList<>(); + profilerMetricBo.getTags().forEach((key, value) -> {tags.add(new Tag(key, value));}); + String agentId = profilerMetricBo.getAgentId(); + long timestamp = profilerMetricBo.getTimestamp() * 1000; + String metricName = profilerMetricBo.getMetricName(); + profilerMetricBo.getValues().forEach((key, value) -> { + AgentStat stat = new AgentStat("defaultTenantId", "", "applicationName", agentId, metricName, key, value, timestamp, tags); + agentStats.add(stat); + }); + return agentStats; + } + } diff --git a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/service/PinotAgentStatService.java b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/service/PinotAgentStatService.java index 8366a4372b05..2f6afa8f6b24 100644 --- a/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/service/PinotAgentStatService.java +++ b/inspector-module/inspector-collector/src/main/java/com/navercorp/pinpoint/inspector/collector/service/PinotAgentStatService.java @@ -18,7 +18,9 @@ import com.navercorp.pinpoint.collector.service.AgentStatService; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatBo; +import com.navercorp.pinpoint.common.server.bo.stat.ProfilerMetricBo; import com.navercorp.pinpoint.inspector.collector.dao.AgentStatDao; +import com.navercorp.pinpoint.inspector.collector.dao.pinot.ProfilerMetricDao; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Service; @@ -35,9 +37,11 @@ public class PinotAgentStatService implements AgentStatService { private final Logger logger = LogManager.getLogger(PinotAgentStatService.class.getName()); private final AgentStatDao[] agentStatDaoList; + private final ProfilerMetricDao profilerMetricDao; - public PinotAgentStatService(AgentStatDao[] agentStatDaoList) { + public PinotAgentStatService(AgentStatDao[] agentStatDaoList, ProfilerMetricDao profilerMetricDao) { this.agentStatDaoList = Objects.requireNonNull(agentStatDaoList, "agentStatDaoList"); + this.profilerMetricDao = Objects.requireNonNull(profilerMetricDao, "profilerMetricDao"); for (AgentStatDao agentStatDao : agentStatDaoList) { logger.info("AgentStatDaoV2:{}", agentStatDao.getClass().getSimpleName()); @@ -52,7 +56,11 @@ public void save(@Valid AgentStatBo agentStatBo) { } catch (Exception e) { logger.warn("Error inserting AgentStatBo to pinot. Caused:{}", e.getMessage(), e); } - } } + + @Override + public void save(ProfilerMetricBo profilerMetricBo) { + profilerMetricDao.dispatch(profilerMetricBo); + } } diff --git a/inspector-module/inspector-web/src/main/resources/inspector/web/inspector-definition.yml b/inspector-module/inspector-web/src/main/resources/inspector/web/inspector-definition.yml index f7b9b99561c7..2cd9f7aabbcd 100644 --- a/inspector-module/inspector-web/src/main/resources/inspector/web/inspector-definition.yml +++ b/inspector-module/inspector-web/src/main/resources/inspector/web/inspector-definition.yml @@ -228,4 +228,134 @@ mappings: - fieldName: "maxConnectionSize" matchingRule: ALL aggregationFunction: MAX - unit : "count" \ No newline at end of file + unit : "count" + - definitionId: "networkInterfaceInfo" + metricName: "network_interface" + title: "Network Interface Information" + grouping: "TAG" + fields: + - fieldName: "rx_packets" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "rx_errors" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "rx_drops" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "tx_packets" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "tx_errors" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "tx_collisions" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - definitionId: "networkInterfaceBytes" + metricName: "network_interface" + title: "Network Bytes" + grouping: "TAG" + fields: + - fieldName: "rx_bytes" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "byte" + - fieldName: "tx_bytes" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "byte" + - definitionId: "tcpStats" + metricName: "tcp_stats" + title: "TCP" + grouping: "TAG" + fields: + - fieldName: "conn_established" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "conn_active" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "conn_passive" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "conn_failure" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "conn_reset" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "seg_sent" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "seg_received" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "seg_retransmitted" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "in_errors" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "out_resets" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - definitionId: "udpStats" + metricName: "udp_stats" + title: "UDP" + grouping: "TAG" + fields: + - fieldName: "tx" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "rx" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "noport" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" + - fieldName: "rx_error" + matchingRule: ALL + aggregationFunction: SUM + chartType : "spline" + unit: "count" \ No newline at end of file diff --git a/profiler/pom.xml b/profiler/pom.xml index 0e1a5447eed4..1fb7ab06eb9c 100644 --- a/profiler/pom.xml +++ b/profiler/pom.xml @@ -84,6 +84,11 @@ com.github.ben-manes.caffeine caffeine + + com.github.oshi + oshi-core + 6.4.5 + diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcProfilerMetricMessageConverter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcProfilerMetricMessageConverter.java new file mode 100644 index 000000000000..8ef2443e695a --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcProfilerMetricMessageConverter.java @@ -0,0 +1,64 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.profiler.context.grpc; + +import com.navercorp.pinpoint.common.profiler.message.MessageConverter; +import com.navercorp.pinpoint.grpc.trace.PProfilerMetric; +import com.navercorp.pinpoint.grpc.trace.PProfilerMetricField; +import com.navercorp.pinpoint.profiler.monitor.metric.MetricType; +import com.navercorp.pinpoint.profiler.monitor.metric.profilermetric.Field; +import com.navercorp.pinpoint.profiler.monitor.metric.profilermetric.NetworkMetric; + +import java.util.List; + +public class GrpcProfilerMetricMessageConverter implements MessageConverter { + @Override + public PProfilerMetric toMessage(MetricType message) { + if (message instanceof NetworkMetric) { + return convertNetworkMetric((NetworkMetric) message); + } else { + return null; + } + } + + private PProfilerMetric convertNetworkMetric(NetworkMetric message) { + PProfilerMetric.Builder builder = PProfilerMetric.newBuilder(); + builder.setTimestamp(message.getTimestamp()); + builder.setCollectInterval(message.getCollectInterval()); + builder.setName(message.getName()); + addFields(builder, message.getFields()); + addTags(builder, message.getTags()); + return builder.build(); + } + + private void addFields(PProfilerMetric.Builder builder, List> fields) { + for(Field f : fields) { + PProfilerMetricField.Builder fieldBuilder = PProfilerMetricField.newBuilder(); + fieldBuilder.setName(f.getName()); + fieldBuilder.setLongValue(f.getValue()); + builder.addFields(fieldBuilder); + } + } + + private void addTags(PProfilerMetric.Builder builder, List> fields) { + for(Field f : fields) { + PProfilerMetricField.Builder fieldBuilder = PProfilerMetricField.newBuilder(); + fieldBuilder.setName(f.getName()); + fieldBuilder.setStringValue(f.getValue()); + builder.addTags(fieldBuilder); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcStatMessageConverter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcStatMessageConverter.java index b3960b305b4b..8f63c3af9dde 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcStatMessageConverter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcStatMessageConverter.java @@ -18,34 +18,10 @@ import com.google.protobuf.GeneratedMessageV3; import com.navercorp.pinpoint.common.profiler.message.MessageConverter; -import com.navercorp.pinpoint.grpc.trace.PActiveTrace; -import com.navercorp.pinpoint.grpc.trace.PActiveTraceHistogram; -import com.navercorp.pinpoint.grpc.trace.PAgentStat; -import com.navercorp.pinpoint.grpc.trace.PAgentStatBatch; -import com.navercorp.pinpoint.grpc.trace.PAgentUriStat; -import com.navercorp.pinpoint.grpc.trace.PCpuLoad; -import com.navercorp.pinpoint.grpc.trace.PCustomMetricMessage; -import com.navercorp.pinpoint.grpc.trace.PDataSource; -import com.navercorp.pinpoint.grpc.trace.PDataSourceList; -import com.navercorp.pinpoint.grpc.trace.PDeadlock; -import com.navercorp.pinpoint.grpc.trace.PDirectBuffer; -import com.navercorp.pinpoint.grpc.trace.PFileDescriptor; -import com.navercorp.pinpoint.grpc.trace.PJvmGc; -import com.navercorp.pinpoint.grpc.trace.PJvmGcDetailed; -import com.navercorp.pinpoint.grpc.trace.PJvmGcType; -import com.navercorp.pinpoint.grpc.trace.PLoadedClass; -import com.navercorp.pinpoint.grpc.trace.PResponseTime; -import com.navercorp.pinpoint.grpc.trace.PThreadDump; -import com.navercorp.pinpoint.grpc.trace.PTotalThread; -import com.navercorp.pinpoint.grpc.trace.PTransaction; +import com.navercorp.pinpoint.grpc.trace.*; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceHistogram; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceHistogramUtils; -import com.navercorp.pinpoint.profiler.monitor.metric.AgentCustomMetricSnapshotBatch; -import com.navercorp.pinpoint.profiler.monitor.metric.AgentStatMetricSnapshot; -import com.navercorp.pinpoint.profiler.monitor.metric.AgentStatMetricSnapshotBatch; -import com.navercorp.pinpoint.profiler.monitor.metric.JvmGcDetailedMetricSnapshot; -import com.navercorp.pinpoint.profiler.monitor.metric.JvmGcMetricSnapshot; -import com.navercorp.pinpoint.profiler.monitor.metric.MetricType; +import com.navercorp.pinpoint.profiler.monitor.metric.*; import com.navercorp.pinpoint.profiler.monitor.metric.buffer.BufferMetricSnapshot; import com.navercorp.pinpoint.profiler.monitor.metric.cpu.CpuLoadMetricSnapshot; import com.navercorp.pinpoint.profiler.monitor.metric.datasource.DataSource; @@ -54,6 +30,7 @@ import com.navercorp.pinpoint.profiler.monitor.metric.deadlock.ThreadDumpMetricSnapshot; import com.navercorp.pinpoint.profiler.monitor.metric.filedescriptor.FileDescriptorMetricSnapshot; import com.navercorp.pinpoint.profiler.monitor.metric.loadedclass.LoadedClassMetricSnapshot; +import com.navercorp.pinpoint.profiler.monitor.metric.profilermetric.ProfilerMetric; import com.navercorp.pinpoint.profiler.monitor.metric.response.ResponseTimeValue; import com.navercorp.pinpoint.profiler.monitor.metric.totalthread.TotalThreadMetricSnapshot; import com.navercorp.pinpoint.profiler.monitor.metric.transaction.TransactionMetricSnapshot; @@ -69,7 +46,7 @@ public class GrpcStatMessageConverter implements MessageConverter jvmGcTypeConverter = new GrpcJvmGcTypeMessageConverter(); private final MessageConverter customMetricMessageConverter = new GrpcCustomMetricMessageConverter(); private final MessageConverter uriStatMessageConverter = new GrpcUriStatMessageConverter(); - + private final MessageConverter profilerMetricConverter = new GrpcProfilerMetricMessageConverter(); @Override public GeneratedMessageV3 toMessage(MetricType message) { @@ -78,13 +55,13 @@ public GeneratedMessageV3 toMessage(MetricType message) { final PAgentStatBatch.Builder agentStatBatchBuilder = PAgentStatBatch.newBuilder(); // Skip agentId, startTimestamp for (AgentStatMetricSnapshot agentStatMetricSnapshot : agentStatMetricSnapshotBatch.getAgentStats()) { - final PAgentStat agentStat = converAgentStat(agentStatMetricSnapshot); + final PAgentStat agentStat = convertAgentStat(agentStatMetricSnapshot); agentStatBatchBuilder.addAgentStat(agentStat); } return agentStatBatchBuilder.build(); } else if (message instanceof AgentStatMetricSnapshot) { final AgentStatMetricSnapshot agentStatMetricSnapshot = (AgentStatMetricSnapshot) message; - final PAgentStat agentStat = converAgentStat(agentStatMetricSnapshot); + final PAgentStat agentStat = convertAgentStat(agentStatMetricSnapshot); return agentStat; } else if (message instanceof AgentCustomMetricSnapshotBatch) { final AgentCustomMetricSnapshotBatch agentCustomMetricSnapshotBatch = (AgentCustomMetricSnapshotBatch) message; @@ -94,11 +71,15 @@ public GeneratedMessageV3 toMessage(MetricType message) { final AgentUriStatData agentUriStatData = (AgentUriStatData) message; final PAgentUriStat agentUriStat = uriStatMessageConverter.toMessage(agentUriStatData); return agentUriStat; + } else if (message instanceof ProfilerMetric) { + final ProfilerMetric profilerMetricData = (ProfilerMetric) message; + final PProfilerMetric profilerMetricMessage = profilerMetricConverter.toMessage(profilerMetricData); + return profilerMetricMessage; } return null; } - private PAgentStat converAgentStat(final AgentStatMetricSnapshot agentStatMetricSnapshot) { + private PAgentStat convertAgentStat(final AgentStatMetricSnapshot agentStatMetricSnapshot) { final PAgentStat.Builder agentStatBuilder = PAgentStat.newBuilder(); agentStatBuilder.setTimestamp(agentStatMetricSnapshot.getTimestamp()); agentStatBuilder.setCollectInterval(agentStatMetricSnapshot.getCollectInterval()); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java index 69fca2b1d615..8eac9b61ad58 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java @@ -112,10 +112,7 @@ import com.navercorp.pinpoint.profiler.metadata.ApiMetaDataService; import com.navercorp.pinpoint.profiler.metadata.SqlMetaDataService; import com.navercorp.pinpoint.profiler.metadata.StringMetaDataService; -import com.navercorp.pinpoint.profiler.monitor.AgentStatMonitor; -import com.navercorp.pinpoint.profiler.monitor.DeadlockMonitor; -import com.navercorp.pinpoint.profiler.monitor.DeadlockThreadRegistry; -import com.navercorp.pinpoint.profiler.monitor.DefaultAgentStatMonitor; +import com.navercorp.pinpoint.profiler.monitor.*; import com.navercorp.pinpoint.profiler.monitor.metric.response.ResponseTimeCollector; import com.navercorp.pinpoint.profiler.monitor.metric.response.ReuseResponseTimeCollector; import com.navercorp.pinpoint.profiler.objectfactory.ObjectBinderFactory; @@ -212,6 +209,7 @@ protected void configure() { bind(DeadlockMonitor.class).toProvider(DeadlockMonitorProvider.class).in(Scopes.SINGLETON); bind(AgentInfoSender.class).toProvider(AgentInfoSenderProvider.class).in(Scopes.SINGLETON); bind(AgentStatMonitor.class).to(DefaultAgentStatMonitor.class).in(Scopes.SINGLETON); + bind(NetworkStatMonitor.class).to(DefaultNetworkStatMonitor.class).in(Scopes.SINGLETON); } private void bindTraceComponent() { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContext.java index bac2c6e87e65..5aa10607764e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContext.java @@ -46,6 +46,7 @@ import com.navercorp.pinpoint.profiler.interceptor.registry.InterceptorRegistryBinder; import com.navercorp.pinpoint.profiler.monitor.AgentStatMonitor; import com.navercorp.pinpoint.profiler.monitor.DeadlockMonitor; +import com.navercorp.pinpoint.profiler.monitor.NetworkStatMonitor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -66,6 +67,7 @@ public class DefaultApplicationContext implements ApplicationContext { private final DeadlockMonitor deadlockMonitor; private final AgentInfoSender agentInfoSender; private final AgentStatMonitor agentStatMonitor; + private final NetworkStatMonitor hwStatMonitor; private final TraceContext traceContext; @@ -131,6 +133,7 @@ public DefaultApplicationContext(AgentOption agentOption, ModuleFactory moduleFa this.deadlockMonitor = injector.getInstance(DeadlockMonitor.class); this.agentInfoSender = injector.getInstance(AgentInfoSender.class); this.agentStatMonitor = injector.getInstance(AgentStatMonitor.class); + this.hwStatMonitor = injector.getInstance(NetworkStatMonitor.class); } private void lambdaFactorySetup(Instrumentation instrumentation, ClassFileTransformModuleAdaptor classFileTransformer, JavaModuleFactory javaModuleFactory) { @@ -227,6 +230,7 @@ public void start() { this.deadlockMonitor.start(); this.agentInfoSender.start(); this.agentStatMonitor.start(); + this.hwStatMonitor.start(); } @Override @@ -234,6 +238,7 @@ public void close() { this.agentInfoSender.stop(); this.agentStatMonitor.stop(); this.deadlockMonitor.stop(); + this.hwStatMonitor.stop(); // Need to process stop if (rpcModuleLifeCycle != null) { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/config/DefaultMonitorConfig.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/config/DefaultMonitorConfig.java index 6bcaa61a72b2..86cdf3b74f4d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/config/DefaultMonitorConfig.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/config/DefaultMonitorConfig.java @@ -22,12 +22,22 @@ public class DefaultMonitorConfig implements MonitorConfig { public static final int DEFAULT_AGENT_STAT_COLLECTION_INTERVAL_MS = 5 * 1000; public static final int DEFAULT_NUM_AGENT_STAT_BATCH_SEND = 6; + public static final int DEFAULT_NETWORK_METRIC_COLLECTION_INTERVAL_MS = 5 * 1000; @Value("${profiler.custommetric.enable}") private boolean customMetricEnable = false; @Value("${profiler.custommetric.limit.size}") private int customMetricLimitSize = 10; + @Value("${profiler.network.metric.enable}") + private boolean networkMetricEnable = false; + @Value("${profiler.network.metric.enable.udpstats}") + private boolean udpStatsEnable = false; + @Value("${profiler.network.metric.enable.tcpstats}") + private boolean tcpStatsEnable = false; + @Value("${profiler.network.metric.collect.interval}") + private int networkMetricCollectIntervalMs = DEFAULT_NETWORK_METRIC_COLLECTION_INTERVAL_MS; + @Value("${profiler.uri.stat.enable}") private boolean uriStatEnable = false; @Value("${profiler.uri.stat.collect.http.method}") @@ -70,6 +80,26 @@ public int getCustomMetricLimitSize() { return customMetricLimitSize; } + @Override + public boolean isNetworkMetricEnable() { + return networkMetricEnable; + } + + @Override + public int getNetworkMetricCollectIntervalMs() { + return networkMetricCollectIntervalMs; + } + + @Override + public boolean isUdpStatsEnable() { + return udpStatsEnable; + } + + @Override + public boolean isTcpStatsEnable() { + return tcpStatsEnable; + } + @Override public boolean isUriStatEnable() { return uriStatEnable; diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/config/MonitorConfig.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/config/MonitorConfig.java index 6aee52a2dea3..087b3e25b8a5 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/config/MonitorConfig.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/config/MonitorConfig.java @@ -27,6 +27,14 @@ public interface MonitorConfig { int getCustomMetricLimitSize(); + boolean isNetworkMetricEnable(); + + int getNetworkMetricCollectIntervalMs(); + + boolean isUdpStatsEnable(); + + boolean isTcpStatsEnable(); + boolean isUriStatEnable(); boolean getUriStatCollectHttpMethod(); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultNetworkStatMonitor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultNetworkStatMonitor.java new file mode 100644 index 000000000000..e75fc99ca992 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultNetworkStatMonitor.java @@ -0,0 +1,94 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.profiler.monitor; + +import com.google.inject.Inject; +import com.navercorp.pinpoint.common.profiler.concurrent.PinpointThreadFactory; +import com.navercorp.pinpoint.common.profiler.message.DataSender; +import com.navercorp.pinpoint.common.util.StringUtils; +import com.navercorp.pinpoint.profiler.context.module.ApplicationName; +import com.navercorp.pinpoint.profiler.context.module.StatDataSender; +import com.navercorp.pinpoint.profiler.context.monitor.config.DefaultMonitorConfig; +import com.navercorp.pinpoint.profiler.context.monitor.config.MonitorConfig; +import com.navercorp.pinpoint.profiler.monitor.metric.MetricType; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class DefaultNetworkStatMonitor implements NetworkStatMonitor { + private static final long MIN_COLLECTION_INTERVAL_MS = 1000 * 5; + private static final long MAX_COLLECTION_INTERVAL_MS = 1000 * 10; + private static final long DEFAULT_COLLECTION_INTERVAL_MS = DefaultMonitorConfig.DEFAULT_NETWORK_METRIC_COLLECTION_INTERVAL_MS; + + private final Logger logger = LogManager.getLogger(this.getClass()); + private final long collectionIntervalMs; + private final StatMonitorJob statMonitorJob; + private final ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1, new PinpointThreadFactory("Pinpoint-hw-stat-monitor", true)); + private final boolean isNetworkMetricEnable; + + @Inject + public DefaultNetworkStatMonitor(@StatDataSender DataSender dataSender, + MonitorConfig monitorConfig) { + long collectionIntervalMs = monitorConfig.getNetworkMetricCollectIntervalMs(); + + if (collectionIntervalMs < MIN_COLLECTION_INTERVAL_MS) { + collectionIntervalMs = DEFAULT_COLLECTION_INTERVAL_MS; + } + if (collectionIntervalMs > MAX_COLLECTION_INTERVAL_MS) { + collectionIntervalMs = DEFAULT_COLLECTION_INTERVAL_MS; + } + + this.collectionIntervalMs = collectionIntervalMs; + List runnableList = new ArrayList<>(); + this.isNetworkMetricEnable = monitorConfig.isNetworkMetricEnable(); + + if (isNetworkMetricEnable && NetworkMetricCollectingJob.isSupported()) { + Runnable networkMetricCollectingJob = new NetworkMetricCollectingJob(dataSender, + monitorConfig.isUdpStatsEnable(), monitorConfig.isTcpStatsEnable(), collectionIntervalMs); + runnableList.add(networkMetricCollectingJob); + } + this.statMonitorJob = new StatMonitorJob(runnableList); + + } + @Override + public void start() { + if (isNetworkMetricEnable) { + executor.scheduleAtFixedRate(statMonitorJob, this.collectionIntervalMs, this.collectionIntervalMs, TimeUnit.MILLISECONDS); + logger.info("HW stat monitor started"); + } else { + logger.info("HW stat monitor disabled"); + } + } + + @Override + public void stop() { + if (isNetworkMetricEnable) { + statMonitorJob.close(); + executor.shutdown(); + try { + executor.awaitTermination(3000, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + logger.info("HW stat monitor stopped"); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/NetworkMetricCollectingJob.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/NetworkMetricCollectingJob.java new file mode 100644 index 000000000000..5ee8f8b45699 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/NetworkMetricCollectingJob.java @@ -0,0 +1,257 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.profiler.monitor; + +import com.navercorp.pinpoint.common.profiler.clock.Clock; +import com.navercorp.pinpoint.common.profiler.message.DataSender; +import com.navercorp.pinpoint.profiler.monitor.metric.MetricType; +import com.navercorp.pinpoint.profiler.monitor.metric.profilermetric.NetworkMetric; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import oshi.PlatformEnum; +import oshi.SystemInfo; +import oshi.hardware.HardwareAbstractionLayer; +import oshi.hardware.NetworkIF; +import oshi.software.os.OperatingSystem; +import oshi.software.os.InternetProtocolStats; + +import java.util.*; + +public class NetworkMetricCollectingJob implements Runnable { + private final Logger logger = LogManager.getLogger(this.getClass()); + private boolean networkInterfaceSupported = true; + private boolean udpStatSupported; + private boolean tcpStatSupported; + private final Clock clock = Clock.tick(1000); + private final long collectInterval; + private final DataSender dataSender; + + private String hostName; + private InternetProtocolStats protocolStats; + private NetworkInterfaceInfo currNetworkIFs = null; + private NetworkInterfaceInfo prevNetworkIFs = null; + private InternetProtocolStats.TcpStats prevTcpV4Stats = null; + private InternetProtocolStats.TcpStats prevTcpV6Stats = null; + private InternetProtocolStats.UdpStats prevUdpV4Stats = null; + private InternetProtocolStats.UdpStats prevUdpV6Stats = null; + + private class NetworkInterfaceInfo { + private Map parsed; + + public NetworkInterfaceInfo(HardwareAbstractionLayer hal) { + List networkIFs = hal.getNetworkIFs(); + this.parsed = new HashMap<>(); + + for (NetworkIF networkIF : networkIFs) { + this.parsed.put(networkIF.getName(), networkIF); + } + } + + public NetworkIF getNetworkIF(String name) { + return parsed.get(name); + } + + public Collection getCollection() { + return parsed.values(); + } + } + + public NetworkMetricCollectingJob(DataSender dataSender, + boolean enableUdpStat, boolean enableTcpStat, long collectInterval) { + this.dataSender = Objects.requireNonNull(dataSender, "dataSender"); + this.udpStatSupported = enableUdpStat; + this.tcpStatSupported = enableTcpStat; + this.collectInterval = collectInterval; + + SystemInfo si = new SystemInfo(); + OperatingSystem os = si.getOperatingSystem(); + this.hostName = os.getNetworkParams().getHostName(); + + initializeNetworkInterfaceInfo(si); + + if (udpStatSupported || tcpStatSupported) { + initializeProtocolStats(os); + } + } + + private void initializeProtocolStats(OperatingSystem os) { + this.protocolStats = os.getInternetProtocolStats(); + try { + protocolStats.getTCPv4Stats(); + protocolStats.getTCPv6Stats(); + } catch (Exception e) { + udpStatSupported = false; + tcpStatSupported = false; + if (logger.isWarnEnabled()) { + logger.warn("OSHI Protocol Statistics not supported. Not collecting protocol stat metrics."); + } + } + } + + private void initializeNetworkInterfaceInfo(SystemInfo si) { + HardwareAbstractionLayer hal = si.getHardware(); + try { + currNetworkIFs = new NetworkInterfaceInfo(hal); + prevNetworkIFs = new NetworkInterfaceInfo(hal); + } catch (Exception e) { + networkInterfaceSupported = false; + if (logger.isWarnEnabled()) { + logger.warn("OSHI Network Interface not supported. Not collecting network interface metrics."); + } + } + + if (currNetworkIFs == null || prevNetworkIFs == null) { + networkInterfaceSupported = false; + } + } + + public static boolean isSupported() { + return !SystemInfo.getCurrentPlatform().equals(PlatformEnum.UNKNOWN); + } + + @Override + public void run() { + if (networkInterfaceSupported) { + checkNetworkIfs(); + } + + if (tcpStatSupported) { + addTCPProtocolStats(); + } + + if (udpStatSupported) { + addUDPProtocolStats(); + } + } + + private void checkNetworkIfs() { + long timestamp = clock.millis() / 1000L; + + for (NetworkIF networkIF : currNetworkIFs.getCollection()) { + if (networkIF.updateAttributes()) { + NetworkIF prev = prevNetworkIFs.getNetworkIF(networkIF.getName()); + + NetworkMetric metric = getMetricData(networkIF, prev, timestamp); + if (metric != null) { + dataSender.send(metric); + } + } else { + if (logger.isWarnEnabled()) { + logger.warn("Failed to update current values for network interfaces"); + } + } + } + + NetworkInterfaceInfo temp = currNetworkIFs; + currNetworkIFs = prevNetworkIFs; + prevNetworkIFs = temp; + } + + private NetworkMetric getMetricData(NetworkIF curr, NetworkIF prev, long timestamp) { + if (prev == null) { + return null; + } + + NetworkMetric metric = new NetworkMetric("network_interface", timestamp, collectInterval); + metric.addTag("name", curr.getName()); + metric.addTag("mac_addr", curr.getMacaddr()); + metric.addTag("host", this.hostName); + metric.addField("rx_packets", (curr.getPacketsRecv() - prev.getPacketsRecv())); + metric.addField("rx_bytes", (curr.getBytesRecv() - prev.getBytesRecv())); + metric.addField("rx_errors", (curr.getInErrors() - prev.getInErrors())); + metric.addField("rx_drops", (curr.getInDrops() - prev.getInDrops())); + metric.addField("tx_packets", (curr.getPacketsSent() - prev.getPacketsSent())); + metric.addField("tx_bytes", (curr.getBytesSent() - prev.getBytesSent())); + metric.addField("tx_errors", (curr.getOutErrors() - prev.getOutErrors())); + metric.addField("tx_collisions", (curr.getCollisions() - prev.getCollisions())); + return metric; + } + + private void addTCPProtocolStats() { + long timestamp = clock.millis() / 1000L; + InternetProtocolStats.TcpStats tcpv4 = protocolStats.getTCPv4Stats(); + InternetProtocolStats.TcpStats tcpv6 = protocolStats.getTCPv6Stats(); + + NetworkMetric metric = getMetricData("v4", tcpv4, prevTcpV4Stats, timestamp); + if (metric != null) { + dataSender.send(metric); + } + + metric = getMetricData("v6", tcpv6, prevTcpV6Stats, timestamp); + if (metric != null) { + dataSender.send(metric); + } + + prevTcpV4Stats = tcpv4; + prevTcpV6Stats = tcpv6; + } + + private void addUDPProtocolStats() { + long timestamp = clock.millis() / 1000L; + InternetProtocolStats.UdpStats udpv4 = protocolStats.getUDPv4Stats(); + InternetProtocolStats.UdpStats udpv6 = protocolStats.getUDPv6Stats(); + + NetworkMetric metric = getMetricData("v4", udpv4, prevUdpV4Stats, timestamp); + if (metric != null) { + dataSender.send(metric); + } + + metric = getMetricData("v6", udpv6, prevUdpV6Stats, timestamp); + if (metric != null) { + dataSender.send(metric); + } + + prevUdpV4Stats = protocolStats.getUDPv4Stats(); + prevUdpV6Stats = protocolStats.getUDPv6Stats(); + } + + private NetworkMetric getMetricData(String version, InternetProtocolStats.TcpStats tcpStats, InternetProtocolStats.TcpStats prev, long timestamp) { + if (prev == null) { + return null; + } + + NetworkMetric metric = new NetworkMetric("tcp_stats", timestamp, collectInterval); + metric.addTag("version", version); + metric.addTag("host", this.hostName); + metric.addField("conn_established", tcpStats.getConnectionsEstablished()); + metric.addField("conn_active", tcpStats.getConnectionsActive()); + metric.addField("conn_passive", tcpStats.getConnectionsPassive()); + metric.addField("conn_failure", tcpStats.getConnectionFailures()); + metric.addField("conn_reset", tcpStats.getConnectionsReset()); + metric.addField("seg_sent", (tcpStats.getSegmentsSent() - prev.getSegmentsSent())); + metric.addField("seg_received", (tcpStats.getSegmentsReceived() - prev.getSegmentsReceived())); + metric.addField("seg_retransmitted", (tcpStats.getSegmentsRetransmitted() - prev.getSegmentsRetransmitted())); + metric.addField("in_errors", (tcpStats.getInErrors() - prev.getInErrors())); + metric.addField("out_resets", (tcpStats.getOutResets() - prev.getOutResets())); + return metric; + } + + private NetworkMetric getMetricData(String version, InternetProtocolStats.UdpStats udpStats, InternetProtocolStats.UdpStats prev, long timestamp) { + if (prev == null) { + return null; + } + + NetworkMetric metric = new NetworkMetric("udp_stats", timestamp, collectInterval); + metric.addTag("version", version); + metric.addTag("host", this.hostName); + metric.addField("tx", (udpStats.getDatagramsSent() - prev.getDatagramsSent())); + metric.addField("rx", (udpStats.getDatagramsReceived() - prev.getDatagramsReceived())); + metric.addField("noport", (udpStats.getDatagramsNoPort() - prev.getDatagramsNoPort())); + metric.addField("rx_error", (udpStats.getDatagramsReceivedErrors() - prev.getDatagramsReceivedErrors())); + return metric; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/NetworkStatMonitor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/NetworkStatMonitor.java new file mode 100644 index 000000000000..d792dcf6e753 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/NetworkStatMonitor.java @@ -0,0 +1,23 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.profiler.monitor; + +public interface NetworkStatMonitor { + void start(); + + void stop(); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/Field.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/Field.java new file mode 100644 index 000000000000..0af2dfd63aae --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/Field.java @@ -0,0 +1,27 @@ +package com.navercorp.pinpoint.profiler.monitor.metric.profilermetric; + +import java.util.Objects; + + +public class Field { + private final String name; + private final T value; + + public Field(String name, T value) { + this.name = Objects.requireNonNull(name, "name"); + this.value = value; + } + + public String getName() { + return name; + } + + public T getValue() { + return value; + } + + @Override + public String toString() { + return name + ":" + value; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/NetworkMetric.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/NetworkMetric.java new file mode 100644 index 000000000000..2afe3352941b --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/NetworkMetric.java @@ -0,0 +1,95 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.profiler.monitor.metric.profilermetric; + +import com.navercorp.pinpoint.profiler.monitor.metric.MetricType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class NetworkMetric implements ProfilerMetric { + private final Fields fields; + private final String name; + private final Fields tags; + private final long timestamp; + private final long collectInterval; + + public NetworkMetric(String name, long timestamp, long collectInterval) { + this.fields = new Fields<>(); + this.name = Objects.requireNonNull(name, "name"); + this.tags = new Fields<>(); + this.timestamp = timestamp; + this.collectInterval = collectInterval; + } + + public void addField(String name, Long value) { + this.fields.add(name, value); + } + + public void addTag(String name, String value) { + this.tags.add(name, value); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"fields\":").append(fields); + sb.append(",\"name\":").append("\"" + name + "\""); + sb.append(",\"tags\":").append(tags); + sb.append(",\"timestamp\":").append(timestamp); + sb.append("}"); + return sb.toString(); + } + + public long getTimestamp() { + return timestamp; + } + + public String getName() { + return name; + } + + public List> getFields() { + return fields.getFields(); + } + + public List> getTags() { + return tags.getFields(); + } + + public long getCollectInterval() { + return collectInterval; + } + + + public class Fields { + List> fields; + + public Fields() { + fields = new ArrayList<>(); + } + + public void add(String name, T value) { + fields.add(new Field<>(name, value)); + } + + public List> getFields() { + return fields; + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/ProfilerMetric.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/ProfilerMetric.java new file mode 100644 index 000000000000..e18db3de5bb2 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/profilermetric/ProfilerMetric.java @@ -0,0 +1,6 @@ +package com.navercorp.pinpoint.profiler.monitor.metric.profilermetric; + +import com.navercorp.pinpoint.profiler.monitor.metric.MetricType; + +public interface ProfilerMetric extends MetricType { +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/grpc/StatGrpcDataSender.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/grpc/StatGrpcDataSender.java index f54d1301c80b..5abc029c8cb5 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/grpc/StatGrpcDataSender.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/grpc/StatGrpcDataSender.java @@ -27,6 +27,7 @@ import com.navercorp.pinpoint.grpc.trace.PCustomMetricMessage; import com.navercorp.pinpoint.grpc.trace.PStatMessage; import com.navercorp.pinpoint.grpc.trace.StatGrpc; +import com.navercorp.pinpoint.grpc.trace.PProfilerMetric; import com.navercorp.pinpoint.profiler.monitor.metric.MetricType; import com.navercorp.pinpoint.profiler.sender.grpc.stream.ClientStreamingProvider; import com.navercorp.pinpoint.profiler.sender.grpc.stream.DefaultStreamTask; @@ -85,8 +86,12 @@ public void onDispatch(ClientCallStreamObserver stream, MetricType if (message instanceof PAgentUriStat) { final PAgentUriStat agentUriStat = (PAgentUriStat) message; final PStatMessage statMessage = PStatMessage.newBuilder().setAgentUriStat(agentUriStat).build(); - - // TODO remove comment + stream.onNext(statMessage); + return; + } + if (message instanceof PProfilerMetric) { + final PProfilerMetric profilerMetric = (PProfilerMetric) message; + final PStatMessage statMessage = PStatMessage.newBuilder().setProfilerMetric(profilerMetric).build(); stream.onNext(statMessage); return; } diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DefaultTBaseLocator.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DefaultTBaseLocator.java index 0cfd569fd154..3b5302127527 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DefaultTBaseLocator.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DefaultTBaseLocator.java @@ -57,6 +57,9 @@ public class DefaultTBaseLocator { // Only supports Grpc public static final short AGENT_URI_STAT = 57; + // Only supports Grpc + public static final short AGENT_PROFILER_STAT = 58; + public static final short SPANCHUNK = 70; public static final short SPANEVENT = 80;