Improve logs for backends owned by the Observability Traces and Profiling squad (#76109)
This commit is contained in:
@@ -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{
|
||||
|
||||
Reference in New Issue
Block a user