Loki: Improve backend instrumentation of CallResource calls (#73899)

* instrument call resource

* capitalize log messages
This commit is contained in:
Sven Grossmann
2023-09-01 15:26:25 +02:00
committed by GitHub
parent b0897d7b36
commit 056c83c788
2 changed files with 17 additions and 6 deletions

View File

@ -227,8 +227,11 @@ func makeRawRequest(ctx context.Context, lokiDsUrl string, resourcePath string)
}
func (api *LokiAPI) RawQuery(ctx context.Context, resourcePath string) (RawLokiResponse, error) {
api.log.Debug("Sending raw query to loki", "resourcePath", resourcePath)
start := time.Now()
req, err := makeRawRequest(ctx, api.url, resourcePath)
if err != nil {
api.log.Error("Failed to prepare request to loki", "err", err, "resourcePath", resourcePath)
return RawLokiResponse{}, err
}
@ -243,6 +246,8 @@ func (api *LokiAPI) RawQuery(ctx context.Context, resourcePath string) (RawLokiR
}
}()
api.log.Debug("Response received from loki", "status", resp.StatusCode, "length", resp.Header.Get("Content-Length"), "took", time.Since(start), "encoding", resp.Header.Get("Content-Encoding"))
// server errors are handled by the plugin-proxy to hide the error message
if resp.StatusCode/100 == 5 {
return RawLokiResponse{}, readLokiError(resp.Body)
@ -256,6 +261,7 @@ func (api *LokiAPI) RawQuery(ctx context.Context, resourcePath string) (RawLokiR
// client errors are passed as a json struct to the client
if resp.StatusCode/100 != 2 {
lokiResponseErr := lokiResponseError{Message: makeLokiError(body).Error()}
api.log.Warn("Non 200 HTTP status received from loki", "err", lokiResponseErr.Message, "status", resp.StatusCode, "resourcePath", resourcePath)
traceID := tracing.TraceIDFromContext(ctx, false)
if traceID != "" {
lokiResponseErr.TraceID = traceID

View File

@ -99,24 +99,27 @@ func newInstanceSettings(httpClientProvider httpclient.Provider) datasource.Inst
func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
dsInfo, err := s.getDSInfo(ctx, req.PluginContext)
logger := logger.FromContext(ctx).New("api", "CallResource")
if err != nil {
logger.Error("failed to get data source info", "err", err)
return err
}
return callResource(ctx, req, sender, dsInfo, logger.FromContext(ctx), s.tracer)
return callResource(ctx, req, sender, dsInfo, logger, s.tracer)
}
func callResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender, dsInfo *datasourceInfo, plog log.Logger, tracer tracing.Tracer) error {
url := req.URL
// a very basic is-this-url-valid check
if req.Method != "GET" {
return fmt.Errorf("invalid resource method: %s", req.Method)
plog.Error("Invalid HTTP method", "method", req.Method)
return fmt.Errorf("invalid HTTP method: %s", req.Method)
}
if (!strings.HasPrefix(url, "labels?")) &&
(!strings.HasPrefix(url, "label/")) && // the `/label/$label_name/values` form
(!strings.HasPrefix(url, "series?")) &&
(!strings.HasPrefix(url, "index/stats?")) {
return fmt.Errorf("invalid resource URL: %s", url)
plog.Error("Invalid URL", "url", url)
return fmt.Errorf("invalid URL: %s", url)
}
lokiURL := fmt.Sprintf("/loki/api/v1/%s", url)
@ -125,12 +128,14 @@ func callResource(ctx context.Context, req *backend.CallResourceRequest, sender
defer span.End()
api := newLokiAPI(dsInfo.HTTPClient, dsInfo.URL, plog, tracer)
rawLokiResponse, err := api.RawQuery(ctx, lokiURL)
rawLokiResponse, err := api.RawQuery(ctx, lokiURL)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
plog.Error("Failed resource call from loki", "err", err, "url", lokiURL)
return err
}
respHeaders := map[string][]string{
"content-type": {"application/json"},
}