@@ -10,6 +10,7 @@ import (
1010 "net/http"
1111 "os"
1212 "path/filepath"
13+ "runtime"
1314 "slices"
1415 "strings"
1516 "sync"
@@ -1637,8 +1638,9 @@ func (u *userTSDB) releaseAppendLock() {
16371638}
16381639
16391640// QueryExemplars implements service.IngesterServer
1640- func (i * Ingester ) QueryExemplars (ctx context.Context , req * client.ExemplarQueryRequest ) (* client.ExemplarQueryResponse , error ) {
1641- if err := i .checkRunning (); err != nil {
1641+ func (i * Ingester ) QueryExemplars (ctx context.Context , req * client.ExemplarQueryRequest ) (resp * client.ExemplarQueryResponse , err error ) {
1642+ defer recoverIngester (i .logger , & err )
1643+ if err = i .checkRunning (); err != nil {
16421644 return nil , err
16431645 }
16441646
@@ -1659,7 +1661,7 @@ func (i *Ingester) QueryExemplars(ctx context.Context, req *client.ExemplarQuery
16591661 return & client.ExemplarQueryResponse {}, nil
16601662 }
16611663
1662- if err : = db .acquireReadLock (); err != nil {
1664+ if err = db .acquireReadLock (); err != nil {
16631665 return & client.ExemplarQueryResponse {}, nil
16641666 }
16651667 defer db .releaseReadLock ()
@@ -1701,14 +1703,16 @@ func (i *Ingester) QueryExemplars(ctx context.Context, req *client.ExemplarQuery
17011703}
17021704
17031705// LabelValues returns all label values that are associated with a given label name.
1704- func (i * Ingester ) LabelValues (ctx context.Context , req * client.LabelValuesRequest ) (* client.LabelValuesResponse , error ) {
1706+ func (i * Ingester ) LabelValues (ctx context.Context , req * client.LabelValuesRequest ) (resp * client.LabelValuesResponse , err error ) {
1707+ defer recoverIngester (i .logger , & err )
17051708 resp , cleanup , err := i .labelsValuesCommon (ctx , req )
17061709 defer cleanup ()
17071710 return resp , err
17081711}
17091712
17101713// LabelValuesStream returns all label values that are associated with a given label name.
1711- func (i * Ingester ) LabelValuesStream (req * client.LabelValuesRequest , stream client.Ingester_LabelValuesStreamServer ) error {
1714+ func (i * Ingester ) LabelValuesStream (req * client.LabelValuesRequest , stream client.Ingester_LabelValuesStreamServer ) (err error ) {
1715+ defer recoverIngester (i .logger , & err )
17121716 resp , cleanup , err := i .labelsValuesCommon (stream .Context (), req )
17131717 defer cleanup ()
17141718
@@ -1796,14 +1800,16 @@ func (i *Ingester) labelsValuesCommon(ctx context.Context, req *client.LabelValu
17961800}
17971801
17981802// LabelNames return all the label names.
1799- func (i * Ingester ) LabelNames (ctx context.Context , req * client.LabelNamesRequest ) (* client.LabelNamesResponse , error ) {
1803+ func (i * Ingester ) LabelNames (ctx context.Context , req * client.LabelNamesRequest ) (resp * client.LabelNamesResponse , err error ) {
1804+ defer recoverIngester (i .logger , & err )
18001805 resp , cleanup , err := i .labelNamesCommon (ctx , req )
18011806 defer cleanup ()
18021807 return resp , err
18031808}
18041809
18051810// LabelNamesStream return all the label names.
1806- func (i * Ingester ) LabelNamesStream (req * client.LabelNamesRequest , stream client.Ingester_LabelNamesStreamServer ) error {
1811+ func (i * Ingester ) LabelNamesStream (req * client.LabelNamesRequest , stream client.Ingester_LabelNamesStreamServer ) (err error ) {
1812+ defer recoverIngester (i .logger , & err )
18071813 resp , cleanup , err := i .labelNamesCommon (stream .Context (), req )
18081814 defer cleanup ()
18091815
@@ -1819,7 +1825,7 @@ func (i *Ingester) LabelNamesStream(req *client.LabelNamesRequest, stream client
18191825 resp := & client.LabelNamesStreamResponse {
18201826 LabelNames : resp .LabelNames [i :j ],
18211827 }
1822- err : = client .SendLabelNamesStream (stream , resp )
1828+ err = client .SendLabelNamesStream (stream , resp )
18231829 if err != nil {
18241830 return err
18251831 }
@@ -1891,8 +1897,9 @@ func (i *Ingester) labelNamesCommon(ctx context.Context, req *client.LabelNamesR
18911897}
18921898
18931899// MetricsForLabelMatchers returns all the metrics which match a set of matchers.
1894- func (i * Ingester ) MetricsForLabelMatchers (ctx context.Context , req * client.MetricsForLabelMatchersRequest ) (* client.MetricsForLabelMatchersResponse , error ) {
1895- result := & client.MetricsForLabelMatchersResponse {}
1900+ func (i * Ingester ) MetricsForLabelMatchers (ctx context.Context , req * client.MetricsForLabelMatchersRequest ) (result * client.MetricsForLabelMatchersResponse , err error ) {
1901+ defer recoverIngester (i .logger , & err )
1902+ result = & client.MetricsForLabelMatchersResponse {}
18961903 cleanup , err := i .metricsForLabelMatchersCommon (ctx , req , func (l labels.Labels ) error {
18971904 result .Metric = append (result .Metric , & cortexpb.Metric {
18981905 Labels : cortexpb .FromLabelsToLabelAdapters (l ),
@@ -1903,7 +1910,8 @@ func (i *Ingester) MetricsForLabelMatchers(ctx context.Context, req *client.Metr
19031910 return result , err
19041911}
19051912
1906- func (i * Ingester ) MetricsForLabelMatchersStream (req * client.MetricsForLabelMatchersRequest , stream client.Ingester_MetricsForLabelMatchersStreamServer ) error {
1913+ func (i * Ingester ) MetricsForLabelMatchersStream (req * client.MetricsForLabelMatchersRequest , stream client.Ingester_MetricsForLabelMatchersStreamServer ) (err error ) {
1914+ defer recoverIngester (i .logger , & err )
19071915 result := & client.MetricsForLabelMatchersStreamResponse {}
19081916
19091917 cleanup , err := i .metricsForLabelMatchersCommon (stream .Context (), req , func (l labels.Labels ) error {
@@ -1927,7 +1935,7 @@ func (i *Ingester) MetricsForLabelMatchersStream(req *client.MetricsForLabelMatc
19271935
19281936 // Send last batch
19291937 if len (result .Metric ) > 0 {
1930- err : = client .SendMetricsForLabelMatchersStream (stream , result )
1938+ err = client .SendMetricsForLabelMatchersStream (stream , result )
19311939 if err != nil {
19321940 return err
19331941 }
@@ -2160,8 +2168,10 @@ const queryStreamBatchMessageSize = 1 * 1024 * 1024
21602168
21612169// QueryStream implements service.IngesterServer
21622170// Streams metrics from a TSDB. This implements the client.IngesterServer interface
2163- func (i * Ingester ) QueryStream (req * client.QueryRequest , stream client.Ingester_QueryStreamServer ) error {
2164- if err := i .checkRunning (); err != nil {
2171+ func (i * Ingester ) QueryStream (req * client.QueryRequest , stream client.Ingester_QueryStreamServer ) (err error ) {
2172+ defer recoverIngester (i .logger , & err )
2173+
2174+ if err = i .checkRunning (); err != nil {
21652175 return err
21662176 }
21672177
@@ -3443,3 +3453,20 @@ func (c *labelSetReasonCounters) increment(matchedLabelSetLimits []validation.Li
34433453 }
34443454 }
34453455}
3456+
3457+ func recoverIngester (logger log.Logger , errp * error ) {
3458+ e := recover ()
3459+ if e == nil {
3460+ return
3461+ }
3462+
3463+ switch err := e .(type ) {
3464+ case runtime.Error :
3465+ // Print the stack trace but do not inhibit the running application.
3466+ buf := make ([]byte , 64 << 10 )
3467+ buf = buf [:runtime .Stack (buf , false )]
3468+
3469+ level .Error (logger ).Log ("msg" , "runtime panic in ingester" , "err" , err , "stacktrace" , string (buf ))
3470+ * errp = errors .Wrap (err , "unexpected error" )
3471+ }
3472+ }
0 commit comments