handleInstantQuery handles the traceql-metrics-instant tool
(ctx context.Context, request mcp.CallToolRequest)
| 120 | |
| 121 | // handleInstantQuery handles the traceql-metrics-instant tool |
| 122 | func (s *MCPServer) handleInstantQuery(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { |
| 123 | metricMCPToolCalls.WithLabelValues(toolTraceQLMetricsInstant).Inc() |
| 124 | |
| 125 | query, err := request.RequireString("query") |
| 126 | if err != nil { |
| 127 | return mcp.NewToolResultError(err.Error()), nil |
| 128 | } |
| 129 | |
| 130 | var startEpochNanos, endEpochNanos int64 |
| 131 | |
| 132 | start := request.GetString("start", "") |
| 133 | end := request.GetString("end", "") |
| 134 | |
| 135 | level.Info(s.logger).Log("msg", "executing instant metrics query", "query", query, "start", start, "end", end) |
| 136 | |
| 137 | if start == "" { |
| 138 | startEpochNanos = time.Now().Add(-1 * time.Hour).UnixNano() |
| 139 | } else { |
| 140 | startTS, err := time.Parse(time.RFC3339, start) |
| 141 | if err != nil { |
| 142 | return mcp.NewToolResultError(fmt.Sprintf("invalid start time: %v", err)), nil |
| 143 | } |
| 144 | startEpochNanos = startTS.UnixNano() |
| 145 | } |
| 146 | if end == "" { |
| 147 | endEpochNanos = time.Now().UnixNano() |
| 148 | } else { |
| 149 | endTS, err := time.Parse(time.RFC3339, end) |
| 150 | if err != nil { |
| 151 | return mcp.NewToolResultError(fmt.Sprintf("invalid end time: %v", err)), nil |
| 152 | } |
| 153 | endEpochNanos = endTS.UnixNano() |
| 154 | } |
| 155 | |
| 156 | parsed, err := traceql.ParseNoOptimizations(query) |
| 157 | if err != nil { |
| 158 | return mcp.NewToolResultError(fmt.Sprintf("query parse error. Consult TraceQL docs tools: %v", err)), nil |
| 159 | } |
| 160 | |
| 161 | if parsed.MetricsPipeline == nil { |
| 162 | return mcp.NewToolResultError("TraceQL search query received on instant query tool. Use the traceql-search tool instead"), nil |
| 163 | } |
| 164 | |
| 165 | queryInstantReq := &tempopb.QueryInstantRequest{ |
| 166 | Query: query, |
| 167 | Start: uint64(startEpochNanos), |
| 168 | End: uint64(endEpochNanos), |
| 169 | } |
| 170 | |
| 171 | req := api.BuildQueryInstantRequest(nil, queryInstantReq) |
| 172 | req.URL.Path = s.buildPath(api.PathMetricsQueryInstant) |
| 173 | |
| 174 | body, err := handleHTTP(ctx, s.frontend.MetricsQueryInstantHandler, req) |
| 175 | if err != nil { |
| 176 | return mcp.NewToolResultError(err.Error()), nil |
| 177 | } |
| 178 | |
| 179 | return toolResult(body, MetaTypeMetricsInstant, "json", "1"), nil |