Improve logs for backends owned by the Observability Traces and Profiling squad (#76109)

This commit is contained in:
Fabrizio
2023-10-31 11:57:17 +01:00
committed by GitHub
parent ba7a8fb75f
commit f8912517e6
12 changed files with 301 additions and 46 deletions
@@ -43,12 +43,15 @@ type PyroscopeDatasource struct {
// NewPyroscopeDatasource creates a new datasource instance.
func NewPyroscopeDatasource(ctx context.Context, httpClientProvider httpclient.Provider, settings backend.DataSourceInstanceSettings, ac accesscontrol.AccessControl) (instancemgmt.Instance, error) {
ctxLogger := logger.FromContext(ctx)
opt, err := settings.HTTPClientOptions(ctx)
if err != nil {
ctxLogger.Error("Failed to get HTTP client options", "error", err, "function", logEntrypoint())
return nil, err
}
httpClient, err := httpClientProvider.New(opt)
if err != nil {
ctxLogger.Error("Failed to create HTTP client", "error", err, "function", logEntrypoint())
return nil, err
}
@@ -61,9 +64,10 @@ func NewPyroscopeDatasource(ctx context.Context, httpClientProvider httpclient.P
}
func (d *PyroscopeDatasource) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
ctxLogger := logger.FromContext(ctx)
ctx, span := tracing.DefaultTracer().Start(ctx, "datasource.pyroscope.CallResource", trace.WithAttributes(attribute.String("path", req.Path), attribute.String("method", req.Method)))
defer span.End()
logger.Debug("CallResource", "Path", req.Path, "Method", req.Method, "Body", req.Body)
ctxLogger.Debug("CallResource", "Path", req.Path, "Method", req.Method, "Body", req.Body, "function", logEntrypoint())
if req.Path == "profileTypes" {
return d.profileTypes(ctx, req, sender)
}
@@ -79,32 +83,40 @@ func (d *PyroscopeDatasource) CallResource(ctx context.Context, req *backend.Cal
}
func (d *PyroscopeDatasource) profileTypes(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
ctxLogger := logger.FromContext(ctx)
types, err := d.client.ProfileTypes(ctx)
if err != nil {
ctxLogger.Error("Received error from client", "error", err, "function", logEntrypoint())
return err
}
bodyData, err := json.Marshal(types)
if err != nil {
ctxLogger.Error("Failed to marshal response", "error", err, "function", logEntrypoint())
return err
}
err = sender.Send(&backend.CallResourceResponse{Body: bodyData, Headers: req.Headers, Status: 200})
if err != nil {
ctxLogger.Error("Failed to send response", "error", err, "function", logEntrypoint())
return err
}
return nil
}
func (d *PyroscopeDatasource) labelNames(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
ctxLogger := logger.FromContext(ctx)
res, err := d.client.LabelNames(ctx)
if err != nil {
ctxLogger.Error("Received error from client", "error", err, "function", logEntrypoint())
return fmt.Errorf("error calling LabelNames: %v", err)
}
data, err := json.Marshal(res)
if err != nil {
ctxLogger.Error("Failed to marshal response", "error", err, "function", logEntrypoint())
return err
}
err = sender.Send(&backend.CallResourceResponse{Body: data, Headers: req.Headers, Status: 200})
if err != nil {
ctxLogger.Error("Failed to send response", "error", err, "function", logEntrypoint())
return err
}
return nil
@@ -118,24 +130,32 @@ type LabelValuesPayload struct {
}
func (d *PyroscopeDatasource) labelValues(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
ctxLogger := logger.FromContext(ctx)
u, err := url.Parse(req.URL)
if err != nil {
ctxLogger.Error("Failed to parse URL", "error", err, "function", logEntrypoint())
return err
}
query := u.Query()
res, err := d.client.LabelValues(ctx, query["label"][0])
if err != nil {
ctxLogger.Error("Received error from client", "error", err, "function", logEntrypoint())
return fmt.Errorf("error calling LabelValues: %v", err)
}
data, err := json.Marshal(res)
if err != nil {
ctxLogger.Error("Failed to marshal response", "error", err, "function", logEntrypoint())
return err
}
err = sender.Send(&backend.CallResourceResponse{Body: data, Headers: req.Headers, Status: 200})
if err != nil {
ctxLogger.Error("Failed to send response", "error", err, "function", logEntrypoint())
return err
}
return nil
}
@@ -144,13 +164,15 @@ func (d *PyroscopeDatasource) labelValues(ctx context.Context, req *backend.Call
// The QueryDataResponse contains a map of RefID to the response for each query, and each response
// contains Frames ([]*Frame).
func (d *PyroscopeDatasource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
logger.Debug("QueryData called", "Queries", req.Queries)
ctxLogger := logger.FromContext(ctx)
ctxLogger.Debug("Processing queries", "queryLenght", len(req.Queries), "function", logEntrypoint())
// create response struct
response := backend.NewQueryDataResponse()
// loop over queries and execute them individually.
for _, q := range req.Queries {
for i, q := range req.Queries {
ctxLogger.Debug("Processing query", "counter", i, "function", logEntrypoint())
res := d.query(ctx, req.PluginContext, q)
// save the response in a hashmap
@@ -158,6 +180,7 @@ func (d *PyroscopeDatasource) QueryData(ctx context.Context, req *backend.QueryD
response.Responses[q.RefID] = res
}
ctxLogger.Debug("All queries processed", "function", logEntrypoint())
return response, nil
}
@@ -166,7 +189,7 @@ func (d *PyroscopeDatasource) QueryData(ctx context.Context, req *backend.QueryD
// datasource configuration page which allows users to verify that
// a datasource is working as expected.
func (d *PyroscopeDatasource) CheckHealth(ctx context.Context, _ *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
logger.Debug("CheckHealth called")
logger.FromContext(ctx).Debug("CheckHealth called", "function", logEntrypoint())
status := backend.HealthStatusOk
message := "Data source is working"
@@ -185,7 +208,7 @@ func (d *PyroscopeDatasource) CheckHealth(ctx context.Context, _ *backend.CheckH
// SubscribeStream is called when a client wants to connect to a stream. This callback
// allows sending the first message.
func (d *PyroscopeDatasource) SubscribeStream(_ context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) {
logger.Debug("SubscribeStream called")
logger.Debug("Subscribing stream called", "function", logEntrypoint())
status := backend.SubscribeStreamStatusPermissionDenied
if req.Path == "stream" {
@@ -200,7 +223,8 @@ func (d *PyroscopeDatasource) SubscribeStream(_ context.Context, req *backend.Su
// RunStream is called once for any open channel. Results are shared with everyone
// subscribed to the same channel.
func (d *PyroscopeDatasource) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error {
logger.Debug("RunStream called")
ctxLogger := logger.FromContext(ctx)
ctxLogger.Debug("Running stream", "path", req.Path, "function", logEntrypoint())
// Create the same data frame as for query data.
frame := data.NewFrame("response")
@@ -217,7 +241,7 @@ func (d *PyroscopeDatasource) RunStream(ctx context.Context, req *backend.RunStr
for {
select {
case <-ctx.Done():
logger.Info("Context done, finish streaming", "path", req.Path)
ctxLogger.Info("Context done, finish streaming", "path", req.Path, "function", logEntrypoint())
return nil
case <-time.After(time.Second):
// Send new data periodically.
@@ -228,7 +252,7 @@ func (d *PyroscopeDatasource) RunStream(ctx context.Context, req *backend.RunStr
err := sender.SendFrame(frame, data.IncludeAll)
if err != nil {
logger.Error("Error sending frame", "error", err)
ctxLogger.Error("Error sending frame", "error", err, "function", logEntrypoint())
continue
}
}
@@ -236,8 +260,8 @@ func (d *PyroscopeDatasource) RunStream(ctx context.Context, req *backend.RunStr
}
// PublishStream is called when a client sends a message to the stream.
func (d *PyroscopeDatasource) PublishStream(_ context.Context, _ *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) {
logger.Debug("PublishStream called")
func (d *PyroscopeDatasource) PublishStream(ctx context.Context, _ *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) {
logger.FromContext(ctx).Debug("Publishing stream", "function", logEntrypoint())
// Do not allow publishing at all.
return &backend.PublishStreamResponse{