HTTP metrics per endpoint uri in spring boot app - spring

I have enabled actuator for my project. I am interested in metrics per endpoint uri in my application.
I have two endpoints / and /hello. When I visit /actuator/metrics/http.server.requests I get the following result:
{
"name": "http.server.requests",
"description": null,
"baseUnit": "seconds",
"measurements": [
{
"statistic": "COUNT",
"value": 11
},
{
"statistic": "TOTAL_TIME",
"value": 0.07724317
},
{
"statistic": "MAX",
"value": 0.024692496
}
],
"availableTags": [
{
"tag": "exception",
"values": [
"None"
]
},
{
"tag": "method",
"values": [
"POST",
"GET"
]
},
{
"tag": "uri",
"values": [
"/actuator/metrics/{requiredMetricName}",
"/actuator/health",
"/**",
"/hello",
"/"
]
},
{
"tag": "outcome",
"values": [
"CLIENT_ERROR",
"SUCCESS"
]
},
{
"tag": "status",
"values": [
"404",
"200"
]
}
]
}
However I am interested in the metrics for each endpoint / and /hello, information such as average response time, max, min etc.
Is there a configuration parameter for this? Above only provides an aggregate metrics information. I would like to see each endpoints metris.

You can use tags to get aggregated results, for example, if you just want to get metrics for /hello you would request:
/actuator/metrics/http.server.requests?tag=uri:/hello
And you can combine tags, for example if you want to get metrics for all requests made to /hello that returned 200 you could request:
/actuator/metrics/http.server.requests?tag=uri:/hello&tag=status:200

Related

How do I get custom metrics done in micrometer to graphite?

Similar to How to get Micrometer to output all custom metrics but I am trying to do it for Graphite.
I have a custom metric counter defined as:
#Bean
Counter successfulAuthenticationRequests(MeterRegistry meterRegistry) {
return Counter.builder(metricPrefix + ".auth.authentication.success")
.tag("group", "authentication")
.tag("state", "ok")
.register(meterRegistry);
}
In actuator I can see the value
❯ curl http://localhost:28082/actuator/metrics/spring.cloud.gateway.auth.authentication.success | jq
{
"name": "spring.cloud.gateway.auth.authentication.success",
"measurements": [
{
"statistic": "COUNT",
"value": 2
}
],
"availableTags": [
{
"tag": "node",
"values": [
"docker-desktop"
]
},
{
"tag": "service",
"values": [
"ds_gateway"
]
},
{
"tag": "state",
"values": [
"ok"
]
},
{
"tag": "group",
"values": [
"authentication"
]
}
]
}
The environment is set up as
management.graphite.metrics.export.host: graphite
management.graphite.metrics.export.enabled: "true"
management.graphite.metrics.export.port: 2004
And I can see that there's data added to Graphite so I presume the connection is all valid.
However, I can't see my custom counter. I tried to use a different prefix as well and none of it worked.
Is there anything I may be missing?
I also tried to disable tag support by adding
management.graphite.metrics.export.graphiteTagsEnabled: "false"
I get more metrics with this set in Spring but not for my custom metrics.

Get the count per status in micrometer #Timed annotation

I am using #Timed annotation in SpringBoot application to monitor a method. I also want to know the count of response per status.
#GetMapping("/status/{productNumber}", produces = [MediaType.APPLICATION_JSON_VALUE])
#Timed(value = "status.productnumber", description = "Timed information retrieveProduct()")
fun retrieveProduct(#PathVariable productNumber: String): ResponseEntity {
When I open http://localhost:8080/actuator/metrics/status.productnumber I see:
{
"name": "status.productnumber",
"description": "Timed information retrieveProduct()",
"base_unit": "seconds",
"measurements": [
{
"statistic": "COUNT",
"value": 3.0
},
{
"statistic": "TOTAL_TIME",
"value": 0.515840608
},
{
"statistic": "MAX",
"value": 0.006641343
}
],
"available_tags": [
{
"tag": "exception",
"values": [
"None",
"RuntimeException"
]
},
{
"tag": "method",
"values": [
"GET"
]
},
{
"tag": "uri",
"values": [
"/status/{productNumber}"
]
},
{
"tag": "outcome",
"values": [
"SERVER_ERROR",
"SUCCESS"
]
},
{
"tag": "status",
"values": [
"500",
"200"
]
}
]
}
Here the COUNT statistic shows the total number of times this endpoint or method is accessed. Can I know the count per status? I want to know how many times 500 status code has occurred
You can query the tags this way: /actuator/metrics/status.productnumber?tag=status:500, please see the docs.
A couple of side notes:
The metrics endpoint is for metrics debugging/troubleshooting purposes, it does not substitute a metrics backend, it should not be used instead of it in prod
I'm not sure I get what is the purpose of status.productnumber by reading its name

How to link batch-response entries with the request entries in FHIR (DSTU3)

I am currently building an application for which it is important to check the existence of resources with a certain profile.
As we need to check this for 40+ profiles I'd like to put this all in 1 batch request and let our HAPI-FHIR server implementation handle this, as opposed to querying them one by one. This would get too chatty otherwise.
Because I only need to know about whether the resource exists I'd like to use _summary=count. I am assuming this increases the performance of the request.
Example request
{
"resourceType": "Bundle",
"type": "batch",
"entry": [
{
"request": {
"method": "GET",
"url": "/Observation?_profile=http://nictiz.nl/fhir/StructureDefinition/zib-DrugUse&_summary=true"
}
},
{
"request": {
"method": "GET",
"url": "/RelatedPerson?_profile=http://fhir.nl/fhir/StructureDefinition/nl-core-relatedperson&_summary=count"
}
}
]
}
Response
{
"resourceType": "Bundle",
"id": "fd66cfd9-4693-496d-86fc-98289067480b",
"type": "batch-response",
"link": [
{
"relation": "self",
"url": "<redacted>"
}
],
"entry": [
{
"resource": {
"resourceType": "Bundle",
"id": "2647a49f-0503-496b-b274-07d4e9163f1b",
"meta": {
"lastUpdated": "2021-02-15T11:44:18.035+00:00",
"tag": [
{
"system": "http://hl7.org/fhir/v3/ObservationValue",
"code": "SUBSETTED",
"display": "Resource encoded in summary mode"
}
]
},
"type": "searchset",
"total": 48
},
"response": {
"status": "200 OK"
}
},
{
"resource": {
"resourceType": "Bundle",
"id": "2f9cc861-5d20-4da1-aa9f-12153b75539d",
"meta": {
"lastUpdated": "2021-02-15T11:44:18.151+00:00",
"tag": [
{
"system": "http://hl7.org/fhir/v3/ObservationValue",
"code": "SUBSETTED",
"display": "Resource encoded in summary mode"
}
]
},
"type": "searchset",
"total": 10
},
"response": {
"status": "200 OK"
}
}
]
}
Can I assume that the ordering of the batch-response is the same as that of the batch-request?
Or is there a method to annotate the batch entries which are persisted onto the batch-response?
Or finally, is there a flag I can turn on to make the response include the request.url part?
I'm using HAPI-FHIR 5.1.0 both for client and server.
Apparently I didn't look well enough in the specs, as I just found the following:
From the FHIR spec
For a batch, or a successful transaction, the response the server SHALL return a Bundle with type set to batch-response or transaction-response that contains one entry for each entry in the request, in the same order, with the outcome of processing the entry.

How to configure Spring Actuator for httptrace and Rest Template?

I have a Spring boot application that it executes several parallel requests, of course, using RestTemplate class.
I configured Spring actuator,to see the Http Trace.
management.endpoints.web.exposure.include=httptrace
When I execute: http://localhost:8080/actuator/httptrace
I see information but related to the request I am doing to my Spring Mvc exposed controllers, but I don't see any info related to the request I am doing internally.
So how can I achieve that? Could you show me some example?
Thanks in advance folks!
You can use Spring Boot /actuator/metrics/http.server.requests to get all endPoints which are executed with their count, exception, outcome, status, total time, etc as follow.
If you want to see details for particular endPoint then you can do it by calling request as follow
localhost:8889/actuator/metrics/http.server.requests?tag=uri:<endPoint>
localhost:8889/actuator/metrics/http.server.requests?tag=uri:/user/asset/getAllAssets
localhost:8889/actuator/metrics/http.server.requests?tag=uri:/user/asset/getAllAssets&tag=status:200
You will get COUNT as how many times particular endPoint has been
called
You will get COUNT as how many times particular endPoint has been
called with a particular Status
To get the average time to execute endPoint you can do
TOTAL_TIME/COUNT for particular endPoint as well as for the whole
application
More Details are Here
localhost:8889/actuator/metrics/http.server.requests
{
"name": "http.server.requests",
"description": null,
"baseUnit": "seconds",
"measurements": [
{
"statistic": "COUNT",
"value": 3
},
{
"statistic": "TOTAL_TIME",
"value": 0.21817219999999998
},
{
"statistic": "MAX",
"value": 0.1379249
}
],
"availableTags": [
{
"tag": "exception",
"values": [
"MethodArgumentTypeMismatchException",
"None"
]
},
{
"tag": "method",
"values": [
"GET"
]
},
{
"tag": "uri",
"values": [
"/{id}.*",
"/user/asset/getAsset/{assetId}",
"/user/asset/getAllAssets"
]
},
{
"tag": "outcome",
"values": [
"CLIENT_ERROR",
"SUCCESS"
]
},
{
"tag": "status",
"values": [
"400",
"404",
"200"
]
}
]
}

400 Bad Request in Spring Boot Swagger UI for POST

I've created a Spring Boot application with RestController. I enabled Swagger UI and it works fine as I can login to the UI and execute any GET methods. But for POST methods accepting objects in the body, when I fire off the request using Swagger UI, it always returns 400 status code. I can see the request never reached the particular POST method. May I know if any special config I need for Swagger UI?
The particular method in my Spring Boot RestController
#ApiOperation(value = "Query requests by search criteria")
#RequestMapping(value = "/api/query", method = POST)
public PageResult<MyPOJO> find(#RequestBody SearchRequest request) {
//implementation omitted.
}
and I'm using
"io.springfox:springfox-swagger2:2.1.2",
"io.springfox:springfox-swagger-ui:2.1.2"
This one (generated by Swagger UI) for the corresponding api gives me 400 bad request:
{
"listEntrySearchCriteria": {
"summary": {
"createdBy": "string",
"createdOn": "2016-03-21T10:33:05.048Z",
"effectiveEnd": "2016-03-21T10:33:05.048Z",
"effectiveStart": "2016-03-21T10:33:05.048Z",
"id": 0,
"region": "string",
"type": "ETB",
"updatedBy": "string",
"updatedOn": "2016-03-21T10:33:05.048Z",
"version": 0
}
},
"listSummarySearchCriteria": {
"effectiveEnd": "2016-03-21T10:33:05.048Z",
"effectiveStart": "2016-03-21T10:33:05.048Z",
"statuses": [
"string"
],
"types": [
"string"
]
},
"pageRequest": {
"orders": [
{
"direction": "ASC",
"ignoreCase": true,
"nullHandling": "NATIVE",
"property": "string"
}
],
"page": 0,
"size": 0
}
}
But if I supply a random request for the same method, it at least reaches my method:
{
"orders": [
{
"direction": "ASC",
"ignoreCase": true,
"nullHandling": "NATIVE",
"property": "id"
}
],
"page": 0,
"size": 0
}

Resources