diff --git a/collector/gen/exporter/otlpexporter/internal/arrow/stream.go b/collector/gen/exporter/otlpexporter/internal/arrow/stream.go index 839fde30..e00dc795 100644 --- a/collector/gen/exporter/otlpexporter/internal/arrow/stream.go +++ b/collector/gen/exporter/otlpexporter/internal/arrow/stream.go @@ -196,10 +196,23 @@ func (s *Stream) run(bgctx context.Context, streamClient StreamClientFunc, grpcO zap.String("message", status.Message()), ) - case codes.Unavailable: + case codes.Unavailable, codes.Internal: // gRPC returns this when max connection age is reached. // The message string will contain NO_ERROR if it's a // graceful shutdown. + // + // Having seen: + // + // arrow stream unknown {"kind": "exporter", + // "data_type": "traces", "name": "otlp/traces", + // "code": 13, "message": "stream terminated by + // RST_STREAM with error code: NO_ERROR"} + // + // from the default case below print `"code": 13`, this + // branch is now used for both Unavailable (witnessed + // in local testing) and Internal (witnessed in + // production); in both cases "NO_ERROR" is the key + // signifier. if strings.Contains(status.Message(), "NO_ERROR") { s.telemetry.Logger.Debug("arrow stream shutdown") } else { diff --git a/collector/gen/receiver/otlpreceiver/internal/arrow/arrow.go b/collector/gen/receiver/otlpreceiver/internal/arrow/arrow.go index 005718b3..5a76092a 100644 --- a/collector/gen/receiver/otlpreceiver/internal/arrow/arrow.go +++ b/collector/gen/receiver/otlpreceiver/internal/arrow/arrow.go @@ -234,6 +234,10 @@ func (r *Receiver) logStreamError(err error) { switch status.Code() { case codes.Canceled: r.telemetry.Logger.Debug("arrow stream canceled") + case codes.Unavailable: + r.telemetry.Logger.Info("arrow stream unavailable", + zap.String("message", status.Message()), + ) default: r.telemetry.Logger.Error("arrow stream error", zap.Uint32("code", uint32(status.Code())),