github.com/thanos-io/thanos@v0.32.5/pkg/store/recover.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package store
     5  
     6  import (
     7  	"fmt"
     8  	"runtime"
     9  
    10  	"github.com/go-kit/log"
    11  	"github.com/go-kit/log/level"
    12  	"github.com/pkg/errors"
    13  
    14  	"github.com/thanos-io/thanos/pkg/store/storepb"
    15  )
    16  
    17  type recoverableStoreServer struct {
    18  	logger log.Logger
    19  	storepb.StoreServer
    20  }
    21  
    22  func NewRecoverableStoreServer(logger log.Logger, storeServer storepb.StoreServer) *recoverableStoreServer {
    23  	return &recoverableStoreServer{logger: logger, StoreServer: storeServer}
    24  }
    25  
    26  func (r *recoverableStoreServer) Series(request *storepb.SeriesRequest, srv storepb.Store_SeriesServer) error {
    27  	defer r.recover(srv)
    28  	return r.StoreServer.Series(request, srv)
    29  }
    30  
    31  func (r *recoverableStoreServer) recover(srv storepb.Store_SeriesServer) {
    32  	e := recover()
    33  	if e == nil {
    34  		return
    35  	}
    36  
    37  	switch err := e.(type) {
    38  	case runtime.Error:
    39  		// Print the stack trace but do not inhibit the running application.
    40  		buf := make([]byte, 64<<10)
    41  		buf = buf[:runtime.Stack(buf, false)]
    42  
    43  		level.Error(r.logger).Log("msg", "runtime panic in TSDB Series server", "err", err.Error(), "stacktrace", string(buf))
    44  		if err := srv.Send(storepb.NewWarnSeriesResponse(err)); err != nil {
    45  			level.Error(r.logger).Log("err", err)
    46  		}
    47  	default:
    48  		if err := srv.Send(storepb.NewWarnSeriesResponse(errors.New(fmt.Sprintf("unknown error while processing Series: %v", e)))); err != nil {
    49  			level.Error(r.logger).Log("err", err)
    50  		}
    51  	}
    52  }