...

Source file src/github.com/prometheus/alertmanager/cli/alert_query.go

Documentation: github.com/prometheus/alertmanager/cli

     1  // Copyright 2018 Prometheus Team
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package cli
    15  
    16  import (
    17  	"context"
    18  	"errors"
    19  	"fmt"
    20  
    21  	"gopkg.in/alecthomas/kingpin.v2"
    22  
    23  	"github.com/prometheus/alertmanager/api/v2/client/alert"
    24  	"github.com/prometheus/alertmanager/cli/format"
    25  	"github.com/prometheus/alertmanager/pkg/labels"
    26  )
    27  
    28  type alertQueryCmd struct {
    29  	inhibited, silenced, active, unprocessed bool
    30  	receiver                                 string
    31  	matcherGroups                            []string
    32  }
    33  
    34  const alertQueryHelp = `View and search through current alerts.
    35  
    36  Amtool has a simplified prometheus query syntax, but contains robust support for
    37  bash variable expansions. The non-option section of arguments constructs a list
    38  of "Matcher Groups" that will be used to filter your query. The following
    39  examples will attempt to show this behaviour in action:
    40  
    41  amtool alert query alertname=foo node=bar
    42  
    43  	This query will match all alerts with the alertname=foo and node=bar label
    44  	value pairs set.
    45  
    46  amtool alert query foo node=bar
    47  
    48  	If alertname is omitted and the first argument does not contain a '=' or a
    49  	'=~' then it will be assumed to be the value of the alertname pair.
    50  
    51  amtool alert query 'alertname=~foo.*'
    52  
    53  	As well as direct equality, regex matching is also supported. The '=~' syntax
    54  	(similar to prometheus) is used to represent a regex match. Regex matching
    55  	can be used in combination with a direct match.
    56  
    57  Amtool supports several flags for filtering the returned alerts by state
    58  (inhibited, silenced, active, unprocessed). If none of these flags is given,
    59  only active alerts are returned.
    60  `
    61  
    62  func configureQueryAlertsCmd(cc *kingpin.CmdClause) {
    63  	var (
    64  		a        = &alertQueryCmd{}
    65  		queryCmd = cc.Command("query", alertQueryHelp).Default()
    66  	)
    67  	queryCmd.Flag("inhibited", "Show inhibited alerts").Short('i').BoolVar(&a.inhibited)
    68  	queryCmd.Flag("silenced", "Show silenced alerts").Short('s').BoolVar(&a.silenced)
    69  	queryCmd.Flag("active", "Show active alerts").Short('a').BoolVar(&a.active)
    70  	queryCmd.Flag("unprocessed", "Show unprocessed alerts").Short('u').BoolVar(&a.unprocessed)
    71  	queryCmd.Flag("receiver", "Show alerts matching receiver (Supports regex syntax)").Short('r').StringVar(&a.receiver)
    72  	queryCmd.Arg("matcher-groups", "Query filter").StringsVar(&a.matcherGroups)
    73  	queryCmd.Action(execWithTimeout(a.queryAlerts))
    74  }
    75  
    76  func (a *alertQueryCmd) queryAlerts(ctx context.Context, _ *kingpin.ParseContext) error {
    77  	if len(a.matcherGroups) > 0 {
    78  		// Attempt to parse the first argument. If the parser fails
    79  		// then we likely don't have a (=|=~|!=|!~) so lets assume that
    80  		// the user wants alertname=<arg> and prepend `alertname=` to
    81  		// the front.
    82  		m := a.matcherGroups[0]
    83  		_, err := labels.ParseMatcher(m)
    84  		if err != nil {
    85  			a.matcherGroups[0] = fmt.Sprintf("alertname=%s", m)
    86  		}
    87  	}
    88  
    89  	// If no selector was passed, default to showing active alerts.
    90  	if !a.silenced && !a.inhibited && !a.active && !a.unprocessed {
    91  		a.active = true
    92  	}
    93  
    94  	alertParams := alert.NewGetAlertsParams().WithContext(ctx).
    95  		WithActive(&a.active).
    96  		WithInhibited(&a.inhibited).
    97  		WithSilenced(&a.silenced).
    98  		WithUnprocessed(&a.unprocessed).
    99  		WithReceiver(&a.receiver).
   100  		WithFilter(a.matcherGroups)
   101  
   102  	amclient := NewAlertmanagerClient(alertmanagerURL)
   103  
   104  	getOk, err := amclient.Alert.GetAlerts(alertParams)
   105  	if err != nil {
   106  		return err
   107  	}
   108  
   109  	formatter, found := format.Formatters[output]
   110  	if !found {
   111  		return errors.New("unknown output formatter")
   112  	}
   113  	return formatter.FormatAlerts(getOk.Payload)
   114  }
   115  

View as plain text