fix(outputs.stackdriver): Drop metrics on InvalidArgument gRPC error (#13931)

This commit is contained in:
Joshua Powers 2023-09-22 09:40:05 -06:00 committed by GitHub
parent b6d946da6e
commit 080f5a2ecb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 28 deletions

View File

@ -15,6 +15,7 @@ import (
"google.golang.org/api/option"
metricpb "google.golang.org/genproto/googleapis/api/metric"
monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/influxdata/telegraf"
@ -54,10 +55,6 @@ const (
// MaxInt is the max int64 value.
MaxInt = int(^uint(0) >> 1)
errStringPointsOutOfOrder = "one or more of the points specified had an older end time than the most recent point"
errStringPointsTooOld = "data points cannot be written more than 24h in the past"
errStringPointsTooFrequent = "one or more points were written more frequently than the maximum sampling period configured for the metric"
)
func (s *Stackdriver) Init() error {
@ -322,12 +319,13 @@ func (s *Stackdriver) sendBatch(batch []telegraf.Metric) error {
// Create the time series in Stackdriver.
err := s.client.CreateTimeSeries(ctx, timeSeriesRequest)
if err != nil {
if strings.Contains(err.Error(), errStringPointsOutOfOrder) ||
strings.Contains(err.Error(), errStringPointsTooOld) ||
strings.Contains(err.Error(), errStringPointsTooFrequent) {
s.Log.Debugf("Unable to write to Stackdriver: %s", err)
return nil
if errStatus, ok := status.FromError(err); ok {
if errStatus.Code().String() == "InvalidArgument" {
s.Log.Warnf("Unable to write to Stackdriver - dropping metrics: %s", err)
return nil
}
}
s.Log.Errorf("Unable to write to Stackdriver: %s", err)
return err
}

View File

@ -18,8 +18,10 @@ import (
"google.golang.org/api/option"
metricpb "google.golang.org/genproto/googleapis/api/metric"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/timestamppb"
@ -55,9 +57,18 @@ func (s *mockMetricServer) CreateTimeSeries(ctx context.Context, req *monitoring
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
}
s.reqs = append(s.reqs, req)
if s.err != nil {
return nil, s.err
var statusResp *status.Status
switch s.err.Error() {
case "InvalidArgument":
statusResp = status.New(codes.InvalidArgument, s.err.Error())
default:
statusResp = status.New(codes.Unknown, s.err.Error())
}
return nil, statusResp.Err()
}
return s.resps[0].(*emptypb.Empty), nil
}
@ -396,23 +407,16 @@ func TestWriteIgnoredErrors(t *testing.T) {
err error
expectedErr bool
}{
{
name: "points too old",
err: errors.New(errStringPointsTooOld),
},
{
name: "points out of order",
err: errors.New(errStringPointsOutOfOrder),
},
{
name: "points too frequent",
err: errors.New(errStringPointsTooFrequent),
},
{
name: "other errors reported",
err: errors.New("test"),
err: errors.New("Unknown"),
expectedErr: true,
},
{
name: "invalid argument",
err: errors.New("InvalidArgument"),
expectedErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -431,13 +435,11 @@ func TestWriteIgnoredErrors(t *testing.T) {
client: c,
}
err = s.Connect()
require.NoError(t, err)
err = s.Write(testutil.MockMetrics())
require.NoError(t, s.Connect())
if tt.expectedErr {
require.Error(t, err)
require.Error(t, s.Write(testutil.MockMetrics()))
} else {
require.NoError(t, err)
require.NoError(t, s.Write(testutil.MockMetrics()))
}
})
}