/** * Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com) * * 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.linkedin.pinot.transport.metrics; import java.util.Collection; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import com.linkedin.pinot.common.metrics.AggregatedHistogram; import com.linkedin.pinot.common.metrics.LatencyMetric; import com.yammer.metrics.core.Sampling; import com.yammer.metrics.core.Summarizable; public class AggregatedPoolStats<T extends Sampling & Summarizable> implements PoolStats<T>, PoolStatsProvider { private final long DEFAULT_REFRESH_MS = 60 * 1000; // 1 minute // Refresh Delay config private final long _refreshMs; // Last Refreshed timestamp private volatile long _lastRefreshedTime; private volatile int _totalCreated; private volatile int _totalDestroyed; private volatile int _totalCreateErrors; private volatile int _totalDestroyErrors; private volatile int _totalBadDestroyed; private volatile int _totalTimedOut; private volatile int _checkedOut; private volatile int _maxPoolSize; private volatile int _minPoolSize; private volatile int _poolSize; private volatile int _sampleMaxCheckedOut; private volatile int _sampleMaxPoolSize; private volatile int _idleCount; private volatile LatencyMetric<T> _waitTime; private volatile LifecycleStats<T> _lifecycleStats; private final List<PoolStatsProvider> _poolStatsProvider = new CopyOnWriteArrayList<PoolStatsProvider>(); public AggregatedPoolStats(long refreshMs) { _refreshMs = refreshMs; } public AggregatedPoolStats() { _refreshMs = DEFAULT_REFRESH_MS; } public AggregatedPoolStats<T> addAll(Collection<PoolStatsProvider> poolStats) { _poolStatsProvider.addAll(poolStats); return this; } public AggregatedPoolStats<T> add(PoolStatsProvider poolStat) { _poolStatsProvider.add(poolStat); return this; } public void refreshIfElapsed() { long currentTime = System.currentTimeMillis(); if (currentTime - _lastRefreshedTime > _refreshMs && !_poolStatsProvider.isEmpty()) { refresh(); _lastRefreshedTime = currentTime; } } public void refresh() { int totalCreated = 0; int totalDestroyed = 0; int totalCreateErrors = 0; int totalDestroyErrors = 0; int totalBadDestroyed = 0; int totalTimedOut = 0; int checkedOut = 0; int maxPoolSize = 0; int minPoolSize = 0; int poolSize = 0; int sampleMaxCheckedOut = 0; int sampleMaxPoolSize = 0; int idleCount = 0; AggregatedHistogram<Sampling> waitTimeHist = new AggregatedHistogram<Sampling>(); AggregatedHistogram<Sampling> createTimeHist = new AggregatedHistogram<Sampling>(); for (PoolStatsProvider p : _poolStatsProvider) { PoolStats<T> s = p.getStats(); totalCreated += s.getTotalCreated(); totalDestroyed += s.getTotalBadDestroyed(); totalCreateErrors += s.getTotalCreateErrors(); totalDestroyErrors += s.getTotalDestroyErrors(); totalBadDestroyed += s.getTotalBadDestroyed(); totalTimedOut += s.getTotalTimedOut(); checkedOut += s.getCheckedOut(); maxPoolSize += s.getMaxPoolSize(); minPoolSize += s.getMinPoolSize(); poolSize += s.getPoolSize(); sampleMaxCheckedOut += s.getSampleMaxCheckedOut(); sampleMaxPoolSize += s.getSampleMaxPoolSize(); idleCount += s.getIdleCount(); waitTimeHist.add(s.getWaitTime().getHistogram()); createTimeHist.add(s.getLifecycleStats().getCreateTime().getHistogram()); } _totalCreated = totalCreated; _totalDestroyed = totalDestroyed; _totalBadDestroyed = totalBadDestroyed; _totalCreateErrors = totalCreateErrors; _totalDestroyErrors = totalDestroyErrors; _totalTimedOut = totalTimedOut; _checkedOut = checkedOut; _maxPoolSize = maxPoolSize; _minPoolSize = minPoolSize; _poolSize = poolSize; _sampleMaxCheckedOut = sampleMaxCheckedOut; _sampleMaxPoolSize = sampleMaxPoolSize; _idleCount = idleCount; _waitTime = new LatencyMetric(waitTimeHist); _lifecycleStats = new LifecycleStats(new LatencyMetric<AggregatedHistogram<Sampling>>(createTimeHist)); } @Override public int getTotalCreated() { refreshIfElapsed(); return _totalCreated; } @Override public int getTotalDestroyed() { refreshIfElapsed(); return _totalDestroyed; } @Override public int getTotalCreateErrors() { refreshIfElapsed(); return _totalCreateErrors; } @Override public int getTotalDestroyErrors() { refreshIfElapsed(); return _totalDestroyErrors; } @Override public int getTotalBadDestroyed() { refreshIfElapsed(); return _totalBadDestroyed; } @Override public int getTotalTimedOut() { refreshIfElapsed(); return _totalTimedOut; } @Override public int getCheckedOut() { refreshIfElapsed(); return _checkedOut; } @Override public int getMaxPoolSize() { refreshIfElapsed(); return _maxPoolSize; } @Override public int getMinPoolSize() { refreshIfElapsed(); return _minPoolSize; } @Override public int getPoolSize() { refreshIfElapsed(); return _poolSize; } @Override public int getSampleMaxCheckedOut() { refreshIfElapsed(); return _sampleMaxCheckedOut; } @Override public int getSampleMaxPoolSize() { refreshIfElapsed(); return _sampleMaxPoolSize; } @Override public int getIdleCount() { refreshIfElapsed(); return _idleCount; } @Override public LatencyMetric<T> getWaitTime() { refreshIfElapsed(); return _waitTime; } @Override public LifecycleStats<T> getLifecycleStats() { refreshIfElapsed(); return _lifecycleStats; } @Override public PoolStats<T> getStats() { return this; } @Override public String toString() { return "AggregatedPoolStats [_refreshMs=" + _refreshMs + ", _lastRefreshedTime=" + _lastRefreshedTime + ", _totalCreated=" + _totalCreated + ", _totalDestroyed=" + _totalDestroyed + ", _totalCreateErrors=" + _totalCreateErrors + ", _totalDestroyErrors=" + _totalDestroyErrors + ", _totalBadDestroyed=" + _totalBadDestroyed + ", _totalTimedOut=" + _totalTimedOut + ", _checkedOut=" + _checkedOut + ", _maxPoolSize=" + _maxPoolSize + ", _minPoolSize=" + _minPoolSize + ", _poolSize=" + _poolSize + ", _sampleMaxCheckedOut=" + _sampleMaxCheckedOut + ", _sampleMaxPoolSize=" + _sampleMaxPoolSize + ", _idleCount=" + _idleCount + ", _waitTime=" + _waitTime + ", _lifecycleStats=" + _lifecycleStats + ", _poolStatsProvider=" + _poolStatsProvider + "]"; } }