private void parseLine(String word) { String[] tokens1 = new ColonSplitter(word).split(); if (tokens1.length != 2 && tokens1.length != 3) { throw new IllegalArgumentException("Invalid LINE statement: " + word); } String[] tokens2 = tokens1[1].split("#"); if (tokens2.length != 1 && tokens2.length != 2) { throw new IllegalArgumentException("Invalid LINE statement: " + word); } float width = Integer.parseInt(tokens1[0].substring(tokens1[0].length() - 1)); String name = tokens2[0]; Paint color = tokens2.length == 2 ? Util.parseColor(tokens2[1]) : BLIND_COLOR; String legend = tokens1.length == 3 ? tokens1[2] : null; gdef.line(name, color, legend, width); }
public RrdGraphDef getGraphDef( long nowInSeconds, SourceIdentifier sourceIdentifier, boolean showMax) { String absoluteRrdPath = getRrdFile(sourceIdentifier).getAbsolutePath(); RrdGraphDef graphDef = new RrdGraphDef(); graphDef.setColor(RrdGraphConstants.COLOR_CANVAS, new Color(0xcc, 0xcc, 0xcc)); graphDef.setNoMinorGrid(true); graphDef.setShowSignature(false); graphDef.setMinValue(0); graphDef.setAltAutoscaleMax(true); graphDef.setAltYGrid(false); graphDef.setTimeAxis( RrdGraphConstants.HOUR, 1, RrdGraphConstants.HOUR, 6, RrdGraphConstants.DAY, 1, 0, "yyyy-MM-dd"); graphDef.setFilename("-"); graphDef.setImageFormat("PNG"); ConsolFun consolFun; String description; if (showMax) { consolFun = ConsolFun.MAX; description = " (max.)"; } else { consolFun = ConsolFun.AVERAGE; description = " (avg.)"; } graphDef.setVerticalLabel("Events/s" + description); graphDef.datasource( RrdLoggingEventHandler.TRACE, absoluteRrdPath, RrdLoggingEventHandler.TRACE_DS_NAME, consolFun); graphDef.datasource( RrdLoggingEventHandler.DEBUG, absoluteRrdPath, RrdLoggingEventHandler.DEBUG_DS_NAME, consolFun); graphDef.datasource( RrdLoggingEventHandler.INFO, absoluteRrdPath, RrdLoggingEventHandler.INFO_DS_NAME, consolFun); graphDef.datasource( RrdLoggingEventHandler.WARN, absoluteRrdPath, RrdLoggingEventHandler.WARN_DS_NAME, consolFun); graphDef.datasource( RrdLoggingEventHandler.ERROR, absoluteRrdPath, RrdLoggingEventHandler.ERROR_DS_NAME, consolFun); graphDef.area( RrdLoggingEventHandler.TRACE, new Color(0x00, 0x00, 0xff), RrdLoggingEventHandler.TRACE); graphDef.stack( RrdLoggingEventHandler.DEBUG, new Color(0x00, 0xff, 0x00), RrdLoggingEventHandler.DEBUG); graphDef.stack( RrdLoggingEventHandler.INFO, new Color(0xff, 0xff, 0xff), RrdLoggingEventHandler.INFO); graphDef.stack( RrdLoggingEventHandler.WARN, new Color(0xff, 0xff, 0x00), RrdLoggingEventHandler.WARN); graphDef.stack( RrdLoggingEventHandler.ERROR, new Color(0xff, 0x00, 0x00), RrdLoggingEventHandler.ERROR); if (showMax) { graphDef.datasource( RrdLoggingEventHandler.TOTAL, absoluteRrdPath, RrdLoggingEventHandler.TOTAL_DS_NAME, consolFun); graphDef.line(RrdLoggingEventHandler.TOTAL, Color.BLACK, RrdLoggingEventHandler.TOTAL); } graphDef.setAntiAliasing(true); graphDef.setLazy(false); String sourceTitle = createGraphTitle(sourceIdentifier); long before = nowInSeconds - 7 * 24 * 60 * 60; graphDef.setTimeSpan(before, nowInSeconds); graphDef.setTitle(sourceTitle); graphDef.setWidth(graphSize.width); graphDef.setHeight(graphSize.height); return graphDef; }
@Override public byte[] renderSvcVerPayloadSizeGraph(long theServiceVersionPid, TimeRange theRange) throws IOException { ourLog.info("Rendering payload size graph for service version {}", theServiceVersionPid); myBroadcastSender.requestFlushQueuedStats(); final List<Integer> invCount = new ArrayList<>(); final List<Long> totalSuccessReqBytes = new ArrayList<>(); final List<Long> totalSuccessRespBytes = new ArrayList<>(); final List<Long> timestamps = new ArrayList<>(); BasePersServiceVersion svcVer = myServiceRegistry.getServiceVersionByPid(theServiceVersionPid); for (PersMethod nextMethod : svcVer.getMethods()) { doWithStatsByMinute( myConfig.getConfig(), theRange, myStatus, nextMethod, new IWithStats<PersInvocationMethodSvcverStatsPk, PersInvocationMethodSvcverStats>() { @Override public void withStats(int theIndex, PersInvocationMethodSvcverStats theStats) { growToSizeInt(invCount, theIndex); growToSizeLong(totalSuccessRespBytes, theIndex); growToSizeLong(totalSuccessReqBytes, theIndex); growToSizeLong(timestamps, theIndex); totalSuccessReqBytes.set( theIndex, addToLong( totalSuccessReqBytes.get(theIndex), theStats.getSuccessRequestMessageBytes())); totalSuccessRespBytes.set( theIndex, addToLong( totalSuccessRespBytes.get(theIndex), theStats.getSuccessResponseMessageBytes())); invCount.set( theIndex, addToInt(invCount.get(theIndex), theStats.getSuccessInvocationCount())); timestamps.set(theIndex, theStats.getPk().getStartTime().getTime()); } }); } double[] avgSuccessReqSize = new double[invCount.size()]; double[] avgSuccessRespSize = new double[invCount.size()]; for (int i = 0; i < invCount.size(); i++) { avgSuccessReqSize[i] = invCount.get(i) == 0 ? 0 : totalSuccessReqBytes.get(i) / invCount.get(i); avgSuccessRespSize[i] = invCount.get(i) == 0 ? 0 : totalSuccessRespBytes.get(i) / invCount.get(i); } RrdGraphDef graphDef = new RrdGraphDef(); graphDef.setWidth(600); graphDef.setHeight(200); graphDef.setTitle( "Message Payload Size: " + svcVer.getService().getDomain().getDomainId() + " / " + svcVer.getService().getServiceId() + " / " + svcVer.getVersionId()); long[] timestamps1 = new long[invCount.size()]; double prevReq = 0.0; double prevResp = 0.0; for (int i = 0; i < invCount.size(); i++) { timestamps1[i] = timestamps.get(i) / 1000; prevReq = avgSuccessReqSize[i] > 0 ? avgSuccessReqSize[i] : prevReq; avgSuccessReqSize[i] = prevReq; prevResp = avgSuccessRespSize[i] > 0 ? avgSuccessRespSize[i] : prevResp; avgSuccessRespSize[i] = prevResp; } for (int i = 0; i < avgSuccessReqSize.length; i++) {} graphDef.setTimeSpan(timestamps1); graphDef.setVerticalLabel("Bytes / Message"); graphDef.setTextAntiAliasing(true); LinearInterpolator reqPlot = new LinearInterpolator(timestamps1, avgSuccessReqSize); graphDef.datasource("req", reqPlot); graphDef.line("req", Color.RED, "Requests ", 2.0f); graphDef.gprint("req", ConsolFun.AVERAGE, "Average Size %8.1f "); graphDef.gprint("req", ConsolFun.MIN, "Min %8.1f "); graphDef.gprint("req", ConsolFun.MAX, "Max %8.1f\\l"); LinearInterpolator respPlot = new LinearInterpolator(timestamps1, avgSuccessRespSize); graphDef.datasource("resp", respPlot); graphDef.line("resp", Color.GREEN, "Responses ", 2.0f); graphDef.gprint("resp", ConsolFun.AVERAGE, "Average Size %8.1f "); graphDef.gprint("resp", ConsolFun.MIN, "Min %8.1f "); graphDef.gprint("resp", ConsolFun.MAX, "Max %8.1f\\l"); return render(graphDef); }
@Override public byte[] renderSvcVerLatencyMethodGraph( long theSvcVerPid, TimeRange theRange, boolean theIndividualMethod) throws IOException { ourLog.info("Rendering user method graph for Service Version {}", theSvcVerPid); myBroadcastSender.requestFlushQueuedStats(); BasePersServiceVersion svcVer = myServiceRegistry.getServiceVersionByPid(theSvcVerPid); /* * Init the graph */ RrdGraphDef graphDef = new RrdGraphDef(); graphDef.setWidth(600); graphDef.setHeight(200); graphDef.setTitle( "Backing Service Latency: " + svcVer.getService().getDomain().getDomainId() + " / " + svcVer.getService().getServiceId() + " / " + svcVer.getVersionId()); graphDef.setVerticalLabel("Milliseconds / Call"); graphDef.setTextAntiAliasing(true); graphDef.setMinValue(0.0); /* * Loop through each method and load the latency stats */ final List<String> names = new ArrayList<>(); final List<List<Long>> latencyLists = new ArrayList<>(); final List<Long> timestamps = new ArrayList<>(); for (PersMethod nextMethod : svcVer.getMethods()) { if (BaseDtoServiceVersion.METHOD_NAME_UNKNOWN.equals(nextMethod.getName())) { continue; } final List<Long> latencyMin; if (theIndividualMethod) { names.add(nextMethod.getName()); latencyMin = new ArrayList<>(); latencyLists.add(latencyMin); } else { if (names.isEmpty()) { names.add("All Methods"); latencyMin = new ArrayList<>(); latencyLists.add(latencyMin); } else { latencyMin = latencyLists.get(0); } } doWithStatsByMinute( myConfig.getConfig(), theRange, myStatus, nextMethod, new IWithStats<PersInvocationMethodSvcverStatsPk, PersInvocationMethodSvcverStats>() { @Override public void withStats(int theIndex, PersInvocationMethodSvcverStats theStats) { growToSizeLong(latencyMin, theIndex); growToSizeLong(timestamps, theIndex); long latency = theStats.getSuccessInvocationTotalTime() > 0 ? theStats.getSuccessInvocationTotalTime() / theStats.getSuccessInvocationCount() : 0; latencyMin.set(theIndex, addToLong(latencyMin.get(theIndex), latency)); timestamps.set(theIndex, theStats.getPk().getStartTime().getTime()); } }); } /* * Set time span */ long[] graphTimestamps = new long[timestamps.size()]; for (int i = 0; i < timestamps.size(); i++) { graphTimestamps[i] = timestamps.get(i) / 1000; } graphDef.setTimeSpan(graphTimestamps); /* * Figure out the longest name */ int longestName = 0; for (String next : names) { longestName = Math.max(longestName, next.length()); } /* * Straighten */ int numWithValues = 0; List<Boolean> hasValuesList = new ArrayList<>(); for (List<Long> nextList : latencyLists) { boolean hasValues = false; for (int i = 0; i < nextList.size(); i++) { long l = nextList.get(i); if (l == 0) { if (i > 0 && nextList.get(i - 1) > 0) { nextList.set(i, nextList.get(i - 1)); } } else { hasValues = true; } } hasValuesList.add(hasValues); if (hasValues) { numWithValues++; } } /* * Figure out colours */ List<Color> colours = new ArrayList<>(); int colourIndex = 0; for (int i = 0; i < hasValuesList.size(); i++) { if (hasValuesList.get(i)) { colours.add(createStackColour(numWithValues, colourIndex++)); } else { colours.add(Color.black); } } /* * Add the lines to the graph */ for (int i = 0; i < names.size(); i++) { String name = names.get(i); List<Long> latencyMin = latencyLists.get(i); Plottable avgPlot = new LinearInterpolator(graphTimestamps, toDoublesFromLongs(latencyMin)); String srcName = "inv" + i; graphDef.datasource(srcName, avgPlot); graphDef.line(srcName, colours.get(i), " " + StringUtils.rightPad(name, longestName), 2); if (hasValuesList.get(i)) { graphDef.gprint(srcName, ConsolFun.AVERAGE, "Avg %5.1f "); graphDef.gprint(srcName, ConsolFun.MIN, "Min %5.1f "); graphDef.gprint(srcName, ConsolFun.MAX, "Max %5.1f \\l"); } else { graphDef.comment("No Invocations During This Period\\l"); } } return render(graphDef); }
@Override public byte[] createGraph( String metricName, String rrdFilename, long startTime, long endTime, String verticalAxisLabel, String title) throws IOException, MetricsGraphException { // Create RRD DB in read-only mode for the specified RRD file RrdDb rrdDb = new RrdDb(rrdFilename, true); // Extract the data source (should always only be one data source per RRD file - otherwise we // have a problem) if (rrdDb.getDsCount() != 1) { throw new MetricsGraphException( "Only one data source per RRD file is supported - RRD file " + rrdFilename + " has " + rrdDb.getDsCount() + " data sources."); } // Define attributes of the graph to be created for this metric RrdGraphDef graphDef = new RrdGraphDef(); graphDef.setTimeSpan(startTime, endTime); graphDef.setImageFormat("PNG"); graphDef.setShowSignature(false); graphDef.setStep(60); graphDef.setVerticalLabel(verticalAxisLabel); graphDef.setHeight(500); graphDef.setWidth(1000); graphDef.setTitle(title); DsType dataSourceType = rrdDb.getDatasource(0).getType(); // Determine if the Data Source for this RRD file is a COUNTER or GAUGE // (Need to know this because COUNTER data is averaged across samples and the vertical axis of // the // generated graph by default will show data per rrdStep interval) if (dataSourceType == DsType.COUNTER) { // If we ever needed to adjust the metric's data collected by RRD by the archive step // (which is the rrdStep * archiveSampleCount) this is how to do it. // FetchRequest fetchRequest = rrdDb.createFetchRequest(ConsolFun.AVERAGE, // startTime, endTime); // Archive archive = rrdDb.findMatchingArchive(fetchRequest); // long archiveStep = archive.getArcStep(); // LOGGER.debug("archiveStep = " + archiveStep); long rrdStep = rrdDb.getRrdDef().getStep(); LOGGER.debug("rrdStep = " + rrdStep); // Still TBD if we want to graph the AVERAGE data on the same graph // graphDef.comment(metricName + " "); // graphDef.datasource("myAverage", rrdFilename, "data", ConsolFun.AVERAGE); // graphDef.datasource("realAverage", "myAverage," + rrdStep + ",*"); // graphDef.line("realAverage", Color.GREEN, "Average", 2); // Multiplied by the rrdStep to "undo" the automatic averaging that RRD does // when it collects TOTAL data - we want the actual totals for the step, not // the average of the totals. graphDef.datasource("myTotal", rrdFilename, "data", ConsolFun.TOTAL); graphDef.datasource("realTotal", "myTotal," + rrdStep + ",*"); graphDef.line("realTotal", Color.BLUE, convertCamelCase(metricName), 2); // Add some spacing between the graph and the summary stats shown beneath the graph graphDef.comment("\\s"); graphDef.comment("\\s"); graphDef.comment("\\c"); // Average, Min, and Max over all of the TOTAL data - displayed at bottom of the graph graphDef.gprint("realTotal", ConsolFun.AVERAGE, "Average = %.3f%s"); graphDef.gprint("realTotal", ConsolFun.MIN, "Min = %.3f%s"); graphDef.gprint("realTotal", ConsolFun.MAX, "Max = %.3f%s"); } else if (dataSourceType == DsType.GAUGE) { graphDef.datasource("myAverage", rrdFilename, "data", ConsolFun.AVERAGE); graphDef.line("myAverage", Color.RED, convertCamelCase(metricName), 2); // Add some spacing between the graph and the summary stats shown beneath the graph graphDef.comment("\\s"); graphDef.comment("\\s"); graphDef.comment("\\c"); // Average, Min, and Max over all of the AVERAGE data - displayed at bottom of the graph graphDef.gprint("myAverage", ConsolFun.AVERAGE, "Average = %.3f%s"); graphDef.gprint("myAverage", ConsolFun.MIN, "Min = %.3f%s"); graphDef.gprint("myAverage", ConsolFun.MAX, "Max = %.3f%s"); } else { rrdDb.close(); throw new MetricsGraphException( "Unsupported data source type " + dataSourceType.name() + " in RRD file " + rrdFilename + ", only COUNTER and GAUGE data source types supported."); } rrdDb.close(); // Use "-" as filename so that RRD creates the graph only in memory (no file is // created, hence no file locking problems due to race conditions between multiple clients) graphDef.setFilename("-"); RrdGraph graph = new RrdGraph(graphDef); return graph.getRrdGraphInfo().getBytes(); }
public void draw(RrdGraphDef rgd, String sn, Color color, String legend) { rgd.line(sn, color, legend); };