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 }