Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
gotjosh committed Mar 22, 2024
2 parents 8bcbaab + 14cbe63 commit a7b1ed4
Show file tree
Hide file tree
Showing 66 changed files with 1,662 additions and 641 deletions.
8 changes: 8 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ linters:
enable:
- depguard
- errorlint
- godot
- gofumpt
- goimports
- misspell
Expand Down Expand Up @@ -51,6 +52,13 @@ linters-settings:
- (github.com/go-kit/log.Logger).Log
# Never check for rollback errors as Rollback() is called when a previous error was detected.
- (github.com/prometheus/prometheus/storage.Appender).Rollback
godot:
scope: toplevel
exclude:
- "^ ?This file is safe to edit"
- "^ ?scheme value"
period: true
capital: true
goimports:
local-prefixes: github.com/prometheus/alertmanager
gofumpt:
Expand Down
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@
## 0.27.0 / 2024-02-28

* [CHANGE] Discord Integration: Enforce max length in `message`. #3597
* [CHANGE] API: Removal of all `api/v1/` endpoints. These endpoints now log and return a deprecation message and respond with a status code of `410`. #2970
* [FEATURE] UTF-8 Support: Introduction of support for any UTF-8 character as part of label names and matchers. Please read more below. #3453, #3483, #3567, #3570
* [FEATURE] Metrics: Introduced the experimental feature flag `--enable-feature=receiver-name-in-metrics` to include the receiver name in the following metrics: #3045
* `alertmanager_notifications_total`
* `alertmanager_notifications_failed_totall`
* `alertmanager_notification_requests_total`
* `alertmanager_notification_requests_failed_total`
* `alertmanager_notification_latency_seconds`
* [FEATURE] Metrics: Introduced a new gauge named `alertmanager_inhibition_rules` that counts the number of configured inhibition rules. #3681
* [FEATURE] Metrics: Introduced a new counter named `alertmanager_alerts_supressed_total` that tracks muted alerts, it contains a `reason` label to indicate the source of the mute. #3565
* [ENHANCEMENT] Discord Integration: Introduced support for `webhook_url_file`. #3555
* [ENHANCEMENT] Microsoft Teams Integration: Introduced support for `webhook_url_file`. #3555
* [ENHANCEMENT] Microsoft Teams Integration: Add support for `summary`. #3616
* [ENHANCEMENT] Metrics: Notification metrics now support two new values for the label `reason`, `contextCanceled` and `contextDeadlineExceeded`. #3631
* [ENHANCEMENT] Email Integration: Contents of `auth_password_file` are now trimmed of prefixed and suffixed whitespace. #3680
* [BUGFIX] amtool: Fixes the error `scheme required for webhook url` when using amtool with `--alertmanager.url`. #3509
* [BUGFIX] Mixin: Fix `AlertmanagerFailedToSendAlerts`, `AlertmanagerClusterFailedToSendAlerts`, and `AlertmanagerClusterFailedToSendAlerts` to make sure they ignore the `reason` label. #3599

### Removal of API v1

The Alertmanager `v1` API has been deprecated since January 2019 with the release of Alertmanager `v0.16.0`. With the release of version `0.27.0` it is now removed.
A successful HTTP request to any of the `v1` endpoints will log and return a deprecation message while responding with a status code of `410`.
Please ensure you switch to the `v2` equivalent endpoint in your integrations before upgrading.

### Alertmanager support for all UTF-8 characters in matchers and label names

Starting with Alertmanager `v0.27.0`, we have a new parser for matchers that has a number of backwards incompatible changes. While most matchers will be forward-compatible, some will not. Alertmanager is operating a transition period where it supports both UTF-8 and classic matchers, so **it's entirely safe to upgrade without any additional configuration**. With that said, we recommend the following:

- If this is a new Alertmanager installation, we recommend enabling UTF-8 strict mode before creating an Alertmanager configuration file. You can enable strict mode with `alertmanager --config.file=config.yml --enable-feature="utf8-strict-mode"`.

- If this is an existing Alertmanager installation, we recommend running the Alertmanager in the default mode called fallback mode before enabling UTF-8 strict mode. In this mode, Alertmanager will log a warning if you need to make any changes to your configuration file before UTF-8 strict mode can be enabled. **Alertmanager will make UTF-8 strict mode the default in the next two versions**, so it's important to transition as soon as possible.

Irrespective of whether an Alertmanager installation is a new or existing installation, you can also use `amtool` to validate that an Alertmanager configuration file is compatible with UTF-8 strict mode before enabling it in Alertmanager server by running `amtool check-config config.yml` and inspecting the log messages.

Should you encounter any problems, you can run the Alertmanager with just the classic parser enabled by running `alertmanager --config.file=config.yml --enable-feature="classic-mode"`. If so, please submit a bug report via GitHub issues.

## 0.26.0 / 2023-08-23

* [SECURITY] Fix stored XSS via the /api/v1/alerts endpoint in the Alertmanager UI. CVE-2023-40577
Expand Down
4 changes: 2 additions & 2 deletions Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ SKIP_GOLANGCI_LINT :=
GOLANGCI_LINT :=
GOLANGCI_LINT_OPTS ?=
GOLANGCI_LINT_VERSION ?= v1.55.2
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64.
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.
# windows isn't included here because of the path separator being different.
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386))
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386 arm64))
# If we're in CI and there is an Actions file, that means the linter
# is being run in Actions, so we don't need to run it here.
ifneq (,$(SKIP_GOLANGCI_LINT))
Expand Down
3 changes: 2 additions & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ Release cadence of first pre-releases being cut is 12 weeks.
| release series | date (year-month-day) | release shepherd |
|----------------|-----------------------|-------------------------------|
| v0.26 | 2023-08-23 | Josh Abreu (Github: @gotjosh) |
| v0.27 | 2023-11-01 | Josh Abreu (Github: @gotjosh) |
| v0.27 | 2024-02-28 | Josh Abreu (Github: @gotjosh) |
| v0.28 | 2024-05-28 | Josh Abreu (Github: @gotjosh) |

If you are interested in volunteering please create a pull request against the [prometheus/alertmanager](https://github.com/prometheus/alertmanager) repository and propose yourself for the release of your choice.

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.26.0
0.27.0
1 change: 0 additions & 1 deletion api/v1_deprecation_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
// 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 l

package api

Expand Down
8 changes: 4 additions & 4 deletions api/v2/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import (
"github.com/prometheus/alertmanager/types"
)

// API represents an Alertmanager API v2
// API represents an Alertmanager API v2.
type API struct {
peer cluster.ClusterPeer
silences *silence.Silences
Expand Down Expand Up @@ -82,7 +82,7 @@ type (
setAlertStatusFn func(prometheus_model.LabelSet)
)

// NewAPI returns a new Alertmanager API v2
// NewAPI returns a new Alertmanager API v2.
func NewAPI(
alerts provider.Alerts,
gf groupsFn,
Expand Down Expand Up @@ -545,9 +545,9 @@ var silenceStateOrder = map[types.SilenceState]int{

// SortSilences sorts first according to the state "active, pending, expired"
// then by end time or start time depending on the state.
// active silences should show the next to expire first
// Active silences should show the next to expire first
// pending silences are ordered based on which one starts next
// expired are ordered based on which one expired most recently
// expired are ordered based on which one expired most recently.
func SortSilences(sils open_api_models.GettableSilences) {
sort.Slice(sils, func(i, j int) bool {
state1 := types.SilenceState(*sils[i].Status.State)
Expand Down
2 changes: 1 addition & 1 deletion cli/check_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"github.com/prometheus/alertmanager/template"
)

// TODO: This can just be a type that is []string, doesn't have to be a struct
// TODO: This can just be a type that is []string, doesn't have to be a struct.
type checkConfigCmd struct {
files []string
}
Expand Down
2 changes: 1 addition & 1 deletion cli/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (

const clusterHelp = `View cluster status and peers.`

// clusterCmd represents the cluster command
// configureClusterCmd represents the cluster command.
func configureClusterCmd(app *kingpin.Application) {
clusterCmd := app.Command("cluster", clusterHelp)
clusterCmd.Command("show", clusterHelp).Default().Action(execWithTimeout(showStatus)).PreAction(requireAlertManagerURL)
Expand Down
2 changes: 1 addition & 1 deletion cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The amount of output is controlled by the output selection flag:
- Json: Print entire config object as json
`

// configCmd represents the config command
// configureConfigCmd represents the config command.
func configureConfigCmd(app *kingpin.Application) {
configCmd := app.Command("config", configHelp)
configCmd.Command("show", configHelp).Default().Action(execWithTimeout(queryConfig)).PreAction(requireAlertManagerURL)
Expand Down
2 changes: 1 addition & 1 deletion cli/config/http_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"gopkg.in/yaml.v2"
)

// LoadHTTPConfigFile returns HTTPClientConfig for the given http_config file
// LoadHTTPConfigFile returns HTTPClientConfig for the given http_config file.
func LoadHTTPConfigFile(filename string) (*promconfig.HTTPClientConfig, error) {
b, err := os.ReadFile(filename)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions cli/format/format_extended.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (formatter *ExtendedFormatter) SetOutput(writer io.Writer) {
formatter.writer = writer
}

// FormatSilences formats the silences into a readable string
// FormatSilences formats the silences into a readable string.
func (formatter *ExtendedFormatter) FormatSilences(silences []models.GettableSilence) error {
w := tabwriter.NewWriter(formatter.writer, 0, 0, 2, ' ', 0)
sort.Sort(ByEndAt(silences))
Expand All @@ -58,7 +58,7 @@ func (formatter *ExtendedFormatter) FormatSilences(silences []models.GettableSil
return w.Flush()
}

// FormatAlerts formats the alerts into a readable string
// FormatAlerts formats the alerts into a readable string.
func (formatter *ExtendedFormatter) FormatAlerts(alerts []*models.GettableAlert) error {
w := tabwriter.NewWriter(formatter.writer, 0, 0, 2, ' ', 0)
sort.Sort(ByStartsAt(alerts))
Expand All @@ -78,7 +78,7 @@ func (formatter *ExtendedFormatter) FormatAlerts(alerts []*models.GettableAlert)
return w.Flush()
}

// FormatConfig formats the alertmanager status information into a readable string
// FormatConfig formats the alertmanager status information into a readable string.
func (formatter *ExtendedFormatter) FormatConfig(status *models.AlertmanagerStatus) error {
fmt.Fprintln(formatter.writer, status.Config.Original)
fmt.Fprintln(formatter.writer, "buildUser", status.VersionInfo.BuildUser)
Expand Down
6 changes: 3 additions & 3 deletions cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func initMatchersCompat(_ *kingpin.ParseContext) error {
if err != nil {
kingpin.Fatalf("error parsing the feature flag list: %v\n", err)
}
compat.InitFromFlags(logger, compat.RegisteredMetrics, featureConfig)
compat.InitFromFlags(logger, featureConfig)
return nil
}

Expand Down Expand Up @@ -89,7 +89,7 @@ const (
defaultAmApiv2path = "/api/v2"
)

// NewAlertmanagerClient initializes an alertmanager client with the given URL
// NewAlertmanagerClient initializes an alertmanager client with the given URL.
func NewAlertmanagerClient(amURL *url.URL) *client.AlertmanagerAPI {
address := defaultAmHost + ":" + defaultAmPort
schemes := []string{"http"}
Expand Down Expand Up @@ -145,7 +145,7 @@ func NewAlertmanagerClient(amURL *url.URL) *client.AlertmanagerAPI {
return c
}

// Execute is the main function for the amtool command
// Execute is the main function for the amtool command.
func Execute() {
app := kingpin.New("amtool", helpRoot).UsageWriter(os.Stdout)

Expand Down
2 changes: 1 addition & 1 deletion cli/silence.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/alecthomas/kingpin/v2"
)

// silenceCmd represents the silence command
// configureSilenceCmd represents the silence command.
func configureSilenceCmd(app *kingpin.Application) {
silenceCmd := app.Command("silence", "Add, expire or view silences. For more information and additional flags see query help").PreAction(requireAlertManagerURL)
configureSilenceAddCmd(silenceCmd)
Expand Down
5 changes: 3 additions & 2 deletions cli/template_render.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"time"

"github.com/alecthomas/kingpin/v2"
"github.com/prometheus/common/model"

"github.com/prometheus/alertmanager/template"
)
Expand All @@ -31,7 +32,7 @@ var defaultData = template.Data{
Status: "alertstatus",
Alerts: template.Alerts{
template.Alert{
Status: "alertstatus",
Status: string(model.AlertFiring),
Labels: template.KV{
"label1": "value1",
"label2": "value2",
Expand All @@ -51,7 +52,7 @@ var defaultData = template.Data{
Fingerprint: "fingerprint1",
},
template.Alert{
Status: "alertstatus",
Status: string(model.AlertResolved),
Labels: template.KV{
"foo": "bar",
"baz": "qux",
Expand Down
8 changes: 4 additions & 4 deletions cli/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"github.com/prometheus/alertmanager/pkg/labels"
)

// getRemoteAlertmanagerConfigStatus returns status responsecontaining configuration from remote Alertmanager
// getRemoteAlertmanagerConfigStatus returns status responsecontaining configuration from remote Alertmanager.
func getRemoteAlertmanagerConfigStatus(ctx context.Context, alertmanagerURL *url.URL) (*models.AlertmanagerStatus, error) {
amclient := NewAlertmanagerClient(alertmanagerURL)
params := general.NewGetStatusParams().WithContext(ctx)
Expand Down Expand Up @@ -69,7 +69,7 @@ func loadAlertmanagerConfig(ctx context.Context, alertmanagerURL *url.URL, confi
return config.Load(*configStatus.Config.Original)
}

// convertClientToCommonLabelSet converts client.LabelSet to model.Labelset
// convertClientToCommonLabelSet converts client.LabelSet to model.Labelset.
func convertClientToCommonLabelSet(cls models.LabelSet) model.LabelSet {
mls := make(model.LabelSet, len(cls))
for ln, lv := range cls {
Expand All @@ -78,7 +78,7 @@ func convertClientToCommonLabelSet(cls models.LabelSet) model.LabelSet {
return mls
}

// TypeMatchers only valid for when you are going to add a silence
// TypeMatchers only valid for when you are going to add a silence.
func TypeMatchers(matchers []labels.Matcher) models.Matchers {
typeMatchers := make(models.Matchers, len(matchers))
for i, matcher := range matchers {
Expand All @@ -87,7 +87,7 @@ func TypeMatchers(matchers []labels.Matcher) models.Matchers {
return typeMatchers
}

// TypeMatcher only valid for when you are going to add a silence
// TypeMatcher only valid for when you are going to add a silence.
func TypeMatcher(matcher labels.Matcher) *models.Matcher {
name := matcher.Name
value := matcher.Value
Expand Down
10 changes: 7 additions & 3 deletions cluster/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,13 @@ func NewChannel(
ConstLabels: prometheus.Labels{"key": key},
})
oversizeGossipDuration := prometheus.NewHistogram(prometheus.HistogramOpts{
Name: "alertmanager_oversize_gossip_message_duration_seconds",
Help: "Duration of oversized gossip message requests.",
ConstLabels: prometheus.Labels{"key": key},
Name: "alertmanager_oversize_gossip_message_duration_seconds",
Help: "Duration of oversized gossip message requests.",
ConstLabels: prometheus.Labels{"key": key},
Buckets: prometheus.DefBuckets,
NativeHistogramBucketFactor: 1.1,
NativeHistogramMaxBucketNumber: 100,
NativeHistogramMinResetDuration: 1 * time.Hour,
})

reg.MustRegister(oversizeGossipDuration, oversizeGossipMessageFailureTotal, oversizeGossipMessageDroppedTotal, oversizeGossipMessageSentTotal)
Expand Down
6 changes: 3 additions & 3 deletions cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type ClusterPeer interface {
Peers() []ClusterMember
}

// ClusterMember interface that represents node peers in a cluster
// ClusterMember interface that represents node peers in a cluster.
type ClusterMember interface {
// Name returns the name of the node
Name() string
Expand Down Expand Up @@ -639,10 +639,10 @@ type Member struct {
node *memberlist.Node
}

// Name implements cluster.ClusterMember
// Name implements cluster.ClusterMember.
func (m Member) Name() string { return m.node.Name }

// Address implements cluster.ClusterMember
// Address implements cluster.ClusterMember.
func (m Member) Address() string { return m.node.Address() }

// Peers returns the peers in the cluster.
Expand Down
2 changes: 2 additions & 0 deletions cluster/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ func testTLSConnection(t *testing.T) {
require.NoError(t, err)
go p2.Settle(context.Background(), 0*time.Second)
p2.WaitReady(context.Background())
require.Equal(t, "ready", p2.Status())

require.Equal(t, 2, p1.ClusterSize())
p2.Leave(0 * time.Second)
require.Equal(t, 1, p1.ClusterSize())
Expand Down
9 changes: 6 additions & 3 deletions cluster/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,12 @@ func newDelegate(l log.Logger, reg prometheus.Registerer, p *Peer, retransmit in
}, []string{"peer"},
)
nodePingDuration := prometheus.NewHistogramVec(prometheus.HistogramOpts{
Name: "alertmanager_cluster_pings_seconds",
Help: "Histogram of latencies for ping messages.",
Buckets: []float64{.005, .01, .025, .05, .1, .25, .5},
Name: "alertmanager_cluster_pings_seconds",
Help: "Histogram of latencies for ping messages.",
Buckets: []float64{.005, .01, .025, .05, .1, .25, .5},
NativeHistogramBucketFactor: 1.1,
NativeHistogramMaxBucketNumber: 100,
NativeHistogramMinResetDuration: 1 * time.Hour,
}, []string{"peer"},
)

Expand Down
11 changes: 7 additions & 4 deletions cmd/alertmanager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,12 @@ import (
var (
requestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "alertmanager_http_request_duration_seconds",
Help: "Histogram of latencies for HTTP requests.",
Buckets: []float64{.05, 0.1, .25, .5, .75, 1, 2, 5, 20, 60},
Name: "alertmanager_http_request_duration_seconds",
Help: "Histogram of latencies for HTTP requests.",
Buckets: []float64{.05, 0.1, .25, .5, .75, 1, 2, 5, 20, 60},
NativeHistogramBucketFactor: 1.1,
NativeHistogramMaxBucketNumber: 100,
NativeHistogramMinResetDuration: 1 * time.Hour,
},
[]string{"handler", "method"},
)
Expand Down Expand Up @@ -186,7 +189,7 @@ func run() int {
level.Error(logger).Log("msg", "error parsing the feature flag list", "err", err)
return 1
}
compat.InitFromFlags(logger, compat.RegisteredMetrics, ff)
compat.InitFromFlags(logger, ff)

err = os.MkdirAll(*dataDir, 0o777)
if err != nil {
Expand Down
Loading

0 comments on commit a7b1ed4

Please sign in to comment.