Testdata: Use contextual logging (#76833)
This commit is contained in:
@@ -26,20 +26,22 @@ func (s *Service) registerRoutes() *http.ServeMux {
|
||||
}
|
||||
|
||||
func (s *Service) testGetHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
s.logger.Debug("Received resource call", "url", req.URL.String(), "method", req.Method)
|
||||
ctxLogger := s.logger.FromContext(req.Context())
|
||||
ctxLogger.Debug("Received resource call", "url", req.URL.String(), "method", req.Method)
|
||||
|
||||
if req.Method != http.MethodGet {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := rw.Write([]byte("Hello world from test datasource!")); err != nil {
|
||||
s.logger.Error("Failed to write response", "error", err)
|
||||
ctxLogger.Error("Failed to write response", "error", err)
|
||||
return
|
||||
}
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (s *Service) getScenariosHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
ctxLogger := s.logger.FromContext(req.Context())
|
||||
result := make([]any, 0)
|
||||
|
||||
scenarioIds := make([]string, 0)
|
||||
@@ -60,18 +62,19 @@ func (s *Service) getScenariosHandler(rw http.ResponseWriter, req *http.Request)
|
||||
|
||||
bytes, err := json.Marshal(&result)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to marshal response body to JSON", "error", err)
|
||||
ctxLogger.Error("Failed to marshal response body to JSON", "error", err)
|
||||
}
|
||||
|
||||
rw.Header().Set("Content-Type", "application/json")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
if _, err := rw.Write(bytes); err != nil {
|
||||
s.logger.Error("Failed to write response", "error", err)
|
||||
ctxLogger.Error("Failed to write response", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) testStreamHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
s.logger.Debug("Received resource call", "url", req.URL.String(), "method", req.Method)
|
||||
ctxLogger := s.logger.FromContext(req.Context())
|
||||
ctxLogger.Debug("Received resource call", "url", req.URL.String(), "method", req.Method)
|
||||
|
||||
if req.Method != http.MethodGet {
|
||||
return
|
||||
@@ -96,7 +99,7 @@ func (s *Service) testStreamHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
|
||||
for i := 1; i <= count; i++ {
|
||||
if _, err := io.WriteString(rw, fmt.Sprintf("Message #%d", i)); err != nil {
|
||||
s.logger.Error("Failed to write response", "error", err)
|
||||
ctxLogger.Error("Failed to write response", "error", err)
|
||||
return
|
||||
}
|
||||
rw.(http.Flusher).Flush()
|
||||
@@ -106,25 +109,26 @@ func (s *Service) testStreamHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
|
||||
func createJSONHandler(logger log.Logger) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
logger.Debug("Received resource call", "url", req.URL.String(), "method", req.Method)
|
||||
ctxLogger := logger.FromContext(req.Context())
|
||||
ctxLogger.Debug("Received resource call", "url", req.URL.String(), "method", req.Method)
|
||||
|
||||
var reqData map[string]any
|
||||
if req.Body != nil {
|
||||
defer func() {
|
||||
if err := req.Body.Close(); err != nil {
|
||||
logger.Warn("Failed to close response body", "err", err)
|
||||
ctxLogger.Warn("Failed to close response body", "err", err)
|
||||
}
|
||||
}()
|
||||
b, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
logger.Error("Failed to read request body to bytes", "error", err)
|
||||
ctxLogger.Error("Failed to read request body to bytes", "error", err)
|
||||
} else {
|
||||
err := json.Unmarshal(b, &reqData)
|
||||
if err != nil {
|
||||
logger.Error("Failed to unmarshal request body to JSON", "error", err)
|
||||
ctxLogger.Error("Failed to unmarshal request body to JSON", "error", err)
|
||||
}
|
||||
|
||||
logger.Debug("Received resource call body", "body", reqData)
|
||||
ctxLogger.Debug("Received resource call body", "body", reqData)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,13 +143,13 @@ func createJSONHandler(logger log.Logger) http.Handler {
|
||||
}
|
||||
bytes, err := json.Marshal(&data)
|
||||
if err != nil {
|
||||
logger.Error("Failed to marshal response body to JSON", "error", err)
|
||||
ctxLogger.Error("Failed to marshal response body to JSON", "error", err)
|
||||
}
|
||||
|
||||
rw.Header().Set("Content-Type", "application/json")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
if _, err := rw.Write(bytes); err != nil {
|
||||
logger.Error("Failed to write response", "error", err)
|
||||
ctxLogger.Error("Failed to write response", "error", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
@@ -231,10 +232,10 @@ Timestamps will line up evenly on timeStepSeconds (For example, 60 seconds means
|
||||
|
||||
func (s *Service) registerScenario(scenario *Scenario) {
|
||||
s.scenarios[scenario.ID] = scenario
|
||||
s.queryMux.HandleFunc(scenario.ID, traceScenarioHandler(scenario.ID, scenario.handler))
|
||||
s.queryMux.HandleFunc(scenario.ID, instrumentScenarioHandler(s.logger, scenario.ID, scenario.handler))
|
||||
}
|
||||
|
||||
func traceScenarioHandler(scenario string, fn backend.QueryDataHandlerFunc) backend.QueryDataHandlerFunc {
|
||||
func instrumentScenarioHandler(logger log.Logger, scenario string, fn backend.QueryDataHandlerFunc) backend.QueryDataHandlerFunc {
|
||||
return backend.QueryDataHandlerFunc(func(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
ctx, span := tracing.DefaultTracer().Start(ctx, "testdatasource.queryData",
|
||||
trace.WithAttributes(
|
||||
@@ -242,6 +243,9 @@ func traceScenarioHandler(scenario string, fn backend.QueryDataHandlerFunc) back
|
||||
))
|
||||
defer span.End()
|
||||
|
||||
ctxLogger := logger.FromContext(ctx)
|
||||
ctxLogger.Debug("queryData", "scenario", scenario)
|
||||
|
||||
return fn(ctx, req)
|
||||
})
|
||||
}
|
||||
@@ -298,12 +302,13 @@ func GetJSONModel(j json.RawMessage) (JSONModel, error) {
|
||||
|
||||
// handleFallbackScenario handles the scenario where queryType is not set and fallbacks to scenarioId.
|
||||
func (s *Service) handleFallbackScenario(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
ctxLogger := s.logger.FromContext(ctx)
|
||||
scenarioQueries := map[string][]backend.DataQuery{}
|
||||
|
||||
for _, q := range req.Queries {
|
||||
model, err := GetJSONModel(q.JSON)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to unmarshal query model to JSON", "error", err)
|
||||
ctxLogger.Error("Failed to unmarshal query model to JSON", "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -315,7 +320,7 @@ func (s *Service) handleFallbackScenario(ctx context.Context, req *backend.Query
|
||||
|
||||
scenarioQueries[scenarioID] = append(scenarioQueries[scenarioID], q)
|
||||
} else {
|
||||
s.logger.Error("Scenario not found", "scenarioId", scenarioID)
|
||||
ctxLogger.Error("Scenario not found", "scenarioId", scenarioID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,9 +332,9 @@ func (s *Service) handleFallbackScenario(ctx context.Context, req *backend.Query
|
||||
Headers: req.Headers,
|
||||
Queries: queries,
|
||||
}
|
||||
handler := traceScenarioHandler(scenarioID, scenario.handler)
|
||||
handler := instrumentScenarioHandler(s.logger, scenarioID, scenario.handler)
|
||||
if sResp, err := handler(ctx, sReq); err != nil {
|
||||
s.logger.Error("Failed to handle scenario", "scenarioId", scenarioID, "error", err)
|
||||
ctxLogger.Error("Failed to handle scenario", "scenarioId", scenarioID, "error", err)
|
||||
} else {
|
||||
for refID, dr := range sResp.Responses {
|
||||
resp.Responses[refID] = dr
|
||||
|
||||
@@ -15,7 +15,8 @@ import (
|
||||
var random20HzStreamRegex = regexp.MustCompile(`random-20Hz-stream(-\d+)?`)
|
||||
|
||||
func (s *Service) SubscribeStream(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) {
|
||||
s.logger.Debug("Allowing access to stream", "path", req.Path, "user", req.PluginContext.User)
|
||||
ctxLogger := s.logger.FromContext(ctx)
|
||||
ctxLogger.Debug("Allowing access to stream", "path", req.Path, "user", req.PluginContext.User)
|
||||
|
||||
if strings.HasPrefix(req.Path, "sim/") {
|
||||
return s.sims.SubscribeStream(ctx, req)
|
||||
@@ -40,7 +41,8 @@ func (s *Service) SubscribeStream(ctx context.Context, req *backend.SubscribeStr
|
||||
}
|
||||
|
||||
func (s *Service) PublishStream(ctx context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) {
|
||||
s.logger.Debug("Attempt to publish into stream", "path", req.Path, "user", req.PluginContext.User)
|
||||
ctxLogger := s.logger.FromContext(ctx)
|
||||
ctxLogger.Debug("Attempt to publish into stream", "path", req.Path, "user", req.PluginContext.User)
|
||||
|
||||
if strings.HasPrefix(req.Path, "sim/") {
|
||||
return s.sims.PublishStream(ctx, req)
|
||||
@@ -52,7 +54,8 @@ func (s *Service) PublishStream(ctx context.Context, req *backend.PublishStreamR
|
||||
}
|
||||
|
||||
func (s *Service) RunStream(ctx context.Context, request *backend.RunStreamRequest, sender *backend.StreamSender) error {
|
||||
s.logger.Debug("New stream call", "path", request.Path)
|
||||
ctxLogger := s.logger.FromContext(ctx)
|
||||
ctxLogger.Debug("New stream call", "path", request.Path)
|
||||
|
||||
if strings.HasPrefix(request.Path, "sim/") {
|
||||
return s.sims.RunStream(ctx, request, sender)
|
||||
@@ -92,6 +95,7 @@ type testStreamConfig struct {
|
||||
}
|
||||
|
||||
func (s *Service) runTestStream(ctx context.Context, path string, conf testStreamConfig, sender *backend.StreamSender) error {
|
||||
ctxLogger := s.logger.FromContext(ctx)
|
||||
spread := 50.0
|
||||
walker := rand.Float64() * 100
|
||||
|
||||
@@ -107,7 +111,7 @@ func (s *Service) runTestStream(ctx context.Context, path string, conf testStrea
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
s.logger.Debug("Stop streaming data for path", "path", path)
|
||||
ctxLogger.Debug("Stop streaming data for path", "path", path)
|
||||
return ctx.Err()
|
||||
case t := <-ticker.C:
|
||||
if rand.Float64() < conf.Drop {
|
||||
|
||||
Reference in New Issue
Block a user