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

Prometheus encoder added similar to hostd #1068

Closed
wants to merge 7 commits into from

Conversation

bustedware
Copy link
Contributor

Prometheus encoder added to renterd similar to hostd. ?response=prometheus added for various endpoints

@ChrisSchinnerl ChrisSchinnerl changed the base branch from master to dev March 15, 2024 09:10
Copy link
Member

@ChrisSchinnerl ChrisSchinnerl left a comment

Choose a reason for hiding this comment

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

I updated the base branch to dev since we don't develop on master in renterd.

@@ -175,6 +176,34 @@ func (ap *Autopilot) Handler() http.Handler {
})
}

func (ap *Autopilot) writeResponse(c jape.Context, code int, resp any) {
Copy link
Member

Choose a reason for hiding this comment

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

Can you move the content of this to a function in a new file api/utils.go like so

func WriteResponse(c jape.Context, code int, resp any) error

and then call that function in here, check its error, and log it? Right now there is a lot of duplicate code.

enc := prometheus.NewEncoder(c.ResponseWriter)
if err := enc.Append(v); err != nil {
ap.logger.Error("failed to marshal prometheus response", zap.Error(err))
return
Copy link
Member

Choose a reason for hiding this comment

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

You return here without calling c.Error.

Copy link
Member

Choose a reason for hiding this comment

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

I'd move all your prometheus.go files into a single api/prometheus.go and implement the interface directly on the types. The types in api/*.go are supposed to be the types that get returned by the API and casting to a new type breaks that promise in some sense. Plus we can get rid of the casting altogether this way.

@@ -701,7 +730,7 @@ func (ap *Autopilot) stateHandlerGET(jc jape.Context) {
return
}

jc.Encode(api.AutopilotStateResponse{
ap.writeResponse(jc, http.StatusOK, AutopilotStateResp(api.AutopilotStateResponse{
Copy link
Member

Choose a reason for hiding this comment

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

This won't work with our static code analysis tool jape. It expects jc.Encode to be called in the handler right now. So without updating that this won't make it through the CI.

Copy link
Member

Choose a reason for hiding this comment

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

We should seriously consider extending jape to support this or maybe try and write some kind of middleware for it. It won't work otherwise. Maybe we can make jape.Context an interface and then we can swap it (using a middleware) with one that's capable of handling prometheus response types. E.g. test the interface in Encode on some kind of interface that implements toPrometheus and handle it accordingly


type AutopilotStateResp api.AutopilotStateResponse

func (asr AutopilotStateResp) PrometheusMetric() (metrics []prometheus.Metric) {
Copy link
Member

Choose a reason for hiding this comment

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

I'd implement PrometheusMetric or maybe ToPrometheus on the actual return type in the api package within a single api/prometheus.go. That way we don't need 3 of these prometheus.go files with duplicated types.

If a return type doesn't exist yet because it's directly returning a types.Currency or something it's fine to create a new one in the api package.

Copy link
Member

Choose a reason for hiding this comment

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

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@n8maninger wrote this I can'ti would run it by him before I make any changes to it.

var resp interface{}
err = json.Unmarshal([]byte(setting), &resp)
if err != nil {
jc.Error(fmt.Errorf("couldn't unmarshal the setting, error: %v", err), http.StatusInternalServerError)
return
}

jc.Encode(resp)
if key == "s3authentication" {
Copy link
Member

Choose a reason for hiding this comment

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

why only return the s3authentication setting as a prometheus metric?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the other data points are already being collected elsewhere for the other settings so it wasn't needed.

@@ -175,6 +176,34 @@ func (ap *Autopilot) Handler() http.Handler {
})
}

func (ap *Autopilot) writeResponse(c jape.Context, code int, resp any) {
Copy link
Member

Choose a reason for hiding this comment

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

code is unused by the way

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hey I think @n8maninger wrote this method not sure what it does I just use it

return
}

type ContractsResp []api.ContractMetadata
Copy link
Member

Choose a reason for hiding this comment

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

What happens if you define PrometheusMetric on api.ContractMetadata. Wouldn't it automatically work for slices of the type too? This is a little add and when we move this PrometheusMetric methods to the api package it would be nice if we could avoid adding custom types for everything we return slices of.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

im not sure

@peterjan
Copy link
Member

@bustedware do you think you'll have some time this month to update your PR?

@bustedware
Copy link
Contributor Author

@peterjan no I don't have time. this effort officially expired in January

@ChrisSchinnerl
Copy link
Member

Closing this for now since it is no longer maintained.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants