private void add(@NonNull Container container, String name, LoadStatistics stats) { // A headless environment may be missing the fonts required for these graphs, so even though // we should be able to generate graphs from a headless environment we will skip the graphs // if headless boolean headless = GraphicsEnvironment.isHeadless(); for (MultiStageTimeSeries.TimeScale scale : MultiStageTimeSeries.TimeScale.values()) { String scaleName = scale.name().toLowerCase(Locale.ENGLISH); if (!headless) { BufferedImage image = stats.createTrendChart(scale).createChart().createBufferedImage(500, 400); container.add(new ImageContent(String.format("load-stats/%s/%s.png", name, scaleName), image)); } container.add(new CsvContent(String.format("load-stats/%s/%s.csv", name, scaleName), stats, scale)); } // on the other hand, if headless we should give an easy way to generate the graphs if (headless) { container.add(new GnuPlotScript(String.format("load-stats/%s/gnuplot", name))); } }
public CsvContent(String name, LoadStatistics stats, MultiStageTimeSeries.TimeScale scale) { super(name); time = System.currentTimeMillis(); clock = scale.tick; data = new TreeMap<String, float[]>(); for (Field f : FIELDS) { try { MultiStageTimeSeries ts = (MultiStageTimeSeries) f.get(stats); if (ts != null) { TimeSeries series = ts.pick(scale); if (series != null) { data.put(camelCaseToSentenceCase(f.getName()), series.getHistory()); } } } catch (IllegalAccessException e) { continue; } } }
private StrategyDecision applyFoCloud(@Nonnull NodeProvisioner.StrategyState state, DockerCloud cloud) { final Label label = state.getLabel(); if (!cloud.canProvision(label)) { return CONSULT_REMAINING_STRATEGIES; } LoadStatistics.LoadStatisticsSnapshot snapshot = state.getSnapshot(); LOGGER.log(FINEST, "Available executors={0}, connecting={1}, planned={2}", new Object[]{snapshot.getAvailableExecutors(), snapshot.getConnectingExecutors(), state.getPlannedCapacitySnapshot()}); int availableCapacity = snapshot.getAvailableExecutors() + snapshot.getConnectingExecutors() + state.getPlannedCapacitySnapshot(); int currentDemand = snapshot.getQueueLength(); LOGGER.log(FINE, "Available capacity={0}, currentDemand={1}", new Object[]{availableCapacity, currentDemand}); if (availableCapacity < currentDemand) { Collection<NodeProvisioner.PlannedNode> plannedNodes = cloud.provision(label, currentDemand - availableCapacity); LOGGER.log(FINE, "Planned {0} new nodes", plannedNodes.size()); state.recordPendingLaunches(plannedNodes); availableCapacity += plannedNodes.size(); LOGGER.log(FINE, "After provisioning, available capacity={0}, currentDemand={1}", new Object[]{availableCapacity, currentDemand}); } if (availableCapacity >= currentDemand) { LOGGER.log(FINE, "Provisioning completed"); return PROVISIONING_COMPLETED; } else { LOGGER.log(FINE, "Provisioning not complete, consulting remaining strategies"); return CONSULT_REMAINING_STRATEGIES; } }
/** * The fields that a {@link LoadStatistics} has change as you move from pre-1.607 to post 1.607, so better to * just look and see what there is rather than hard-code. * * @return the fields that correspond to {@link MultiStageTimeSeries} */ private static List<Field> findFields() { List<Field> result = new ArrayList<Field>(); for (Field f : LoadStatistics.class.getFields()) { if (Modifier.isPublic(f.getModifiers()) && MultiStageTimeSeries.class.isAssignableFrom(f.getType()) && f.getAnnotation(Deprecated.class) == null) { result.add(f); } } return result; }