github.com/grafana/pyroscope@v1.18.0/pkg/util/spanlogger/query_log.go (about)

     1  package spanlogger
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  
     7  	"connectrpc.com/connect"
     8  	"github.com/go-kit/log"
     9  	"github.com/go-kit/log/level"
    10  	"github.com/opentracing/opentracing-go"
    11  	"github.com/prometheus/common/model"
    12  
    13  	profilev1 "github.com/grafana/pyroscope/api/gen/proto/go/google/v1"
    14  	querierv1 "github.com/grafana/pyroscope/api/gen/proto/go/querier/v1"
    15  	"github.com/grafana/pyroscope/api/gen/proto/go/querier/v1/querierv1connect"
    16  	typesv1 "github.com/grafana/pyroscope/api/gen/proto/go/types/v1"
    17  )
    18  
    19  type LogSpanParametersWrapper struct {
    20  	client querierv1connect.QuerierServiceClient
    21  	logger log.Logger
    22  }
    23  
    24  func NewLogSpanParametersWrapper(client querierv1connect.QuerierServiceClient, logger log.Logger) *LogSpanParametersWrapper {
    25  	return &LogSpanParametersWrapper{
    26  		client: client,
    27  		logger: logger,
    28  	}
    29  }
    30  
    31  func (l LogSpanParametersWrapper) ProfileTypes(ctx context.Context, c *connect.Request[querierv1.ProfileTypesRequest]) (*connect.Response[querierv1.ProfileTypesResponse], error) {
    32  	spanName := "ProfileTypes"
    33  	sp, ctx := opentracing.StartSpanFromContext(ctx, spanName)
    34  	level.Info(FromContext(ctx, l.logger)).Log(
    35  		"method", spanName,
    36  		"start", model.Time(c.Msg.Start).Time().String(),
    37  		"end", model.Time(c.Msg.End).Time().String(),
    38  		"query_window", model.Time(c.Msg.End).Sub(model.Time(c.Msg.Start)).String(),
    39  	)
    40  	defer sp.Finish()
    41  
    42  	return l.client.ProfileTypes(ctx, c)
    43  }
    44  
    45  func (l LogSpanParametersWrapper) LabelValues(ctx context.Context, c *connect.Request[typesv1.LabelValuesRequest]) (*connect.Response[typesv1.LabelValuesResponse], error) {
    46  	spanName := "LabelValues"
    47  	sp, ctx := opentracing.StartSpanFromContext(ctx, spanName)
    48  	level.Info(FromContext(ctx, l.logger)).Log(
    49  		"method", spanName,
    50  		"start", model.Time(c.Msg.Start).Time().String(),
    51  		"end", model.Time(c.Msg.End).Time().String(),
    52  		"query_window", model.Time(c.Msg.End).Sub(model.Time(c.Msg.Start)).String(),
    53  		"matchers", lazyJoin(c.Msg.Matchers),
    54  		"name", c.Msg.Name,
    55  	)
    56  	defer sp.Finish()
    57  
    58  	return l.client.LabelValues(ctx, c)
    59  }
    60  
    61  func (l LogSpanParametersWrapper) LabelNames(ctx context.Context, c *connect.Request[typesv1.LabelNamesRequest]) (*connect.Response[typesv1.LabelNamesResponse], error) {
    62  	spanName := "LabelNames"
    63  	sp, ctx := opentracing.StartSpanFromContext(ctx, spanName)
    64  	level.Info(FromContext(ctx, l.logger)).Log(
    65  		"method", spanName,
    66  		"start", model.Time(c.Msg.Start).Time().String(),
    67  		"end", model.Time(c.Msg.End).Time().String(),
    68  		"query_window", model.Time(c.Msg.End).Sub(model.Time(c.Msg.Start)).String(),
    69  		"matchers", lazyJoin(c.Msg.Matchers),
    70  	)
    71  	defer sp.Finish()
    72  
    73  	return l.client.LabelNames(ctx, c)
    74  }
    75  
    76  func (l LogSpanParametersWrapper) Series(ctx context.Context, c *connect.Request[querierv1.SeriesRequest]) (*connect.Response[querierv1.SeriesResponse], error) {
    77  	spanName := "Series"
    78  	sp, ctx := opentracing.StartSpanFromContext(ctx, spanName)
    79  	level.Info(FromContext(ctx, l.logger)).Log(
    80  		"method", spanName,
    81  		"start", model.Time(c.Msg.Start).Time().String(),
    82  		"end", model.Time(c.Msg.End).Time().String(),
    83  		"query_window", model.Time(c.Msg.End).Sub(model.Time(c.Msg.Start)).String(),
    84  		"matchers", lazyJoin(c.Msg.Matchers),
    85  		"label_names", lazyJoin(c.Msg.LabelNames),
    86  	)
    87  	defer sp.Finish()
    88  
    89  	return l.client.Series(ctx, c)
    90  }
    91  
    92  func (l LogSpanParametersWrapper) SelectMergeStacktraces(ctx context.Context, c *connect.Request[querierv1.SelectMergeStacktracesRequest]) (*connect.Response[querierv1.SelectMergeStacktracesResponse], error) {
    93  	spanName := "SelectMergeStacktraces"
    94  	sp, ctx := opentracing.StartSpanFromContext(ctx, spanName)
    95  	level.Info(FromContext(ctx, l.logger)).Log(
    96  		"method", spanName,
    97  		"start", model.Time(c.Msg.Start).Time().String(),
    98  		"end", model.Time(c.Msg.End).Time().String(),
    99  		"query_window", model.Time(c.Msg.End).Sub(model.Time(c.Msg.Start)).String(),
   100  		"selector", c.Msg.LabelSelector,
   101  		"profile_type", c.Msg.ProfileTypeID,
   102  		"format", c.Msg.Format,
   103  		"max_nodes", c.Msg.GetMaxNodes(),
   104  	)
   105  	defer sp.Finish()
   106  
   107  	return l.client.SelectMergeStacktraces(ctx, c)
   108  }
   109  
   110  func (l LogSpanParametersWrapper) SelectMergeSpanProfile(ctx context.Context, c *connect.Request[querierv1.SelectMergeSpanProfileRequest]) (*connect.Response[querierv1.SelectMergeSpanProfileResponse], error) {
   111  	spanName := "SelectMergeSpanProfile"
   112  	sp, ctx := opentracing.StartSpanFromContext(ctx, spanName)
   113  	level.Info(FromContext(ctx, l.logger)).Log(
   114  		"method", spanName,
   115  		"start", model.Time(c.Msg.Start).Time().String(),
   116  		"end", model.Time(c.Msg.End).Time().String(),
   117  		"query_window", model.Time(c.Msg.End).Sub(model.Time(c.Msg.Start)).String(),
   118  		"selector", c.Msg.LabelSelector,
   119  		"profile_type", c.Msg.ProfileTypeID,
   120  		"format", c.Msg.Format,
   121  		"max_nodes", c.Msg.GetMaxNodes(),
   122  	)
   123  	defer sp.Finish()
   124  
   125  	return l.client.SelectMergeSpanProfile(ctx, c)
   126  }
   127  
   128  func (l LogSpanParametersWrapper) SelectMergeProfile(ctx context.Context, c *connect.Request[querierv1.SelectMergeProfileRequest]) (*connect.Response[profilev1.Profile], error) {
   129  	spanName := "SelectMergeProfile"
   130  	sp, ctx := opentracing.StartSpanFromContext(ctx, spanName)
   131  	level.Info(FromContext(ctx, l.logger)).Log(
   132  		"method", spanName,
   133  		"start", model.Time(c.Msg.Start).Time().String(),
   134  		"end", model.Time(c.Msg.End).Time().String(),
   135  		"query_window", model.Time(c.Msg.End).Sub(model.Time(c.Msg.Start)).String(),
   136  		"selector", c.Msg.LabelSelector,
   137  		"max_nodes", c.Msg.GetMaxNodes(),
   138  		"profile_type", c.Msg.ProfileTypeID,
   139  		"stacktrace_selector", c.Msg.StackTraceSelector,
   140  	)
   141  	defer sp.Finish()
   142  
   143  	return l.client.SelectMergeProfile(ctx, c)
   144  }
   145  
   146  func (l LogSpanParametersWrapper) SelectSeries(ctx context.Context, c *connect.Request[querierv1.SelectSeriesRequest]) (*connect.Response[querierv1.SelectSeriesResponse], error) {
   147  	spanName := "SelectSeries"
   148  	sp, ctx := opentracing.StartSpanFromContext(ctx, spanName)
   149  	level.Info(FromContext(ctx, l.logger)).Log(
   150  		"method", spanName,
   151  		"start", model.Time(c.Msg.Start).Time().String(),
   152  		"end", model.Time(c.Msg.End).Time().String(),
   153  		"query_window", model.Time(c.Msg.End).Sub(model.Time(c.Msg.Start)).String(),
   154  		"selector", c.Msg.LabelSelector,
   155  		"profile_type", c.Msg.ProfileTypeID,
   156  		"stacktrace_selector", c.Msg.StackTraceSelector,
   157  		"step", c.Msg.Step,
   158  		"by", lazyJoin(c.Msg.GroupBy),
   159  		"aggregation", c.Msg.Aggregation,
   160  		"limit", c.Msg.Limit,
   161  	)
   162  	defer sp.Finish()
   163  
   164  	return l.client.SelectSeries(ctx, c)
   165  }
   166  
   167  func (l LogSpanParametersWrapper) Diff(ctx context.Context, c *connect.Request[querierv1.DiffRequest]) (*connect.Response[querierv1.DiffResponse], error) {
   168  	spanName := "Diff"
   169  	sp, ctx := opentracing.StartSpanFromContext(ctx, spanName)
   170  
   171  	left := &querierv1.SelectMergeStacktracesRequest{}
   172  	if c.Msg.Left != nil {
   173  		left = c.Msg.Left
   174  	}
   175  
   176  	right := &querierv1.SelectMergeStacktracesRequest{}
   177  	if c.Msg.Right != nil {
   178  		right = c.Msg.Right
   179  	}
   180  
   181  	level.Info(FromContext(ctx, l.logger)).Log(
   182  		"method", spanName,
   183  		"left_start", model.Time(left.Start).Time().String(),
   184  		"left_end", model.Time(left.End).Time().String(),
   185  		"left_query_window", model.Time(left.End).Sub(model.Time(left.Start)).String(),
   186  		"left_selector", left.LabelSelector,
   187  		"left_profile_type", left.ProfileTypeID,
   188  		"left_format", left.Format,
   189  		"left_max_nodes", left.GetMaxNodes(),
   190  		"right_start", model.Time(right.Start).Time().String(),
   191  		"right_end", model.Time(right.End).Time().String(),
   192  		"right_query_window", model.Time(right.End).Sub(model.Time(right.Start)).String(),
   193  		"right_selector", right.LabelSelector,
   194  		"right_profile_type", right.ProfileTypeID,
   195  		"right_format", right.Format,
   196  		"right_max_nodes", right.GetMaxNodes(),
   197  	)
   198  	defer sp.Finish()
   199  
   200  	return l.client.Diff(ctx, c)
   201  }
   202  
   203  func (l LogSpanParametersWrapper) GetProfileStats(ctx context.Context, c *connect.Request[typesv1.GetProfileStatsRequest]) (*connect.Response[typesv1.GetProfileStatsResponse], error) {
   204  	sp, ctx := opentracing.StartSpanFromContext(ctx, "GetProfileStats")
   205  	defer sp.Finish()
   206  
   207  	return l.client.GetProfileStats(ctx, c)
   208  }
   209  
   210  func (l LogSpanParametersWrapper) AnalyzeQuery(ctx context.Context, c *connect.Request[querierv1.AnalyzeQueryRequest]) (*connect.Response[querierv1.AnalyzeQueryResponse], error) {
   211  	spanName := "AnalyzeQuery"
   212  	sp, ctx := opentracing.StartSpanFromContext(ctx, spanName)
   213  	level.Info(FromContext(ctx, l.logger)).Log(
   214  		"method", spanName,
   215  		"start", model.Time(c.Msg.Start).Time().String(),
   216  		"end", model.Time(c.Msg.End).Time().String(),
   217  		"query_window", model.Time(c.Msg.End).Sub(model.Time(c.Msg.Start)).String(),
   218  		"query", c.Msg.Query,
   219  	)
   220  	defer sp.Finish()
   221  
   222  	return l.client.AnalyzeQuery(ctx, c)
   223  }
   224  
   225  type LazyJoin struct {
   226  	strs []string
   227  	sep  string
   228  }
   229  
   230  func (l *LazyJoin) String() string {
   231  	return strings.Join(l.strs, l.sep)
   232  }
   233  
   234  func lazyJoin(strs []string) *LazyJoin {
   235  	return &LazyJoin{strs: strs, sep: ","}
   236  }