package com.intuit.tank.harness; /* * #%L * Intuit Tank Agent (apiharness) * %% * Copyright (C) 2011 - 2015 Intuit Inc. * %% * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * #L% */ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.intuit.tank.http.BaseRequest; import com.intuit.tank.reporting.api.TPSInfo; import com.intuit.tank.reporting.api.TPSInfoContainer; import com.intuit.tank.vm.settings.TimeUtil; public class TPSMonitor { @SuppressWarnings("unused") private static Logger LOG = LogManager.getLogger(TPSMonitor.class); private int period; private List<Counter> counters; private List<TPSInfo> infoList = new ArrayList<TPSInfo>(); private Date minDate; public TPSMonitor(int period) { super(); this.counters = Collections.synchronizedList(new ArrayList<TPSMonitor.Counter>()); this.period = period; } public boolean isEnabled() { return period > 0; } /** * @return the tpsMap */ public TPSInfoContainer getTPSInfo() { TPSInfoContainer ret = null; if (isEnabled()) { long now = TimeUtil.normalizeToPeriod(period, new Date()).getTime(); long min = now; long max = 0; Map<Long, Map<String, Integer>> tpsMap = new ConcurrentHashMap<Long, Map<String, Integer>>(); List<Counter> toRemove = new ArrayList<TPSMonitor.Counter>(); List<Counter> subList = new ArrayList<TPSMonitor.Counter>(counters); for (Counter counter : subList) { long entryTime = counter.time; if (now > (entryTime + (period * 4))) { min = Math.min(min, entryTime); max = Math.max(max, entryTime); Map<String, Integer> map = tpsMap.get(counter.time); if (map == null) { map = new HashMap<String, Integer>(); tpsMap.put(counter.time, map); } Integer integer = map.get(counter.key); if (integer == null) { integer = new Integer(0); map.put(counter.key, integer); } map.put(counter.key, integer + 1); toRemove.add(counter); } } if (!toRemove.isEmpty()) { counters.removeAll(toRemove); } for (Entry<Long, Map<String, Integer>> entry : tpsMap.entrySet()) { for (Entry<String, Integer> valueEntry : entry.getValue().entrySet()) { TPSInfo info = new TPSInfo(new Date(entry.getKey()), valueEntry.getKey(), valueEntry.getValue() .intValue(), period); infoList.add(info); } } if (max == 0) { // no data yet ret = new TPSInfoContainer(new Date(min), new Date(min), period, infoList); } else { if (minDate == null) { minDate = new Date(min); } ret = new TPSInfoContainer(minDate, new Date(max), period, infoList); } } return ret; } public void addToMap(final String loggingKey, final BaseRequest req) { if (isEnabled()) { // LOG.info("Adding request " + req.getTimeStamp()); new Thread(new Runnable() { @Override public void run() { if (req != null && req.getTimeStamp() != null) { Date targetDate = TimeUtil.normalizeToPeriod(period, req.getTimeStamp()); // LOG.info("Adding normalized " + targetDate); counters.add(new Counter(loggingKey, targetDate)); } } }).start(); } } private static class Counter { private String key; private long time; public Counter(String key, Date date) { super(); this.key = key; this.time = date.getTime(); } } }