Skip to content

Commit 911f596

Browse files
elasticblrmergify[bot]
authored andcommitted
[AutoOps] Stop when it cannot recover (#48292)
Added the panic logic in the Autoops agent when its credentials are not valid to fetch the metrics from the Elasticsearch cluster. (cherry picked from commit 568454d)
1 parent 4269e9a commit 911f596

3 files changed

Lines changed: 93 additions & 13 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# REQUIRED
2+
# Kind can be one of:
3+
# - breaking-change: a change to previously-documented behavior
4+
# - deprecation: functionality that is being removed in a later release
5+
# - bug-fix: fixes a problem in a previous version
6+
# - enhancement: extends functionality but does not break or fix existing behavior
7+
# - feature: new functionality
8+
# - known-issue: problems that we are aware of in a given version
9+
# - security: impacts on the security of a product or a user’s deployment.
10+
# - upgrade: important information for someone upgrading from a prior version
11+
# - other: does not fit into any of the other categories
12+
kind: bug-fix
13+
14+
# REQUIRED for all kinds
15+
# Change summary; a 80ish characters long description of the change.
16+
summary: autoops agent to shutdown when it can't recover from the http errors
17+
18+
# REQUIRED for breaking-change, deprecation, known-issue
19+
# Long description; in case the summary is not enough to describe the change
20+
# this field accommodate a description without length limits.
21+
# description:
22+
23+
# REQUIRED for breaking-change, deprecation, known-issue
24+
# impact:
25+
26+
# REQUIRED for breaking-change, deprecation, known-issue
27+
# action:
28+
29+
# REQUIRED for all kinds
30+
# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
31+
component: metricbeat
32+
33+
# AUTOMATED
34+
# OPTIONAL to manually add other PR URLs
35+
# PR URL: A link the PR that added the changeset.
36+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
37+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
38+
# Please provide it if you are adding a fragment for a different PR.
39+
# pr: https://github.com/owner/repo/1234
40+
41+
# AUTOMATED
42+
# OPTIONAL to manually add other issue URLs
43+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
44+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
45+
# issue: https://github.com/owner/repo/1234

x-pack/metricbeat/module/autoops_es/metricset/cluster_info.go

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
package metricset
66

77
import (
8-
"os"
9-
"time"
8+
"errors"
9+
"fmt"
10+
"slices"
1011

1112
"github.com/elastic/beats/v7/metricbeat/module/elasticsearch"
1213
"github.com/elastic/beats/v7/x-pack/metricbeat/module/autoops_es/utils"
13-
"github.com/elastic/elastic-agent-libs/logp"
1414
libversion "github.com/elastic/elastic-agent-libs/version"
1515
)
1616

@@ -19,10 +19,20 @@ const MinimumEsVersion = "7.17.0"
1919
var minVersion = libversion.MustNew(MinimumEsVersion)
2020
var isVersionChecked = false
2121

22+
const (
23+
CLUSTER_INFO_INITIAL_ERROR = 1
24+
CLUSTER_INFO_RUNTIME_ERROR = 2
25+
)
26+
27+
// List of HTTP status codes that indicate the agent cannot recover
28+
var terminalHttpErrorStatusCodes = []int{401, 403, 404}
29+
2230
func GetInfo(m *elasticsearch.MetricSet) (*utils.ClusterInfo, error) {
2331
info, err := utils.FetchAPIData[utils.ClusterInfo](m, "/")
2432

2533
if err != nil {
34+
var httpResponse *utils.HTTPResponse
35+
handleClusterInfoError(m, err, httpResponse)
2636
return nil, err
2737
} else if info.ClusterID == "" || info.ClusterID == "_na_" {
2838
return nil, &utils.ClusterInfoError{Message: "cluster ID is unset, which means the cluster is not ready"}
@@ -32,7 +42,7 @@ func GetInfo(m *elasticsearch.MetricSet) (*utils.ClusterInfo, error) {
3242
if !isVersionChecked {
3343
// for some reason log.Fatal() isn't working properly so we need to handle the error in a goroutine
3444
errChan := make(chan error)
35-
go handleErrors(m.Logger(), errChan)
45+
go handleFatalErrors(m.Logger(), errChan, CLUSTER_INFO_INITIAL_ERROR)
3646

3747
if err := checkEsVersion(info.Version.Number, errChan); err != nil {
3848
return nil, err
@@ -42,6 +52,19 @@ func GetInfo(m *elasticsearch.MetricSet) (*utils.ClusterInfo, error) {
4252
return info, nil
4353
}
4454

55+
func handleClusterInfoError(m *elasticsearch.MetricSet, err error, httpResponse *utils.HTTPResponse) {
56+
if errors.As(err, &httpResponse) {
57+
if slices.Contains(terminalHttpErrorStatusCodes, httpResponse.StatusCode) {
58+
// in these error cases Autoops agent can't recover itself, hence stop the agent
59+
errChan := make(chan error)
60+
go handleFatalErrors(m.Logger(), errChan, CLUSTER_INFO_RUNTIME_ERROR)
61+
customErr := fmt.Errorf("autoops agent can't fetch the metrics due to http error! Code: %d, Status: %s",
62+
httpResponse.StatusCode, httpResponse.Status)
63+
errChan <- customErr
64+
}
65+
}
66+
}
67+
4568
func checkEsVersion(esVersion *libversion.V, errChan chan error) error {
4669
if esVersion.LessThan(minVersion) {
4770
isVersionChecked = true
@@ -55,12 +78,3 @@ func checkEsVersion(esVersion *libversion.V, errChan chan error) error {
5578

5679
return nil
5780
}
58-
59-
func handleErrors(logger *logp.Logger, errChan chan error) {
60-
for err := range errChan {
61-
logger.Error(err)
62-
// sleep is needed to make sure the error is logged and error event is sent before exiting
63-
time.Sleep(time.Second * 5)
64-
os.Exit(1)
65-
}
66-
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License;
3+
// you may not use this file except in compliance with the Elastic License.
4+
5+
package metricset
6+
7+
import (
8+
"os"
9+
"time"
10+
11+
"github.com/elastic/elastic-agent-libs/logp"
12+
)
13+
14+
func handleFatalErrors(logger *logp.Logger, errChan chan error, errorCode int) {
15+
for err := range errChan {
16+
logger.Error(err)
17+
// sleep is needed to make sure the error is logged and error event is sent before exiting
18+
time.Sleep(time.Second * 5)
19+
os.Exit(errorCode)
20+
}
21+
}

0 commit comments

Comments
 (0)