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 }