mirror of
https://github.com/prometheus/alertmanager
synced 2025-03-31 23:59:03 +00:00
Add cluster command to show cluster and peer statuses. (#2256)
Signed-off-by: Fahri Yardımcı <f.yardimci06@gmail.com> Signed-off-by: Fahri Yardımcı <f.yardimci06@gmail.com>
This commit is contained in:
parent
de80d907d1
commit
12db463c7f
43
cli/cluster.go
Normal file
43
cli/cluster.go
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2020 Prometheus Team
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
|
||||
"github.com/prometheus/alertmanager/cli/format"
|
||||
)
|
||||
|
||||
const clusterHelp = `View cluster status and peers.`
|
||||
|
||||
// clusterCmd represents the cluster command
|
||||
func configureClusterCmd(app *kingpin.Application) {
|
||||
clusterCmd := app.Command("cluster", clusterHelp)
|
||||
clusterCmd.Command("show", clusterHelp).Default().Action(execWithTimeout(showStatus)).PreAction(requireAlertManagerURL)
|
||||
}
|
||||
|
||||
func showStatus(ctx context.Context, _ *kingpin.ParseContext) error {
|
||||
alertManagerStatus, err := getRemoteAlertmanagerConfigStatus(ctx, alertmanagerURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
formatter, found := format.Formatters[output]
|
||||
if !found {
|
||||
return errors.New("unknown output formatter")
|
||||
}
|
||||
return formatter.FormatClusterStatus(alertManagerStatus.Cluster)
|
||||
}
|
@ -39,6 +39,7 @@ type Formatter interface {
|
||||
FormatSilences([]models.GettableSilence) error
|
||||
FormatAlerts([]*models.GettableAlert) error
|
||||
FormatConfig(*models.AlertmanagerStatus) error
|
||||
FormatClusterStatus(status *models.ClusterStatus) error
|
||||
}
|
||||
|
||||
// Formatters is a map of cli argument names to formatter interface object.
|
||||
|
@ -89,6 +89,27 @@ func (formatter *ExtendedFormatter) FormatConfig(status *models.AlertmanagerStat
|
||||
return nil
|
||||
}
|
||||
|
||||
// FormatClusterStatus formats the cluster status with peers into a readable string.
|
||||
func (formatter *ExtendedFormatter) FormatClusterStatus(status *models.ClusterStatus) error {
|
||||
w := tabwriter.NewWriter(formatter.writer, 0, 0, 2, ' ', 0)
|
||||
fmt.Fprintf(w,
|
||||
"Cluster Status:\t%s\nNode Name:\t%s\n\n",
|
||||
*status.Status,
|
||||
status.Name,
|
||||
)
|
||||
fmt.Fprintln(w, "Address\tName")
|
||||
sort.Sort(ByAddress(status.Peers))
|
||||
for _, peer := range status.Peers {
|
||||
fmt.Fprintf(
|
||||
w,
|
||||
"%s\t%s\t\n",
|
||||
*peer.Address,
|
||||
*peer.Name,
|
||||
)
|
||||
}
|
||||
return w.Flush()
|
||||
}
|
||||
|
||||
func extendedFormatLabels(labels models.LabelSet) string {
|
||||
output := []string{}
|
||||
for name, value := range labels {
|
||||
|
@ -47,3 +47,8 @@ func (formatter *JSONFormatter) FormatConfig(status *models.AlertmanagerStatus)
|
||||
enc := json.NewEncoder(formatter.writer)
|
||||
return enc.Encode(status)
|
||||
}
|
||||
|
||||
func (formatter *JSONFormatter) FormatClusterStatus(status *models.ClusterStatus) error {
|
||||
enc := json.NewEncoder(formatter.writer)
|
||||
return enc.Encode(status)
|
||||
}
|
||||
|
@ -75,6 +75,16 @@ func (formatter *SimpleFormatter) FormatConfig(status *models.AlertmanagerStatus
|
||||
return nil
|
||||
}
|
||||
|
||||
func (formatter *SimpleFormatter) FormatClusterStatus(status *models.ClusterStatus) error {
|
||||
w := tabwriter.NewWriter(formatter.writer, 0, 0, 2, ' ', 0)
|
||||
fmt.Fprintf(w,
|
||||
"Cluster Status:\t%s\nNode Name:\t%s\n",
|
||||
*status.Status,
|
||||
status.Name,
|
||||
)
|
||||
return w.Flush()
|
||||
}
|
||||
|
||||
func simpleFormatMatchers(matchers models.Matchers) string {
|
||||
output := []string{}
|
||||
for _, matcher := range matchers {
|
||||
|
@ -14,6 +14,9 @@
|
||||
package format
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/alertmanager/api/v2/models"
|
||||
@ -34,3 +37,19 @@ func (s ByStartsAt) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s ByStartsAt) Less(i, j int) bool {
|
||||
return time.Time(*s[i].StartsAt).Before(time.Time(*s[j].StartsAt))
|
||||
}
|
||||
|
||||
type ByAddress []*models.PeerStatus
|
||||
|
||||
func (s ByAddress) Len() int { return len(s) }
|
||||
func (s ByAddress) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s ByAddress) Less(i, j int) bool {
|
||||
ip1, port1, _ := net.SplitHostPort(*s[i].Address)
|
||||
ip2, port2, _ := net.SplitHostPort(*s[j].Address)
|
||||
if ip1 == ip2 {
|
||||
p1, _ := strconv.Atoi(port1)
|
||||
p2, _ := strconv.Atoi(port2)
|
||||
return p1 < p2
|
||||
} else {
|
||||
return bytes.Compare(net.ParseIP(ip1), net.ParseIP(ip2)) < 0
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ func Execute() {
|
||||
configureAlertCmd(app)
|
||||
configureSilenceCmd(app)
|
||||
configureCheckConfigCmd(app)
|
||||
configureClusterCmd(app)
|
||||
configureConfigCmd(app)
|
||||
|
||||
err = resolver.Bind(app, os.Args[1:])
|
||||
|
Loading…
Reference in New Issue
Block a user