Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Micrometer-Extension writes wrong URI-Tag when Path-Variables defined at Interface-Level #30843

Closed
lostiniceland opened this issue Feb 3, 2023 · 9 comments · Fixed by #31059
Labels
area/metrics kind/bug Something isn't working
Milestone

Comments

@lostiniceland
Copy link
Contributor

lostiniceland commented Feb 3, 2023

Describe the bug

We are currently seing wrong metric-uri-tags for incoming requests when using the Micrometer-Prometheus extension.

Instead of placeholders for the path-variables, a metric for each path-variable-instance is created.
The issue is caused when placing the JAX-RS annotations on an interface, rather than the actual resource-class.

As a workaround, we have to duplicate @Path (and probably also @PathParam) to the implementing class, which is quite error-prone.

Unfortunatly using quarkus.micrometer.binder.http-server.match-patterns only work as workaround for the first appearance like /<id> but it fails for sub-queries like /<id>/do

Expected behavior

Metric is tagged with proper uri, replacing path-variables with a placeholder
http_server_requests_seconds_count{... uri="/{id}"} 1.0

Path annotation should be recognized regardless of location on interface or class

Actual behavior

A unique metric is written for each path-parameter accessing the endpoint

http_server_requests_seconds_count{... uri="/eae3806d-141c-46ed-a067-6f4b81f36062"} 2.0
http_server_requests_seconds_count{... uri="/eae3806d-141c-yyyy-xxxx-6f4b81f36062"} 1.0

How to Reproduce?

Enable dependency quarkus-micrometer-registry-prometheus

Create a endpoint consisting of interface and impl.

Path("/")
public interface SomeApi {
   @GET
   @Path("{id}")
   Response load(@PathParam("id) String id);
}

@RequestScoped
public class SomeResource implements SomeApi {
   public Response load(String id){
   ...do
   }
}

Access App with /someid to trigger metrics and check /q/metrics for http_server_requests_count

Output of uname -a or ver

No response

Output of java -version

17

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.15.3

Build tool (ie. output of mvnw --version or gradlew --version)

Maven 3.8.3

Additional information

Our main motivation for splitting interface and implementation is to avoid the annotation-hell due to swagger and jax-rs. The implementation in our case then has the meaningfull stuff like access-control, custom interceptors.
Furthermore the split is needed when doing contract first with OpenApi-Generators.

@lostiniceland lostiniceland added the kind/bug Something isn't working label Feb 3, 2023
@quarkus-bot
Copy link

quarkus-bot bot commented Feb 3, 2023

/cc @ebullient (micrometer)

@lostiniceland lostiniceland changed the title Micrometer-Extension writes wron URI-Tag when Path-Variables defined at Interface-Level Micrometer-Extension writes wrong URI-Tag when Path-Variables defined at Interface-Level Feb 3, 2023
@ebullient
Copy link
Member

ebullient commented Feb 3, 2023

A reproducer will be helpful here (just to ensure we cover your use case correctly). Note that we're building the query based on what the runtime has resolved / provides us as the URL is processed, we aren't basing it on config or trying to figure this out as each REST/Servlet container does this differently.

These patterns are proper Java regex. They should apply to sub-patterns if you write them that way. The escaping required for backslashes gets a little bananas, but this one (for example) has subpaths in play:

quarkus.micrometer.binder.http-server.match-patterns=/message/match/\\\\d+/[0-9]+=/message/match/{id}/{sub},\

Can you show/share your configured match pattern?

@lostiniceland
Copy link
Contributor Author

lostiniceland commented Feb 3, 2023

I will try to put something together over the weekend.

After a little debugging it looks like RestPathAnnotationProcessor is responsible for the issue, because it is not setting the runtime Annotation @QuarkusRestTemplatePath when @Path is only set on the interface.

This seems to be the culprit:


It is checking the classInfo. Not sure if there is something like interfaceInfo as well...

@lostiniceland
Copy link
Contributor Author

lostiniceland commented Feb 3, 2023

quarkus-30843.zip

There's a working sample.

I am currently working my way through the RestPathAnnotationProcessor and I think I've found a solution to fallback checking the interface when annotation is not present on the class. Though this only works for class-level annotations. The fallback needs to apply to method-level annotations on the interface as well and I am currently stuck navigating from the interface-types org.jboss.jandex.Type to the method (I was hoping to find something like declaredMethods there as well).
The idea was to iterate over the interface-types and find the matching method (by name) which is then checked for @Path. But I am not yet familiar enough with Jandex.

@ebullient
Copy link
Member

Ok. Just as something else to attempt, I updated the API to have another method:

@Path("/")
public interface SomeApi {
    @GET
    @Path("{id}")
    Response get(@PathParam("id") String id);
    
    @GET
    @Path("{id}/boom")
    Response getBoom(@PathParam("id") String id);
}

and added a quick impl to SomeResource

    @Override
    public Response getBoom(String id) {
        return Response.ok().entity(new Greet("BOOM " + id)).build();
    }

With this match pattern:

quarkus.micrometer.binder.http-server.match-patterns=/[^/]+/boom=/{id}/boom

I get the following output:

http_server_requests_seconds_count{method="GET",outcome="SUCCESS",status="200",uri="/{id}/boom",} 3.0
http_server_requests_seconds_sum{method="GET",outcome="SUCCESS",status="200",uri="/{id}/boom",} 0.202644959

Not saying we shouldn't fix the detection parts, just trying to make sure that you can get the match pattern to work, because it should.

lostiniceland added a commit to lostiniceland/quarkus that referenced this issue Feb 5, 2023
Include interfaces to resolve @path annotation
@lostiniceland
Copy link
Contributor Author

I found a working draft though this is not yet fully fleshed out (missing tests). What do you think?

lostiniceland added a commit to lostiniceland/quarkus that referenced this issue Feb 5, 2023
Include interfaces to resolve @path annotation
lostiniceland added a commit to lostiniceland/quarkus that referenced this issue Feb 7, 2023
Also search interfaces recursively
lostiniceland added a commit to lostiniceland/quarkus that referenced this issue Feb 8, 2023
Fixed @path annotation-lookup

Include interfaces in lookup to resolve @path annotation in order to produce correct path-template used for metrics.
lostiniceland added a commit to lostiniceland/quarkus that referenced this issue Feb 10, 2023
Fixed @path annotation-lookup

Include interfaces in lookup to resolve @path annotation in order to produce correct path-template used for metrics.
lostiniceland added a commit to lostiniceland/quarkus that referenced this issue Feb 10, 2023
Fixed @path annotation-lookup

Include interfaces in lookup to resolve @path annotation in order to produce correct path-template used for metrics.

Replaced deprecated method calls with recommended one
@quarkus-bot quarkus-bot bot added this to the 3.0 - main milestone Feb 14, 2023
@lostiniceland
Copy link
Contributor Author

@geoand how to backport this fix to 2.16 now?

@quarkus-bot
Copy link

quarkus-bot bot commented Feb 14, 2023

@geoand triage/backport* labels may not be added to an issue. Please add them to the corresponding pull request.

This message is automatically generated by a bot.

@geoand
Copy link
Contributor

geoand commented Feb 14, 2023

We will handle it, you don't need to do anything

@gsmet gsmet modified the milestones: 3.0 - main, 2.16.3.Final Feb 15, 2023
benkard added a commit to benkard/mulkcms2 that referenced this issue Apr 2, 2023
This MR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [flow-bin](https://github.com/flowtype/flow-bin) ([changelog](https://github.com/facebook/flow/blob/master/Changelog.md)) | devDependencies | minor | [`^0.199.0` -> `^0.200.0`](https://renovatebot.com/diffs/npm/flow-bin/0.199.0/0.200.0) |
| [com.rometools:rome](http://rometools.com) ([source](https://github.com/rometools/rome)) | compile | minor | `1.18.0` -> `1.19.0` |
| [org.postgresql:postgresql](https://jdbc.postgresql.org) ([source](https://github.com/pgjdbc/pgjdbc)) | build | patch | `42.5.3` -> `42.5.4` |
| [org.jsoup:jsoup](https://jsoup.org/) ([source](https://github.com/jhy/jsoup)) | compile | patch | `1.15.3` -> `1.15.4` |
| [io.quarkus:quarkus-maven-plugin](https://github.com/quarkusio/quarkus) | build | patch | `2.16.2.Final` -> `2.16.3.Final` |
| [io.quarkus:quarkus-universe-bom](https://github.com/quarkusio/quarkus-platform) | import | patch | `2.16.2.Final` -> `2.16.3.Final` |

---

### Release Notes

<details>
<summary>flowtype/flow-bin</summary>

### [`v0.200.0`](flow/flow-bin@9618443...b6c1eb0)

[Compare Source](flow/flow-bin@9618443...b6c1eb0)

### [`v0.199.1`](flow/flow-bin@05bb4e3...9618443)

[Compare Source](flow/flow-bin@05bb4e3...9618443)

</details>

<details>
<summary>rometools/rome</summary>

### [`v1.19.0`](https://github.com/rometools/rome/releases/tag/1.19.0)

[Compare Source](rometools/rome@1.18.0...1.19.0)

<!-- Release notes generated using configuration in .github/release.yml at 1.19.0 -->

#### What's Changed

##### 🔨 Dependency Upgrades

-   Bump flatten-maven-plugin from 1.2.7 to 1.3.0 by [@&#8203;dependabot](https://github.com/dependabot) in rometools/rome#565
-   Bump maven-bundle-plugin from 5.1.5 to 5.1.8 by [@&#8203;dependabot](https://github.com/dependabot) in rometools/rome#563
-   Bump maven-dependency-plugin from 3.3.0 to 3.5.0 by [@&#8203;dependabot](https://github.com/dependabot) in rometools/rome#602
-   Bump maven-deploy-plugin from 2.8.2 to 3.1.0 by [@&#8203;dependabot](https://github.com/dependabot) in rometools/rome#607
-   Bump maven-jar-plugin from 3.2.2 to 3.3.0 by [@&#8203;dependabot](https://github.com/dependabot) in rometools/rome#574
-   Bump maven-javadoc-plugin from 3.3.1 to 3.5.0 by [@&#8203;dependabot](https://github.com/dependabot) in rometools/rome#609
-   Bump maven-scm-plugin from 1.12.2 to 1.13.0 by [@&#8203;dependabot](https://github.com/dependabot) in rometools/rome#554
-   Bump assertj-core from 3.22.0 to 3.24.2 by [@&#8203;dependabot](https://github.com/dependabot) in rometools/rome#603
-   Bump slf4j-api from 1.7.36 to 2.0.6 by [@&#8203;dependabot](https://github.com/dependabot) in rometools/rome#596

##### Other Changes

-   Bump actions/setup-java from 3.3.0 to 3.10.0 by [@&#8203;dependabot](https://github.com/dependabot) in rometools/rome#606
-   Bump logback-classic from 1.2.10 to 1.3.5 by [@&#8203;PatrickGotthard](https://github.com/PatrickGotthard) in rometools/rome#611

**Full Changelog**: rometools/rome@1.18.0...1.19.0

</details>

<details>
<summary>pgjdbc/pgjdbc</summary>

### [`v42.5.4`](https://github.com/pgjdbc/pgjdbc/blob/HEAD/CHANGELOG.md#&#8203;4254-2023-02-15-102104--0500)

##### Fixed

fix: fix testGetSQLTypeQueryCache by searching for xid type. We used to search for box type but it is now cached. xid is not cached, this nuance is required for the test.
fix OidValueCorrectnessTest BOX_ARRAY OID, by adding BOX_ARRAY to the oidTypeName map \[MR [#&#8203;2810](https://github.com/pgjdbc/pgjdbc/issues/2810)]\((https://github.com/pgjdbc/pgjdbc/pull/2810).
fixes [Issue #&#8203;2804](pgjdbc/pgjdbc#2804).
fix: Make sure that github CI runs tests on all [MRs #&#8203;2809](\(https://github.com/pgjdbc/pgjdbc/pull/2809\)).

</details>

<details>
<summary>quarkusio/quarkus</summary>

### [`v2.16.3.Final`](https://github.com/quarkusio/quarkus/releases/tag/2.16.3.Final)

[Compare Source](quarkusio/quarkus@2.16.2.Final...2.16.3.Final)

##### Major changes

-   [#&#8203;29756](quarkusio/quarkus#29756) - Support custom Flyway credentials/URL

##### Complete changelog

-   [#&#8203;31141](quarkusio/quarkus#31141) - Resolve roles allowed configuration expression after config setup is completed
-   [#&#8203;31129](quarkusio/quarkus#31129) - Fix stuck HTTP2 request when sent challenge has resumed request
-   [#&#8203;31125](quarkusio/quarkus#31125) - Add "keep-alive-enabled" parameter to REST client reactive
-   [#&#8203;31112](quarkusio/quarkus#31112) - Qute - fix assignability check when validating expressions
-   [#&#8203;31099](quarkusio/quarkus#31099) - Use the effective Maven project build config when initializing sources and classes paths for dev mode
-   [#&#8203;31092](quarkusio/quarkus#31092) - Make sure quarkus:go-offline properly supports test scoped dependencies
-   [#&#8203;31077](quarkusio/quarkus#31077) - Qute: regression in template extension method with byte array
-   [#&#8203;31076](quarkusio/quarkus#31076) - Quarkiverse: Install instead of verify
-   [#&#8203;31074](quarkusio/quarkus#31074) - Added quarkus-jms-spi to quarkus bom
-   [#&#8203;31059](quarkusio/quarkus#31059) - Path lookup must also consider interfaces
-   [#&#8203;31046](quarkusio/quarkus#31046) - Simplify Quarkiverse release.yml workflow
-   [#&#8203;31038](quarkusio/quarkus#31038) - Update Instrumentation Processor check logic to match comment
-   [#&#8203;31036](quarkusio/quarkus#31036) - Use CDI when accessing UserTransaction/TransactionManager in QuarkusTransaction
-   [#&#8203;31028](quarkusio/quarkus#31028) - Fix typo in snapstart enable config
-   [#&#8203;31016](quarkusio/quarkus#31016) - Re-initialize platform dependent netty classes/values at runtime
-   [#&#8203;30988](quarkusio/quarkus#30988) - Race condition in SmallRye Config property expansion for [@&#8203;RolesAllowed](https://github.com/RolesAllowed) value?
-   [#&#8203;30964](quarkusio/quarkus#30964) - Add ConfigMappings from a builder class to support full hot reload
-   [#&#8203;30961](quarkusio/quarkus#30961) - Error of quarkus:dev when the project.build.directory is overridden by a profile
-   [#&#8203;30960](quarkusio/quarkus#30960) - Register CDI Bean when ConfigMapping is marked as Unremovable
-   [#&#8203;30922](quarkusio/quarkus#30922) - Fix dependency parsing in JBangBuilderImpl
-   [#&#8203;30885](quarkusio/quarkus#30885) - Add concurrency configuration to the GitHub Action workflows
-   [#&#8203;30843](quarkusio/quarkus#30843) - Micrometer-Extension writes wrong URI-Tag when Path-Variables defined at Interface-Level
-   [#&#8203;30672](quarkusio/quarkus#30672) - Avoid creating CSRF cookie if no CSRF token was created
-   [#&#8203;30648](quarkusio/quarkus#30648) - Support passing filename to multipart form data output
-   [#&#8203;30594](quarkusio/quarkus#30594) - CSRF: exception thrown when authentication falied
-   [#&#8203;30570](quarkusio/quarkus#30570) - Set filename for PartItems in MultipartFormDataOutput
-   [#&#8203;30455](quarkusio/quarkus#30455) - Introduce `quarkus.datasource.devservices.init-script-path`
-   [#&#8203;29756](quarkusio/quarkus#29756) - Support custom Flyway credentials/URL
-   [#&#8203;29631](quarkusio/quarkus#29631) - [@&#8203;Unremovable](https://github.com/Unremovable) ConfigMapping is still removed
-   [#&#8203;29630](quarkusio/quarkus#29630) - Changes to configmappings not being applied during hot reload
-   [#&#8203;28709](quarkusio/quarkus#28709) - QuarkusTransaction does not fire [@&#8203;Initialized](https://github.com/Initialized)(TransactionScoped.class)
-   [#&#8203;24639](quarkusio/quarkus#24639) - configure dedicated db user for database migrations: DML-only user for datasource, but DDL user for migration
-   [#&#8203;23360](quarkusio/quarkus#23360) - "Request has already been read" using vertx + auth
-   [#&#8203;17839](quarkusio/quarkus#17839) - Invalid memory configuration for netty maxDirectMemory in native image

</details>

<details>
<summary>quarkusio/quarkus-platform</summary>

### [`v2.16.3.Final`](quarkusio/quarkus-platform@2.16.2.Final...2.16.3.Final)

[Compare Source](quarkusio/quarkus-platform@2.16.2.Final...2.16.3.Final)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever MR is behind base branch, or you tick the rebase/retry checkbox.

👻 **Immortal**: This MR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC4yNC4wIiwidXBkYXRlZEluVmVyIjoiMzQuMjQuMCJ9-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/metrics kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants