/*******************************************************************************
* Copyright (c) 2011 The Board of Trustees of the Leland Stanford Junior University
* as Operator of the SLAC National Accelerator Laboratory.
* Copyright (c) 2011 Brookhaven National Laboratory.
* EPICS archiver appliance is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*******************************************************************************/
package org.epics.archiverappliance.mgmt.bpl.reports;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.epics.archiverappliance.common.BPLAction;
import org.epics.archiverappliance.config.ApplianceAggregateInfo;
import org.epics.archiverappliance.config.ApplianceInfo;
import org.epics.archiverappliance.config.ConfigService;
import org.epics.archiverappliance.config.PVTypeInfo;
import org.epics.archiverappliance.mgmt.archivepv.CapacityPlanningData;
import org.epics.archiverappliance.utils.ui.GetUrlContent;
import org.epics.archiverappliance.utils.ui.MimeTypeConstants;
import org.json.simple.JSONArray;
import org.json.simple.JSONValue;
/**
* Detailed metrics for an appliance
* @author mshankar
*
*/
public class ApplianceMetricsDetails implements BPLAction {
private static Logger logger = Logger.getLogger(ApplianceMetricsDetails.class.getName());
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp, ConfigService configService) throws IOException {
String applianceIdentity = req.getParameter("appliance");
logger.info("Getting the detailed metrics for the appliance " + applianceIdentity);
resp.setContentType(MimeTypeConstants.APPLICATION_JSON);
String applianceDetailsURLSnippet = "/getApplianceMetricsForAppliance?appliance=" + URLEncoder.encode(applianceIdentity, "UTF-8");
ApplianceInfo info = configService.getAppliance(applianceIdentity);
try (PrintWriter out = resp.getWriter()) {
DecimalFormat twoSignificantDigits = new DecimalFormat("###,###,###,###,###,###.##");
DecimalFormat noSignificantDigits = new DecimalFormat("###,###,###,###,###,###");
LinkedList<Map<String, String>> result = new LinkedList<Map<String, String>>();
addDetailedStatus(result, "Appliance Identity", applianceIdentity);
logger.debug("Asking engine using " + info.getEngineURL() + applianceDetailsURLSnippet);
JSONArray engineStatusVars = GetUrlContent.getURLContentAsJSONArray(info.getEngineURL() + applianceDetailsURLSnippet );
if(engineStatusVars == null) {
logger.warn("No status vars from engine using URL " + info.getEngineURL() + applianceDetailsURLSnippet);
} else {
GetUrlContent.combineJSONArrays(result, engineStatusVars);
}
logger.debug("Asking ETL using " + info.getEngineURL() + applianceDetailsURLSnippet);
JSONArray etlStatusVars = GetUrlContent.getURLContentAsJSONArray(info.getEtlURL() + applianceDetailsURLSnippet );
if(etlStatusVars == null) {
logger.warn("No status vars from ETL using URL " + info.getEtlURL() + applianceDetailsURLSnippet);
} else {
GetUrlContent.combineJSONArrays(result, etlStatusVars);
}
logger.debug("Asking retrieval using " + info.getEngineURL() + applianceDetailsURLSnippet);
JSONArray retrievalStatusVars = GetUrlContent.getURLContentAsJSONArray(info.getRetrievalURL() + applianceDetailsURLSnippet);
if(retrievalStatusVars == null) {
logger.warn("No status vars from retrieval using URL " + info.getRetrievalURL() + applianceDetailsURLSnippet);
} else {
GetUrlContent.combineJSONArrays(result, retrievalStatusVars);
}
logger.debug("Computing local stats " + info.getEngineURL() + applianceDetailsURLSnippet);
addDetailedStatus(result, "PVs in archive workflow", Integer.toString(configService.getMgmtRuntimeState().getPVsPendingInWorkflow()));
CapacityPlanningData capacityPlanningMetrics = CapacityPlanningData.getMetricsForAppliances(configService).cpApplianceMetrics.get(configService.getMyApplianceInfo());
ApplianceAggregateInfo applianceAggregateDifferenceFromLastFetch = capacityPlanningMetrics.getApplianceAggregateDifferenceFromLastFetch(configService);
addDetailedStatus(result, "Capacity planning last update", capacityPlanningMetrics.getStaticDataLastUpdated());
addDetailedStatus(result, "Engine write thread usage", twoSignificantDigits.format(capacityPlanningMetrics.getEngineWriteThreadUsage(PVTypeInfo.DEFAULT_BUFFER_INTERVAL)));
addDetailedStatus(result, "Aggregated appliance storage rate (in GB/year)", twoSignificantDigits.format((configService.getAggregatedApplianceInfo(info).getTotalStorageRate()*60*60*24*365)/(1024*1024*1024)));
addDetailedStatus(result, "Aggregated appliance event rate (in events/sec)", twoSignificantDigits.format(configService.getAggregatedApplianceInfo(info).getTotalEventRate()));
addDetailedStatus(result, "Aggregated appliance PV count", noSignificantDigits.format(configService.getAggregatedApplianceInfo(info).getTotalPVCount()));
addDetailedStatus(result, "Incremental appliance storage rate (in GB/year)", twoSignificantDigits.format((applianceAggregateDifferenceFromLastFetch.getTotalStorageRate()*60*60*24*365)/(1024*1024*1024)));
addDetailedStatus(result, "Incremental appliance event rate (in events/sec)", twoSignificantDigits.format(applianceAggregateDifferenceFromLastFetch.getTotalEventRate()));
addDetailedStatus(result, "Incremental appliance PV count", noSignificantDigits.format(applianceAggregateDifferenceFromLastFetch.getTotalPVCount()));
out.println(JSONValue.toJSONString(result));
}
}
private static void addDetailedStatus(LinkedList<Map<String, String>> statuses, String name, String value) {
Map<String, String> obj = new LinkedHashMap<String, String>();
obj.put("name", name);
obj.put("value", value);
obj.put("source", "mgmt");
statuses.add(obj);
}
}