I have a number of REST API endpoints and I would like to measure the timing metrics for each separately. Annotating the methods with @PerformanceMonitor works, but the recorderSource field takes a class and there’s no way to pass a unique forWhat
descriptor for each method. Do I need to create a child class for every endpoint + HTTP method just to define a unique forWhat
string? That does not seem scalable. Am I missing something?
Here’s an example of a specific recorder source:
import org.spf4j.annotations.RecorderSourceInstance; import org.spf4j.perf.MeasurementRecorderSource; import org.spf4j.perf.impl.RecorderFactory; public static final class GetAllProductsRecorderSource extends RecorderSourceInstance { public static final MeasurementRecorderSource INSTANCE; static { Object forWhat = "GetAllProducts"; INSTANCE = RecorderFactory.createScalableMinMaxAvgRecorderSource(forWhat, unitOfMeasurement, sampleTimeMillis); } }
Here’s the REST endpoing with annotation:
import org.spf4j.annotations.PerformanceMonitor; @PerformanceMonitor(warnThresholdMillis=1, errorThresholdMillis=100, recorderSource=GetAllProductsRecorderSource.class) @GetMapping("/products") public List<Product> getAllProducts() throws IOException { return productRepository.findAll(); }
Advertisement
Answer
If you use recorderSource=RecorderSourceInstance.Rs15m.class
The forWhat in your case will be “RecorderSourceInstance.Rs15m, YourClassName.getAllProducts”
So you would not need to create custom RecorderSourceInstance’s for every method.
Another option you have is to measure your metrics at a lower level, in a servlet filter like at. This will get you a more complete picture of the server side execution time (will include ser/deser, io…).
You can see this metric in action at or in prometheus format. This live demo is running on GKE, and the source code is at. See the wiki’s for more details on some of the ideas demonstrated in this demo.