@@ -15,6 +15,7 @@ import (
1515 "net/http"
1616 "net/textproto"
1717 "net/url"
18+ "os"
1819 "strconv"
1920 "time"
2021
@@ -72,15 +73,21 @@ type RemoteEvaluator struct {
7273 overrides RulesLimits
7374 logger log.Logger
7475
76+ // we don't want/need to log all the additional context, such as
77+ // caller=spanlogger.go:116 component=ruler evaluation_mode=remote method=ruler.remoteEvaluation.Query
78+ // in insights logs, so create a new logger
79+ insightsLogger log.Logger
80+
7581 metrics * metrics
7682}
7783
7884func NewRemoteEvaluator (client httpgrpc.HTTPClient , overrides RulesLimits , logger log.Logger , registerer prometheus.Registerer ) (* RemoteEvaluator , error ) {
7985 return & RemoteEvaluator {
80- client : client ,
81- overrides : overrides ,
82- logger : logger ,
83- metrics : newMetrics (registerer ),
86+ client : client ,
87+ overrides : overrides ,
88+ logger : logger ,
89+ insightsLogger : log .NewLogfmtLogger (os .Stderr ),
90+ metrics : newMetrics (registerer ),
8491 }, nil
8592}
8693
@@ -220,6 +227,11 @@ func (r *RemoteEvaluator) query(ctx context.Context, orgID, query string, ts tim
220227 body := []byte (args .Encode ())
221228 hash := util .HashedQuery (query )
222229
230+ // Retrieve rule details from context
231+ ruleName , ruleType := GetRuleDetailsFromContext (ctx )
232+
233+ // Construct the X-Query-Tags header value
234+ queryTags := fmt .Sprintf ("source=ruler,rule_name=%s,rule_type=%s" , ruleName , ruleType )
223235 req := httpgrpc.HTTPRequest {
224236 Method : http .MethodPost ,
225237 Url : queryEndpointPath ,
@@ -228,7 +240,7 @@ func (r *RemoteEvaluator) query(ctx context.Context, orgID, query string, ts tim
228240 {Key : textproto .CanonicalMIMEHeaderKey ("User-Agent" ), Values : []string {userAgent }},
229241 {Key : textproto .CanonicalMIMEHeaderKey ("Content-Type" ), Values : []string {mimeTypeFormPost }},
230242 {Key : textproto .CanonicalMIMEHeaderKey ("Content-Length" ), Values : []string {strconv .Itoa (len (body ))}},
231- {Key : textproto .CanonicalMIMEHeaderKey (string (httpreq .QueryTagsHTTPHeader )), Values : []string {"source=ruler" }},
243+ {Key : textproto .CanonicalMIMEHeaderKey (string (httpreq .QueryTagsHTTPHeader )), Values : []string {queryTags }},
232244 {Key : textproto .CanonicalMIMEHeaderKey (user .OrgIDHeaderName ), Values : []string {orgID }},
233245 },
234246 }
@@ -242,12 +254,12 @@ func (r *RemoteEvaluator) query(ctx context.Context, orgID, query string, ts tim
242254 instrument .ObserveWithExemplar (ctx , r .metrics .responseSizeBytes .WithLabelValues (orgID ), float64 (len (resp .Body )))
243255 }
244256
245- log : = log .With (logger , "query_hash" , hash , "query" , query , "instant" , ts , "response_time" , time .Since (start ).String ())
257+ logger = log .With (logger , "query_hash" , hash , "query" , query , "instant" , ts , "response_time" , time .Since (start ).String ())
246258
247259 if err != nil {
248260 r .metrics .failedEvals .WithLabelValues ("error" , orgID ).Inc ()
249261
250- level .Warn (log ).Log ("msg" , "failed to evaluate rule" , "err" , err )
262+ level .Warn (logger ).Log ("msg" , "failed to evaluate rule" , "err" , err )
251263 return nil , fmt .Errorf ("rule evaluation failed: %w" , err )
252264 }
253265
@@ -261,22 +273,27 @@ func (r *RemoteEvaluator) query(ctx context.Context, orgID, query string, ts tim
261273 r .metrics .failedEvals .WithLabelValues ("upstream_error" , orgID ).Inc ()
262274
263275 respBod , _ := io .ReadAll (limitedBody )
264- level .Warn (log ).Log ("msg" , "rule evaluation failed with non-2xx response" , "response_code" , resp .Code , "response_body" , respBod )
276+ level .Warn (logger ).Log ("msg" , "rule evaluation failed with non-2xx response" , "response_code" , resp .Code , "response_body" , respBod )
265277 return nil , fmt .Errorf ("unsuccessful/unexpected response - status code %d" , resp .Code )
266278 }
267279
268280 maxSize := r .overrides .RulerRemoteEvaluationMaxResponseSize (orgID )
269281 if maxSize > 0 && int64 (len (fullBody )) >= maxSize {
270282 r .metrics .failedEvals .WithLabelValues ("max_size" , orgID ).Inc ()
271283
272- level .Error (log ).Log ("msg" , "rule evaluation exceeded max size" , "max_size" , maxSize , "response_size" , len (fullBody ))
284+ level .Error (logger ).Log ("msg" , "rule evaluation exceeded max size" , "max_size" , maxSize , "response_size" , len (fullBody ))
273285 return nil , fmt .Errorf ("%d bytes exceeds response size limit of %d (defined by ruler_remote_evaluation_max_response_size)" , len (resp .Body ), maxSize )
274286 }
275287
276- level .Debug (log ).Log ("msg" , "rule evaluation succeeded" )
288+ level .Debug (logger ).Log ("msg" , "rule evaluation succeeded" )
277289 r .metrics .successfulEvals .WithLabelValues (orgID ).Inc ()
278290
279- return r .decodeResponse (ctx , resp , orgID )
291+ dr , err := r .decodeResponse (ctx , resp , orgID )
292+ if err != nil {
293+ return nil , err
294+ }
295+ level .Info (r .insightsLogger ).Log ("msg" , "request timings" , "insight" , "true" , "source" , "loki_ruler" , "rule_name" , ruleName , "rule_type" , ruleType , "total" , dr .Statistics .Summary .ExecTime , "total_bytes" , dr .Statistics .Summary .TotalBytesProcessed , "query_hash" , util .HashedQuery (query ))
296+ return dr , err
280297}
281298
282299func (r * RemoteEvaluator ) decodeResponse (ctx context.Context , resp * httpgrpc.HTTPResponse , orgID string ) (* logqlmodel.Result , error ) {
0 commit comments