/* * Copyright 2017 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.profiler.monitor.collector.AgentStatMetricCollector; import com.navercorp.pinpoint.profiler.sender.DataSender; import com.navercorp.pinpoint.thrift.dto.TAgentStat; import com.navercorp.pinpoint.thrift.dto.TAgentStatBatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; /** * @author Woonduk Kang(emeroad) */ public class CollectJob implements Runnable { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final DataSender dataSender; private final String agentId; private final long agentStartTimestamp; private final AgentStatMetricCollector<TAgentStat> agentStatCollector; private final int numCollectionsPerBatch; // Not thread safe. For use with single thread ONLY private int collectCount = 0; private long prevCollectionTimestamp = System.currentTimeMillis(); private List<TAgentStat> agentStats; public CollectJob(DataSender dataSender, String agentId, long agentStartTimestamp, AgentStatMetricCollector<TAgentStat> agentStatCollector, int numCollectionsPerBatch) { if (dataSender == null) { throw new NullPointerException("dataSender must not be null"); } this.dataSender = dataSender; this.agentId = agentId; this.agentStartTimestamp = agentStartTimestamp; this.agentStatCollector = agentStatCollector; this.numCollectionsPerBatch = numCollectionsPerBatch; this.agentStats = new ArrayList<TAgentStat>(numCollectionsPerBatch); } @Override public void run() { final long currentCollectionTimestamp = System.currentTimeMillis(); final long collectInterval = currentCollectionTimestamp - this.prevCollectionTimestamp; try { final TAgentStat agentStat = agentStatCollector.collect(); agentStat.setTimestamp(currentCollectionTimestamp); agentStat.setCollectInterval(collectInterval); this.agentStats.add(agentStat); if (++this.collectCount >= numCollectionsPerBatch) { sendAgentStats(); this.collectCount = 0; } } catch (Exception ex) { logger.warn("AgentStat collect failed. Caused:{}", ex.getMessage(), ex); } finally { this.prevCollectionTimestamp = currentCollectionTimestamp; } } private void sendAgentStats() { // prepare TAgentStat object. // TODO multi thread issue. // If we reuse TAgentStat, there could be concurrency issue because data sender runs in a different thread. final TAgentStatBatch agentStatBatch = new TAgentStatBatch(); agentStatBatch.setAgentId(agentId); agentStatBatch.setStartTimestamp(agentStartTimestamp); agentStatBatch.setAgentStats(this.agentStats); // If we reuse agentStats list, there could be concurrency issue because data sender runs in a different // thread. // So create new list. this.agentStats = new ArrayList<TAgentStat>(numCollectionsPerBatch); logger.trace("collect agentStat:{}", agentStatBatch); dataSender.send(agentStatBatch); } }