-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Add support for fetching rules with API client #508
Add support for fetching rules with API client #508
Conversation
Signed-off-by: Bob Shannon <[email protected]>
api/prometheus/v1/api.go
Outdated
type RuleGroup struct { | ||
Name string `json:"name"` | ||
File string `json:"file"` | ||
Rules []Rule `json:"rules"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since a Rule can be either recording
or alerting
, I'm not sure if we actually want to use a stronger type here with two fields RecordingRules
and AlertingRules
, or put everything in the same list to preserve the rule order like https://github.com/prometheus/prometheus/blob/master/web/api/v1/api.go#L721 does.
That one is for @krasi-georgiev . 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM , but would be best if @simonpasquier and @mxinden can also have a quick look.
One thing I don't like is that we are using server mocks for the tests, but that is a story for another PR tracking in #485 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking into this @bobmshannon. I am hoping that in the future we could generate clients based on e.g. OpenAPI specifications like we will soon do in github.com/prometheus/alertmanager.
I have a couple of comments. What are your thoughts?
RuleTypeAlerting RuleType = "alerting" | ||
|
||
// Possible values for RuleHealth. | ||
RuleHealthGood = "ok" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not import them from here? https://github.com/prometheus/prometheus/blob/master/rules/manager.go#L46
@@ -67,6 +82,15 @@ const ( | |||
HealthGood HealthStatus = "up" | |||
HealthUnknown HealthStatus = "unknown" | |||
HealthBad HealthStatus = "down" | |||
|
|||
// Possible values for RuleType. | |||
RuleTypeRecording RuleType = "recording" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mhh, its a bummer that I didn't expose these as constants when I added this. Sorry about that. Feel free to propose a patch on prometheus/prometheus.
Groups []RuleGroup `json:"groups"` | ||
} | ||
|
||
type RuleGroup struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in general I am ok with duplicating types if this avoid a package dependency.
I follow the principle - import a package for its functionality and not for its types.
Here doesn't matter that much so I am ok either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The primary reasons for not not importing RuleGroup
from the v1
API package referenced above:
RuleGroup
models the list of rules asinterface{}
- this requires the client to use type assertion to determine whether a given rule is a recording or alerting rule.- It adds an external dependency that the client will need to import in order to use this API client package.
api/prometheus/v1/api.go
Outdated
Interval float64 `json:"interval"` | ||
} | ||
|
||
type Rule struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name Rule
is misleading, as recording rules do not expose e.g. Alerts
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, could we import structs from prometheus/prometheus instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should just create two new types here: RecordingRule
and AlertingRule
. Is there any reason why order needs to be preserved by putting both types of rules in the same array?
If we create these two new types, I think we'll need some changes to the imported structs, for example recordingRule
and alertingRule
are not exported so can't be consumed by this package:
https://github.com/prometheus/prometheus/blob/master/web/api/v1/api.go#L730
https://github.com/prometheus/prometheus/blob/master/web/api/v1/api.go#L743
I'm happy make the changes to this PR such that the types are imported from As for using OpenAPI to generate the client code, agreed it would be a very nice place to get to. |
ccc3e2d
to
d813b11
Compare
@mxinden Do you mind having another look at this one? I addressed some of the comments and added new fields I think that importing the types at this point may be more trouble than it's worth, and we should probably just plan to supercede this client with the OpenAPI generated one, however I could be wrong about this. |
Signed-off-by: Bob Shannon <[email protected]>
d813b11
to
e41661f
Compare
api/prometheus/v1/api.go
Outdated
var recordingRules []RecordingRule | ||
|
||
for _, rule := range v.Rules { | ||
// Because both recording and alerting rules are stored in the same |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are stored in the same JSON array as the ordering among them matters (See prometheus/prometheus#4318 (comment) for more details). That way users can understand which rules depend on which.
I am not sure this is a blocker. But probably worth mentioning in a comment somewhere. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing me to that.
To keep things consistent, I've modified the client to preserve rule order as returned by the API, and added some documentation on this behavior regarding how to use a type switch to access each recording or alerting rule.
On the one hand given the fact that this client is already tightly coupled with the On the other hand according to the README of this repository we don't give any stability guarantees in regards to the client. Thereby I am fine with going either way. |
Signed-off-by: Bob Shannon <[email protected]>
62f239d
to
5d5fea7
Compare
// default: | ||
// fmt.Printf("unknown rule type %s", v) | ||
// } | ||
type Rules []interface{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this type used? Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, fixed.
api/prometheus/v1/api.go
Outdated
if !ok { | ||
return errors.New("rule has no type field") | ||
} | ||
ruleJSON, err := json.Marshal(rule) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused here. You are marshaling a rule to unmarshal it?
How about unmarshaling the rule into something like this first:
struct {
type string
}
and depending on type
unmarshal as a recording or an alerting rule?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With that approach I think we'd still need to get the complete byte or JSON encoding of each individual rule (by using MarshalJSON) in order to unmarshal them into a typed recording or alerting rule. That said, I think most of the complexity here is from decoding the mixed type slice and there may not be a super elegant way to do it in Go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made an update to this PR that should be easier to read and is more in-line with the approach suggested in this comment.
Signed-off-by: Bob Shannon <[email protected]>
Signed-off-by: Bob Shannon <[email protected]>
bb466da
to
40f84cb
Compare
Signed-off-by: Bob Shannon <[email protected]>
f6357a9
to
2c872b9
Compare
@mxinden I've made some adjustments to this PR based on the most recent comments, please let me know what you think. |
@beorn7 @mxinden Just wanted to circle back on this one, is there anything I can do to help push this one through? It would be really nice to have this functionality in the API client for my use-case and for any external system that fetches alert and rules data from Prometheus. Thanks in advanced. :) |
I'd like to see @mxinden and @krasi-georgiev to have the final look here. |
yeah waiting for Max for the final input. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that the general preference seems to go towards duplication over dependency, this looks good to me.
I am sorry for the delayed response, just came back from a couple of weeks of vacation.
Great, thanks! |
Thanks |
This PR adds support for fetching rules via the
/api/v1/rules
endpoint using the API client. Currently, the API client exposes no way to do this and it would be nice to have for external systems that wish to retrieve this information.cc @beorn7