mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 22:02:48 +08:00
Loki: Improve backend instrumentation of CallResource
calls (#73899)
* instrument call resource * capitalize log messages
This commit is contained in:
@ -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
|
||||
|
@ -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"},
|
||||
}
|
||||
|
Reference in New Issue
Block a user