modules/enterprise/gui/rest-war/src/main/webapp/raw_graph7.html | 11 - modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java | 23 ++- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java | 65 +++++++++- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerLocal.java | 16 ++ modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Baseline.java | 58 ++++++++ 5 files changed, 153 insertions(+), 20 deletions(-)
New commits: commit a5d162e2e77b65945eb56e0800b380de93ca1bba Author: Heiko W. Rupp hwr@redhat.com Date: Sun Jan 15 14:32:14 2012 +0100
Fix a small issue with opacity, that prevented the dots to show.
diff --git a/modules/enterprise/gui/rest-war/src/main/webapp/raw_graph7.html b/modules/enterprise/gui/rest-war/src/main/webapp/raw_graph7.html index 0f38577..4ff8174 100644 --- a/modules/enterprise/gui/rest-war/src/main/webapp/raw_graph7.html +++ b/modules/enterprise/gui/rest-war/src/main/webapp/raw_graph7.html @@ -160,12 +160,14 @@ $.getJSON('/rest/1/resource/platforms.json', function (json) {
var line = d3.svg.line() .x(function(d,i) { return x(d.timeStamp-dayMinTs); }) - .y(function(d) { return y(d.value); }) - lines.append("svg:path").attr("d", line(daydat)).style("stroke",colors[day]); + .y(function(d) { return y(d.value); }); + lines.append("svg:path") + .attr("d", line(daydat)) + .style("stroke",colors[day]);
var dot = svg.append("svg:g").attr("class","dotschart") - .selectAll("dot").data(jsondata) + .selectAll("dot").data(jsondata);
dot.enter().append("svg:circle") .attr("cx", function (d) { @@ -175,8 +177,7 @@ $.getJSON('/rest/1/resource/platforms.json', function (json) { return y(d.value); }) .style("stroke", colors[day]) - .attr("r", 1) - .attr("opacity","0") + .attr("r", 1);
} });
commit a6015157d51f146e824898b60108d5ea03ec030a Author: Heiko W. Rupp hwr@redhat.com Date: Sun Jan 15 14:31:32 2012 +0100
Allow to get and set baselines.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java index 71a6a45..53255a6 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java @@ -36,6 +36,8 @@ import java.util.Set; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.interceptor.Interceptors; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; import javax.sql.DataSource; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -62,6 +64,7 @@ import org.jboss.cache.Fqn;
import org.rhq.core.domain.common.EntityContext; import org.rhq.core.domain.measurement.DataType; +import org.rhq.core.domain.measurement.MeasurementBaseline; import org.rhq.core.domain.measurement.MeasurementDataNumeric; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.measurement.MeasurementSchedule; @@ -70,6 +73,7 @@ import org.rhq.core.util.jdbc.JDBCUtil; import org.rhq.enterprise.server.RHQConstants; import org.rhq.enterprise.server.measurement.util.MeasurementDataManagerUtility; import org.rhq.enterprise.server.resource.ResourceManagerLocal; +import org.rhq.enterprise.server.rest.domain.Baseline; import org.rhq.enterprise.server.rest.domain.Link; import org.rhq.enterprise.server.rest.domain.MetricAggregate; import org.rhq.enterprise.server.measurement.MeasurementAggregate; @@ -93,6 +97,8 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle MeasurementScheduleManagerLocal scheduleManager; @EJB ResourceManagerLocal resMgr; + @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME) + EntityManager em;
@javax.annotation.Resource(name = "RHQ_DS") private DataSource rhqDs; @@ -114,7 +120,7 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle startTime = endTime - EIGHT_HOURS; }
- MeasurementSchedule schedule = obtainSchedule(scheduleId); + MeasurementSchedule schedule = obtainSchedule(scheduleId, false);
MeasurementAggregate aggr = dataManager.getAggregate(caller, scheduleId, startTime, endTime); MetricAggregate res = new MetricAggregate(scheduleId, aggr.getMin(),aggr.getAvg(),aggr.getMax()); @@ -149,13 +155,16 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle
/** * Get the schedule for the passed schedule id + * * @param scheduleId id to look up + * @param force * @return schedule * @throws StuffNotFoundException if there is no schedule with the passed id */ - private MeasurementSchedule obtainSchedule(int scheduleId) { - MeasurementSchedule schedule; - schedule = getFromCache(scheduleId,MeasurementSchedule.class); + private MeasurementSchedule obtainSchedule(int scheduleId, boolean force) { + MeasurementSchedule schedule=null; + if(!force) + schedule = getFromCache(scheduleId,MeasurementSchedule.class); if (schedule==null) { schedule = scheduleManager.getScheduleById(caller,scheduleId); if (schedule==null) { @@ -419,7 +428,7 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle throw new IllegalArgumentException("Start time is older than 7 days");
// Check if the schedule exists - obtainSchedule(scheduleId); + obtainSchedule(scheduleId, false);
RawNumericStreamingOutput so = new RawNumericStreamingOutput(); so.scheduleId = scheduleId; @@ -441,7 +450,7 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle NumericDataPoint point, @Context HttpHeaders headers, UriInfo uriInfo) {
MediaType mediaType = headers.getAcceptableMediaTypes().get(0); - MeasurementSchedule schedule = obtainSchedule(scheduleId); + MeasurementSchedule schedule = obtainSchedule(scheduleId, false);
Set<MeasurementDataNumeric> data = new HashSet<MeasurementDataNumeric>(1); data.add(new MeasurementDataNumeric(point.getTimeStamp(),scheduleId,point.getValue())); @@ -476,6 +485,50 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle
}
+ @Override + @GET + @Path("data/{scheduleId}/baseline") + public Baseline getBaseline(@PathParam("scheduleId") int scheduleId, @Context HttpHeaders headers, + @Context UriInfo uriInfo) { + MeasurementSchedule schedule = obtainSchedule(scheduleId, true); + MeasurementBaseline mBase = schedule.getBaseline(); + + Baseline b; + if (mBase==null) + throw new StuffNotFoundException("Baseline for schedule [" + scheduleId +"]"); + else + b = new Baseline(mBase.getMin(),mBase.getMax(),mBase.getMean(),mBase.getComputeTime().getTime()); + return b; + + } + + @Override + @PUT + @Path("data/{scheduleId}/baseline") + public void setBaseline(@PathParam("scheduleId") int scheduleId, + Baseline baseline, HttpHeaders headers, @Context UriInfo uriInfo) { + MeasurementSchedule schedule = obtainSchedule(scheduleId, false); + + // little bit of sanity checking + if (baseline.getMin()>baseline.getMean() || baseline.getMean()>baseline.getMax() || baseline.getMin()>baseline.getMax()) + throw new IllegalArgumentException("Baseline not correct. it should be min<=mean<=max"); + + MeasurementBaseline mBase = schedule.getBaseline(); + if (mBase == null) { + mBase = new MeasurementBaseline(); + mBase.setSchedule(schedule); + schedule.setBaseline(mBase); + em.persist(mBase); + } + mBase.setMax(baseline.getMax()); + mBase.setMin(baseline.getMin()); + mBase.setMean(baseline.getMean()); + mBase.setUserEntered(true); + + scheduleManager.updateSchedule(caller,schedule); + + } + /** * Write the numeric data points to the output stream in JSON encoding * without creating tons of objects in the middle to have them marshalled diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerLocal.java index 6f76bce..6d9c174 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerLocal.java @@ -39,6 +39,7 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; import javax.ws.rs.core.UriInfo;
+import org.rhq.enterprise.server.rest.domain.Baseline; import org.rhq.enterprise.server.rest.domain.MetricAggregate; import org.rhq.enterprise.server.rest.domain.MetricSchedule; import org.rhq.enterprise.server.rest.domain.NumericDataPoint; @@ -155,4 +156,19 @@ public interface MetricHandlerLocal { @Path("data/raw") @Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) Response postMetricValues(Collection<NumericDataPoint> points, @Context HttpHeaders headers); + + @GET + @Path("data/{scheduleId}/baseline") + @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) + Baseline getBaseline(@PathParam("scheduleId") int scheduleId, + @Context HttpHeaders headers, + @Context UriInfo uriInfo); + + @PUT + @Path("data/{scheduleId}/baseline") + @Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) + void setBaseline(@PathParam("scheduleId") int scheduleId, + Baseline baseline, + @Context HttpHeaders headers, + @Context UriInfo uriInfo); } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Baseline.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Baseline.java new file mode 100644 index 0000000..d6a4073 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Baseline.java @@ -0,0 +1,58 @@ +package org.rhq.enterprise.server.rest.domain; + +import javax.xml.bind.annotation.XmlRootElement; + +/** + * A baseline + * @author Heiko W. Rupp + */ +@XmlRootElement +public class Baseline { + + double min; + double max; + double mean; + long computeTime; + + public Baseline() { + } + + public Baseline(double min, double max, double mean, long computeTime) { + this.min = min; + this.max = max; + this.mean = mean; + this.computeTime = computeTime; + } + + public double getMin() { + return min; + } + + public void setMin(double min) { + this.min = min; + } + + public double getMax() { + return max; + } + + public void setMax(double max) { + this.max = max; + } + + public double getMean() { + return mean; + } + + public void setMean(double mean) { + this.mean = mean; + } + + public long getComputeTime() { + return computeTime; + } + + public void setComputeTime(long computeTime) { + this.computeTime = computeTime; + } +}
commit 10051994173b5b1467155bb957b7c4dbd579011c Author: Heiko W. Rupp hwr@redhat.com Date: Sun Jan 15 13:55:51 2012 +0100
BZ 781801 - if frequency is 0 print a note and return.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java index 286a75e..1d64102 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java @@ -115,7 +115,12 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage // Determine how much data we need to calculate baselines for by determining the oldest and youngest // measurement data to include in the calculations. long amountOfData = Long.parseLong(baselineDataSetString); - long baselinesOlderThanTime = System.currentTimeMillis() - Long.parseLong(baselineFrequencyString); + long baselineFrequency = Long.parseLong(baselineFrequencyString); + if (baselineFrequency==0) { + log.info("Baseline frequency is set to 0 - not recomputing baselines. Go to Admin->System settings to change this."); + return; + } + long baselinesOlderThanTime = System.currentTimeMillis() - baselineFrequency;
measurementBaselineManager.calculateAutoBaselines(amountOfData, baselinesOlderThanTime);
@@ -147,20 +152,20 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage now = System.currentTimeMillis(); int totalInserted = 0; while (true) { - /* + /* * each call is done in a separate xtn of at most 100K inserted rows; this helps to keep the xtn * shorter to avoid timeouts in scenarios where baseline calculations bunch together. the idea was that - * by basing a batch of baseline calculations off of the import time of the resource into inventory, + * by basing a batch of baseline calculations off of the import time of the resource into inventory, * that the total work would naturally be staggered throughout the day. in practice, this didn't always * work as intended for one of several reasons: - * - * 1) all servers in the cloud were down for a few days (maybe a slow product upgrade, maybe a cold + * + * 1) all servers in the cloud were down for a few days (maybe a slow product upgrade, maybe a cold * data center relocation) * 2) issues with running the job itself, if quartz had locking issues under severe load and somehow * this job wasn't get executed for a few hours / days * 3) the user tended to import all new resources / platforms at the same time of day, thus bypassing * the implicit optimization of trying to stagger the calculations by resource commit time - * + * * 2/18/2010 NOTE: Limits weren't / aren't actually achieving the affect we want. The baseline query * follows the general form of "insert into...select from <big query> having <subquery> limit X". * In this case, the limit was reducing the number of rows inserted, but it was still taking the full @@ -169,20 +174,20 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage * part - the "big query". What we actually want to do is come of with a strategy that lessens the * amount of data we need to select, thereby reducing the amount of time it takes to calculate the * insertion list. - * + * * One proposed strategy for this would be to chunk on the scheduleId. So if there were, say, * 5M scheduleIds in the systems, we might take 500K of them at a time and then execute the * baseline insertion job 10 times against a much smaller set of data each time. But the * complication here is how to calculate precise groups of 500K schedules at a time, and then * walk that chunked list. - * + * * Another strategy would be to divy things up by resource type. Since a measurementSchedule is * linked to a measurementDefinition which is linked to a resourceType, we could very easily chunk * the insertion based off the schedules that belong to each resourceType. This would create * one insert statement for each type of resource in system. The complication here, however, * is that you may have millions of resources of one type, but hardly any resources of another. * So there's still a chance that some insertions proceed slowly (in the worst case). - * + * * In any event, an appropriate chunking solution needs to be found, and that partitioning strategy * needs to replace the limits in the query today. */
rhq-commits@lists.fedorahosted.org