-
Notifications
You must be signed in to change notification settings - Fork 2.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
Amtool implementation #636
Conversation
The primary goal of an alertmanager tool is to provide a cli interface for the prometheus alertmanager. My vision for this tool has two parts: - Silence management (query, add, delete) - Alert management (query, maybe more in future?) Resolves: prometheus#567
Error messages are maybe better?
* also allow for man page generation * update vendors to include cobra/doc * split silence commands into multiple files * move some ommon gits into utils.go
Amtool initial implementation
Oops. Looks like I have some vendoring issues |
Looks quite cool. But also very involved. Before we dive into code-level review, it would be great if @fabxc and/or @brancz could comment if this is fundamentally sane and meeting their expectations. @stuartnelson3 might also have an opinion as he is getting into the AM API quite a bit recently. |
cli/utils.go
Outdated
} | ||
|
||
// Parse a list of labels (cli arguments) | ||
func parseMatchers(labels []string, resolve int) (types.Matchers, error) { |
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.
This is re-implementing functionality that already exists in PromQL, which seems like another vote for moving PromQL to a standalone package as mentioned in this PR #633
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.
Hmm. I looked at this, but it didn't immediately strike me as a fitting what I was trying to do. I'll have to take another look.
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.
It's my hope to #633 merged soon, so then the tool could accept a promql label matcher string ({foo="bar", baz=~"qu.*"}
) and pass that on to the api.
this would be changing your api, however, so it's worth a discussion, and looping in @fabxc to see what he thinks. It looks like this might be expanding into generating a swagger api. Let's drop the discussion down to the main flow of the PR.
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 other issue I had was that I needed to filter silences. Will that be covered in #633 ?
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.
Filtering silences is available in that pr, in 0954959
I'm going to try to get that PR pushed through, then it should just be a few easy changes here and we can get this merged.
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.
Cool. Looking at that.
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.
Quick question.
I implemented a feature where if a user doing a query (silence or alert) does something like the following:
amtool alert query Host
With no matcher name specified then I attempt to match the alertname using a prefix match. Is this something we want to support? Moving to promql should do everything I want, but i'm curious if I should spend the time to re-implement this functionality?
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.
hm, @fabxc ?
cli/silence_add.go
Outdated
|
||
buf := bytes.NewBuffer([]byte{}) | ||
enc := json.NewEncoder(buf) | ||
err = enc.Encode(silence) |
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.
json.NewEncoder(buf).Encode(silence)
The encode and decode stuff doesn't get re-used, so no need to assign it to a var.
cli/silence_add.go
Outdated
decoder := json.NewDecoder(res.Body) | ||
|
||
response := addResponse{} | ||
err = decoder.Decode(&response) |
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.
Same as above
cli/silence_add.go
Outdated
response := addResponse{} | ||
err = decoder.Decode(&response) | ||
if err != nil { | ||
return errors.New(fmt.Sprintf("Unable to parse silence json response from %s", u.String())) |
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.
errors.New(fmt.Sprintf("..", thing1, thing2)) == fmt.Errorf("..", thing1, thing2)
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.
TIL
Sorry for not having an update in quite a few days. Been busy with other things at work. |
* refactor alert fetch to pull filters * discard all multiple query logic in favor of simpler regex * discard all matching logic * cleanup a number of small things that made the code odd * relax the regex in pkg/parse/parse.go to allow no quote characters
Running the top level
The documentation seems to say this is valid though:
Actually, it seems like every query I'm running is resulting in a bad matcher error?
Same deal with silences: Showing all silences works, but when I try to query for them it says bad matcher. |
Looks like I forgot to register the Silence seems to be working in my testing environment. Did you rebuild your alertmanager and docker container? |
Ahhhh yeah I didn't rebuild the actual alertmanager binary :) This is super cool! Querying seems to be working, except for the bare alertname case:
Other than that this looks pretty cool to me. One thing that would be nice is also filtering by receiver as a sort of special key-value pair, but I think we can wait on that because it's also a desired feature in the UI, so doing that via a query param in the API is probably what will happen. |
Oh I don't think I re-implemented the bare alertname functionality now that I'm not parsing any of the arguments. Should be reasonably simple to re-add |
seems to also be an error when using the config subcommand:
expiring an already expired silence:
it also seems that any error output is duplicated? I noticed this before but forgot to mention it. One idea that I had while interacting with this: It's awesome that I can e.g.:
But this requires me to do some bashery to grab the IDs:
Taking a cue from the docker cli, what do you think about adding a
Seems to be |
I think the After a little bit of debugging it seems that the |
Also remove uneeded function
@@ -46,8 +46,7 @@ func NewMatcher(t MatchType, n, v string) (*Matcher, error) { | |||
Value: v, | |||
} | |||
if t == MatchRegexp || t == MatchNotRegexp { | |||
m.Value = "^(?:" + v + ")$" | |||
re, err := regexp.Compile(m.Value) | |||
re, err := regexp.Compile("^(?:" + m.Value + ")$") |
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.
This seems to be the cause of the regex information showing up in the ui since I'm using the internal parser to parse silence matchers.
Is this change acceptable? All tests are still passing
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 would prefer not to diverge from vendored packages.
I went through the code and made a couple changes, but I'll leave it to you to apply them to your branch.
First, reverting the change to the vendored package:
git revert 5d0bba4b3b3e682b4eae10381ce96660d5c3979a
Then here's a patch file that you can apply. Read through it to see what it does, but basically it separates out the actual parsing code in pkg/parse
so that there's an exported function for parsing the raw input string, which the CLI then uses to send to the API.
Note: Apparently github won't let me upload a .patch
file, so it says text, but you should be able to apply it all the same.
Edit:
In case you have to google it (which I always do 🤷♂️ ), I'll save you the 30sec:
git apply parse_regex.patch
What are our next steps to get this merged? |
There are a few things that need to be fixed:
After that this should be ready to merge. Thanks for you patience! |
Awesome. I'm going to go ahead and merge this because it's been so long in a branch. There's an issue I would like to address still, but I'll put that in issue #721 |
As discussed in #567