Skip to content

Commit

Permalink
Add routes for stashing and reading a timed collection (#103)
Browse files Browse the repository at this point in the history
Signed-off-by: markcor11 <[email protected]>
  • Loading branch information
markcor11 authored Feb 17, 2020
1 parent 8fe34fb commit a166a22
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 2 deletions.
2 changes: 1 addition & 1 deletion AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ Authors ordered by first contribution
- Howard Hellyer (https://github.com/hhellyer)
- Richard Chamberlain (https://github.com/rnchamberlain)
- James Wallis (https://github.com/jamesemwallis)

- Mark Cornaia (https://github.com/markcor11)
6 changes: 6 additions & 0 deletions rest/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
Expand Down
111 changes: 110 additions & 1 deletion rest/src/main/java/com/ibm/javametrics/rest/api/MetricsEndpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,25 @@
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import javax.json.Json;
import javax.json.JsonObjectBuilder;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Timer;
import java.util.TimerTask;
import com.ibm.javametrics.analysis.MetricsData;
import com.ibm.javametrics.analysis.MetricsProcessor;

@Path("collections")
public class MetricsEndpoint {

MetricsProcessor mp = MetricsProcessor.getInstance();
final String METRICSFILE_PREFIX = getTempDir() + "/javametrics-collection";

// Get a list of running metric collections
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getContexts(@Context UriInfo uriInfo) {
Expand All @@ -62,6 +72,7 @@ public Response getContexts(@Context UriInfo uriInfo) {
return Response.ok(sb.toString()).build();
}

// Begin collecting a new set of metrics
@POST
@Produces(MediaType.APPLICATION_JSON)
public Response newContext(@Context UriInfo uriInfo) {
Expand All @@ -75,6 +86,7 @@ public Response newContext(@Context UriInfo uriInfo) {
return Response.status(Status.CREATED).header("Location", uri).entity("{\"uri\":\"" + uri + "\"}").build();
}

// Return the metrics collected so far by ID {metricsId}
@Path("/{metricsId}")
@GET
@Produces(MediaType.APPLICATION_JSON)
Expand All @@ -87,6 +99,7 @@ public Response getMetrics(@PathParam("metricsId") int id) {
return Response.ok(metrics.toJson(id)).build();
}

// Reset the metrics collected by {metricsId}
@Path("/{metricsId}")
@PUT
@Produces(MediaType.APPLICATION_JSON)
Expand All @@ -99,6 +112,7 @@ public Response resetContext(@PathParam("metricsId") int id) {
return Response.noContent().build();
}

// Delete the collection by {metricsId}
@Path("/{metricsId}")
@DELETE
public Response deleteContext(@PathParam("metricsId") int id) {
Expand All @@ -110,4 +124,99 @@ public Response deleteContext(@PathParam("metricsId") int id) {
return Response.noContent().build();
}

// Start collecting a timed run of metrics for {seconds}.
// Returns the collection path that includes an ID which can be used to retrieve the summary
@Path("/{seconds}")
@POST
@Produces(MediaType.APPLICATION_JSON)
public Response newTimedContext(@Context UriInfo uriInfo, @PathParam("seconds") int seconds) {
if (mp.getContextIds().length > 9) {
return Response.status(Status.BAD_REQUEST).build();
}

int contextId = mp.addContext();
String metricsFilePath = METRICSFILE_PREFIX + String.valueOf(contextId);
URI uri = getCollectionIDFromURIInfo(uriInfo, contextId);

// Start timing the collection recording
Timer timer = new Timer();
System.out.println("JavaMetrics: Started metrics collection #"+contextId);
TimerTask collectionTimerTask = createCollectionTimer(timer, metricsFilePath, contextId);
timer.schedule(collectionTimerTask, seconds * 1000);

return Response.status(Status.CREATED).header("Location", uri).entity("{\"uri\":\"" + uri + "\"}").build();
}

private URI getCollectionIDFromURIInfo(UriInfo uriInfo, int contextId) {
// remove parameters from url
String urlPath = uriInfo.getPath();
UriBuilder builder = UriBuilder.fromPath(urlPath.substring(0,urlPath.indexOf("/")));
builder.path(Integer.toString(contextId));
return builder.build();
}

// Fetch the recorded stashed metrics and remove the temp file if it exists
@Path("/{metricsId}/stashed")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getStashedMetrics(@PathParam("metricsId") int id) {
try {
if (!mp.removeContext(id)) {
return Response.status(Status.NOT_FOUND).build();
}
String metricsFilePath = METRICSFILE_PREFIX+String.valueOf(id);
File tempFile = new File(metricsFilePath);
if (!tempFile.exists() || tempFile.isDirectory()) {
return Response.status(Status.NOT_FOUND).build();
}
String data = new String(Files.readAllBytes(Paths.get(metricsFilePath)));
tempFile.delete();
return Response.ok(data).build();
} catch (Exception e) {
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
}

// Return the metrics collected so far by ID {metricsId}
@Path("/features")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getFeatures(@Context UriInfo uriInfo) {
JsonObjectBuilder featureList = Json.createObjectBuilder();
featureList.add("timedMetrics",true);
return Response.ok(featureList.build()).build();
}

private String getTempDir() {
return System.getProperty("java.io.tmpdir");
}


private TimerTask createCollectionTimer(Timer timer, String metricsFilePath, int contextId) {
return new TimerTask() {
public void run() {
Thread timerThread = collectionTimerThread(timer, metricsFilePath, contextId);
timerThread.start();
}
};
}

private Thread collectionTimerThread(Timer timer, String metricsFilePath, int contextId) {
return new Thread(new Runnable() {
public void run() {
try (FileWriter tempFile = new FileWriter(metricsFilePath)) {
MetricsData metrics = mp.getMetricsData(contextId);
if (metrics == null) {
System.out.println("JavaMetrics: Unable to locate the running collection");
} else {
tempFile.write(metrics.toJson(contextId));
System.out.println("JavaMetrics: Stashed collection # "+contextId);
}
} catch (IOException e) {
e.printStackTrace();
}
timer.cancel();
}
});
}
}

0 comments on commit a166a22

Please sign in to comment.