Add start/stop count metrics to listener container#4383
Conversation
| import java.util.stream.Collectors; | ||
|
|
||
| import io.micrometer.core.instrument.Counter; | ||
| import io.micrometer.core.instrument.Metrics; |
There was a problem hiding this comment.
I think it is better to avoid tight Micrometer coupling in this abstract base class, since it is shared by all container types. Putting Micrometer types here means anything that loads AbstractMessageListenerContainer pulls in those classes even when the application does not use metrics. I would rather follow the same pattern the listener consumer and KafkaTemplate use: obtain the Micrometer context only when it is needed (take a look at obtainMicrometerHolder()). A cleaner approach might be to introduce two protected lifecycle methods to record start and stop. Subclasses such as KafkaMessageListenerContainer can override them, and a dedicated class similar to MicrometerHolder can handle the core Micrometer work. That will take a bit more design work. Let us know what you think about this idea.
|
Thank you for the detailed feedback @sobychacko! I've refactored the
Please let me know if this looks good or if anything needs adjustment. |
56a41f3 to
c30d632
Compare
There was a problem hiding this comment.
Latest changes in the PR are in the right direction. Thanks for the updates. I added some review comments. Please take a look.
In addition, please address these concerns also.
- Add tests to verify the expected behavior.
- Reference docs - since these are new metrics, we should add reference docs with detailed information.
- Then add an entry in
whats-newdoc and link it to the ref docs section. - You need to add your name as an author to all the classes you added or modified.
- Need to sign your commit using DCO - https://spring.io/blog/2025/01/06/hello-dco-goodbye-cla-simplifying-contributions-to-spring
Thanks.
| * Micrometer holder for container lifecycle metrics (start/stop counts). | ||
| * | ||
| * @author Vineeth Yelagandula | ||
| * @since 3.4 |
There was a problem hiding this comment.
This needs to be 4.1.0.
| * @author Vineeth Yelagandula | ||
| * @since 3.4 | ||
| */ | ||
| public class ContainerLifecycleMicrometerHolder { |
There was a problem hiding this comment.
This class needs to be final.
| @Nullable | ||
| private ContainerLifecycleMicrometerHolder obtainLifecycleMicrometerHolder() { | ||
| try { | ||
| if (KafkaUtils.MICROMETER_PRESENT) { |
There was a problem hiding this comment.
We also should add the this.containerProperties.isMicrometerEnabled() check (similar to the other obtain method for the listener). That way, if the user explicitly disabled micrometer via the property, then this method will (correctly so) return null.
|
|
||
| private final Counter stopCounter; | ||
|
|
||
| public ContainerLifecycleMicrometerHolder(MeterRegistry registry, String containerName) { |
There was a problem hiding this comment.
Need javadoc for the constructor.
| } | ||
|
|
||
| protected void doStop(Runnable callback) { | ||
| recordContainerStopped(); |
There was a problem hiding this comment.
This call should also go into the stopAbnormally method above.
| /** | ||
| * Called when the container is started. Subclasses may override to record metrics. | ||
| */ | ||
| protected void recordContainerStarted() { |
| /** | ||
| * Called when the container is stopped. Subclasses may override to record metrics. | ||
| */ | ||
| protected void recordContainerStopped() { |
| private ContainerLifecycleMicrometerHolder obtainLifecycleMicrometerHolder() { | ||
| try { | ||
| if (KafkaUtils.MICROMETER_PRESENT) { | ||
| org.springframework.context.ApplicationContext ctx = getApplicationContext(); |
There was a problem hiding this comment.
Why are we using FQCN here? Can we import it normally?
| org.springframework.context.ApplicationContext ctx = getApplicationContext(); | ||
| if (ctx != null) { | ||
| io.micrometer.core.instrument.MeterRegistry registry = | ||
| ctx.getBeanProvider(io.micrometer.core.instrument.MeterRegistry.class).getIfUnique(); |
There was a problem hiding this comment.
Why are we using FQCN here? Can we import it normally?
| } | ||
| } | ||
| } | ||
| catch (Exception ex) { |
There was a problem hiding this comment.
Maybe exception could be more specific? Also, add a logging statement?
|
@Yelagandula Could you take a look at these review comments? #4383 (review) |
|
Hi @sobychacko, addressed all the review comments:
Still working on tests, reference docs, whats-new entry, and author |
|
Hi @sobychacko, addressed all remaining review comments:
Please take a look when you get a chance! |
- Add protected recordContainerStarted() and recordContainerStopped() lifecycle hooks in AbstractMessageListenerContainer - Create ContainerLifecycleMicrometerHolder following obtainMicrometerHolder() pattern - Override lifecycle methods in KafkaMessageListenerContainer - Add isMicrometerEnabled() check, proper imports, IllegalStateException logging - Add tests for ContainerLifecycleMicrometerHolder - Add reference docs in micrometer.adoc - Add whats-new entry - Add @author Vineeth Yelagandula to modified classes Closes spring-projects#4277 Signed-off-by: Vineeth Yelagandula <111960524+Yelagandula@users.noreply.github.com>
a461f23 to
6812db7
Compare
|
Also squashed all commits into one clean commit with DCO sign-off. |
|
@Yelagandula Build failed on the CI. Can you take a look? Also, there are some test failures. You need to use a proper email address when signing the commit, the DCO check failed on the PR because of that. |
|
@Yelagandula Any updates on this PR? Just a reminder that we have a release coming up in a few days and if you want to include these changes as part of the |
|
@Yelagandula Any updates on this? |
Adds two Micrometer counters to AbstractMessageListenerContainer to track listener container lifecycle events:
Closes #4277