Skip to content

PR for Micrometer Integration - #64 #486

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

Merged
merged 4 commits into from
Aug 26, 2021
Merged

PR for Micrometer Integration - #64 #486

merged 4 commits into from
Aug 26, 2021

Conversation

laxmikantbpandhare
Copy link
Member

Working on Timer and other remaining part. @metacosm and @csviri - Could you please verify the code for Counter and its implemented methods.

@laxmikantbpandhare laxmikantbpandhare self-assigned this Aug 6, 2021
@laxmikantbpandhare laxmikantbpandhare changed the title PR for - Micrometer Integration - #64 PR for Micrometer Integration - #64 Aug 6, 2021
@jmrodri
Copy link
Member

jmrodri commented Aug 6, 2021

@laxmikantbpandhare will this tie into the deleteResource method for decrementing the metric? https://github.com/java-operator-sdk/java-operator-sdk/blob/master/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ResourceController.java#L28-L30

How will we ensure the increment occurs for the metrics we plan to support? Or is that for another follow on PR?

@jmrodri
Copy link
Member

jmrodri commented Aug 6, 2021

I think that we should create a metrics package in the operator-framework-core/src/main/java/io/javaoperatorsdk/operator or in operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api to house the metrics stuff. And I think CounterDetails should be in implementation detail of what we're trying to do. The issue lists a set of metrics we would like to expose by default.

  • number of controller executions
  • number of events processed
  • controller execution durations
  • number of custom resource managed
  • retry related metrics

So I think we should have a metrics.ControllerExecution which is an instance of a CounterDetails. We can then increment it for the user whenever a reconcile occurs. Similar to how controller-runtime is doing it here: https://github.com/kubernetes-sigs/controller-runtime/blob/master/pkg/internal/controller/metrics/metrics.go#L30-L33

	ReconcileTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
		Name: "controller_runtime_reconcile_total",
		Help: "Total number of reconciliations per controller",
	}, []string{"controller", "result"})

As you see in controller-runtime, there are a series of default structures that represent the default metrics they want to expose. I could see us having 5 classes representing the metrics we want.

Then in the deleteResource we would decrement the ControllerExecution.


public class CounterDetails {

int counter;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do these fields need to be package-private instead of private?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checking on this, we can make those field as a private.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't currently see what's the point of this class since it doesn't appear to be used but I would assume that it should be immutable: all fields should be private and final and there shouldn't be any setters (i.e. it shouldn't be possible to modify an instance, after it's been created)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The counter details class will be used when we call/use these utility methods. You can refer to sample memcached-quarkus-operator where I used this - https://github.com/laxmikantbpandhare/memcached-quarkus-operator/blob/main/src/main/java/com/example/MemcachedController.java

@laxmikantbpandhare
Copy link
Member Author

@laxmikantbpandhare will this tie into the deleteResource method for decrementing the metric? https://github.com/java-operator-sdk/java-operator-sdk/blob/master/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ResourceController.java#L28-L30

How will we ensure the increment occurs for the metrics we plan to support? Or is that for another follow on PR?

@jmrodri - I am still looking into the code of java-operator-sdk for delete resource functionality. I will add those changes as part of this PR only.

@laxmikantbpandhare
Copy link
Member Author

@laxmikantbpandhare will this tie into the deleteResource method for decrementing the metric? https://github.com/java-operator-sdk/java-operator-sdk/blob/master/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ResourceController.java#L28-L30

How will we ensure the increment occurs for the metrics we plan to support? Or is that for another follow on PR?

@jmrodri - We will not decrement any counter as operator-sdk does not decrement anything as such. After delete event, the reconciliation process happens thats why need to increment controller execution counter. The operator-sdk has two counters, succeeded and failed. If reconciliation process fails then failed counter increases. We will follow the same logic for our metrics part in java-operator-sdk.

@jmrodri
Copy link
Member

jmrodri commented Aug 11, 2021

@jmrodri - We will not decrement any counter as operator-sdk does not decrement anything as such. After delete event, the reconciliation process happens thats why need to increment controller execution counter. The operator-sdk has two counters, succeeded and failed. If reconciliation process fails then failed counter increases. We will follow the same logic for our metrics part in java-operator-sdk.

You are correct we only increment. Thanks.

@jmrodri
Copy link
Member

jmrodri commented Aug 11, 2021

@laxmikantbpandhare also, this code should live in a metrics package.

@laxmikantbpandhare
Copy link
Member Author

@laxmikantbpandhare also, this code should live in a metrics package.

@jmrodri - Sure, I will create metrics package and add those changes in it.

@jmrodri
Copy link
Member

jmrodri commented Aug 11, 2021

Also remember that PRs should follow the conventional commit: https://github.com/java-operator-sdk/java-operator-sdk/blob/master/CONTRIBUTING.md#pull-request-process

@laxmikantbpandhare
Copy link
Member Author

Also remember that PRs should follow the conventional commit: https://github.com/java-operator-sdk/java-operator-sdk/blob/master/CONTRIBUTING.md#pull-request-process

Modified commit as a conventional commit.

@metacosm
Copy link
Collaborator

I've converted this PR to draft since it seems quite far from being finished. I cannot really review it in its current state because I need to see:

  • which types of metrics will be provided
  • how they will integrate with the SDK code
  • which data will be recorded

@laxmikantbpandhare
Copy link
Member Author

laxmikantbpandhare commented Aug 17, 2021

@metacosm - I showed demo of metrics during our weekly meeting. Attached screen print for your reference.

Screen Shot 2021-08-17 at 12 00 21 AM

The current changes are just utility methods and I am planning to call/use those methods from reconciliation process. This will calculate the successful execution of reconciliation process. You can see in above image, I marked that data in red box.

@metacosm
Copy link
Collaborator

On a design note: I'd like to see something similar to what is seen in https://github.com/ebullient/monster-combat/blob/main/core/src/main/java/dev/ebullient/dnd/combat/client/CombatMetrics.java. All metrics-related code is confined to a single class so that it doesn't "infect" the code and we can tweak what gets recorded and how in a single spot. The SDK code would call method of this class with application-specific results (e.g. UpdateControl) as opposed to things related to metrics, though we could add metrics-related information to these objects if needed.
Also, we should only depend on micrometer-core, not micrometer-registry-prometheus so that we're not dependent on a given backend but users can choose whichever backend they want.

@laxmikantbpandhare
Copy link
Member Author

On a design note: I'd like to see something similar to what is seen in https://github.com/ebullient/monster-combat/blob/main/core/src/main/java/dev/ebullient/dnd/combat/client/CombatMetrics.java. All metrics-related code is confined to a single class so that it doesn't "infect" the code and we can tweak what gets recorded and how in a single spot. The SDK code would call method of this class with application-specific results (e.g. UpdateControl) as opposed to things related to metrics, though we could add metrics-related information to these objects if needed.
Also, we should only depend on micrometer-core, not micrometer-registry-prometheus so that we're not dependent on a given backend but users can choose whichever backend they want.

Yes, agree on this. I will update the code accordingly.

@laxmikantbpandhare
Copy link
Member Author

laxmikantbpandhare commented Aug 18, 2021

On a design note: I'd like to see something similar to what is seen in https://github.com/ebullient/monster-combat/blob/main/core/src/main/java/dev/ebullient/dnd/combat/client/CombatMetrics.java. All metrics-related code is confined to a single class so that it doesn't "infect" the code and we can tweak what gets recorded and how in a single spot. The SDK code would call method of this class with application-specific results (e.g. UpdateControl) as opposed to things related to metrics, though we could add metrics-related information to these objects if needed.
Also, we should only depend on micrometer-core, not micrometer-registry-prometheus so that we're not dependent on a given backend but users can choose whichever backend they want.

@metacosm - I completely removed CounterDetails class and added entire logic in only one class. Please review the PR. About the second suggestion, micrometer-core contains only SimpleMeterRegistry and it is the simplest form of the registry. As per me, MeterRegistry is the best option. Below links explains more about it.

Links -
https://micrometer.io/docs/installing
https://www.baeldung.com/micrometer#3-registry

@metacosm
Copy link
Collaborator

We're not going to provide a registry implementation in the SDK: this will be up to users to decide which one to use.
More precisely: the SDK will not be doing any actual metering, just provide the infrastructure for it to happen when a user selects a backend and activates it in their operator. MeterRegistry is the abstract class we should be coding against, not any implementation.

@laxmikantbpandhare
Copy link
Member Author

We're not going to provide a registry implementation in the SDK: this will be up to users to decide which one to use.
More precisely: the SDK will not be doing any actual metering, just provide the infrastructure for it to happen when a user selects a backend and activates it in their operator. MeterRegistry is the abstract class we should be coding against, not any implementation.

Ah! sorry it was my confusion. I updated dependency as said by you in Quarkus Memcached Operator and was getting UnSatisfiedDepedency for micrometer-core. It was my mistake. I updated thepom.xml file. Please review and let me know your comments.

@laxmikantbpandhare
Copy link
Member Author

@laxmikantbpandhare can you make your branch writable by maintainers, please? PRs should be opened in a way that maintainers can change stuff on it.

I already tick marked Allow edits by maintainers.

@laxmikantbpandhare
Copy link
Member Author

I've created #497 to show how I think we should go about the integration… Lots of work still to be done but should provide a basis for further discussions.

@metacosm @adam-sandor @csviri - I created similar method for deleteResource(). Please review and let me know your comments.

@metacosm
Copy link
Collaborator

On a strictly process-oriented basis: please do not request reviews for each commit. Finish the PR as you think it should be done and then we will be able to review it. Also, please leave the PR in draft mode until it's ready for review and merging, which isn't the case as this stage.

@metacosm metacosm marked this pull request as draft August 20, 2021 11:01
@laxmikantbpandhare
Copy link
Member Author

laxmikantbpandhare commented Aug 20, 2021

On a strictly process-oriented basis: please do not request reviews for each commit. Finish the PR as you think it should be done and then we will be able to review it. Also, please leave the PR in draft mode until it's ready for review and merging, which isn't the case as this stage.

@metacosm - Sure

import java.util.function.ToDoubleFunction;
import java.util.function.ToLongFunction;

public class Metrics {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me this whole construct while wrapping the logic in a Metrics class is little bit smelly, not sure if there is a better way. But will take a look soon.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially, I wrote a separate class without wrapping it. @metacosm - Chris asked to have it like above wrapping the logic.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's wrong with wrapping the logic, @csviri? More than wrapping, it's about measuring things that make sense from the operator's perspective as opposed to calling more metrics-oriented methods. Another aspect is that all metrics code is in a single spot which makes it easier to figure out what's measured and change it if needed.

Copy link
Collaborator

@csviri csviri Aug 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That the metrics code is in one place that is good. That we are mixing the application logic with metrics is not that nice. Those should be as loosely coupled as possible IMHO. And also seamlessly if possible.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't say I have a better answer for this now, just mentioning that design principle. So something to think about.

feature: micrometer integration for genering metrics

feature: modified variables and made it private

feature: added changes for customize increment method

feature: removed ConterDetails class and modified IncrementCounter accordingly

feature: modified pom depedency

feature: modified pom depedency

feature: added changes and wrapped counter and timer with createAndUpdate method

feature: modified and added inceremenmt() method

feature: modified for enabling google formatter

removed spaces

removed spaces

feature: added counter and timer for delete resource

feature: added counter and timer for delete resource

feature: added changes for delete resource

feature: added changes for delete resource

feature: update control modified

feature: delete control modified

feature: delete control modified

test delete resource

feature: modiofied to retest

feature: modified according to PR review comments

feature: added count for each and event (create, update, and delete)

feature: added count for each and event (create, update, and delete)

feature: added Histogram changes for Time

feature: added histogram changes for delete as well

feature: modified name field in tags

feature: retry counter added
@jmrodri
Copy link
Member

jmrodri commented Aug 25, 2021

@laxmikantbpandhare can you make your branch writable by maintainers, please? PRs should be opened in a way that maintainers can change stuff on it.

This sounds odd to me. I've never done that for any of my other contributions to other projects.

@laxmikantbpandhare
Copy link
Member Author

Update on the PR -

  1. number of controller executions - Added count of controller execution for create, update, and delete events.

  2. number of events processed - Added common count in each try and catch block of createUpdate and Delete method. It will count total events as we discussed in last weeks call.

  3. controller execution durations - Added timer for controller execution which will count method execution time for createUpdate, and Delete method .

  4. number of custom resource managed - As per discussion with @csviri, we are ignoring this task for now.

  5. retry related metrics - Added changes for count retry related metrics.

@laxmikantbpandhare laxmikantbpandhare marked this pull request as ready for review August 25, 2021 18:52
@laxmikantbpandhare
Copy link
Member Author

@metacosm - I added changes in DefaultEventHandler. I created object of Metrics and not added it into the Constructor Parameter as it is causing changes in Multiple files. I used NoopMeterRegistry due to which it asked me to make it Public. These are the changes I did as part of retry related metrics.

Copy link
Collaborator

@metacosm metacosm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get this merged and do subsequent changes on different PRs.

@metacosm metacosm merged commit 7aa9bf3 into operator-framework:master Aug 26, 2021
@laxmikantbpandhare laxmikantbpandhare added kind/feature Categorizes issue or PR as related to a new feature. feature labels Aug 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature kind/feature Categorizes issue or PR as related to a new feature.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Expose Operator metrics out-of-the-box Metrics - Micrometer Integration
5 participants