Skip to content

Commit 95eb90b

Browse files
committed
fix query builder for metric
this adds validation and fixes request type for diff signals fixes readme about defualt duration 24h to 6h
1 parent 9eafb23 commit 95eb90b

File tree

2 files changed

+123
-29
lines changed

2 files changed

+123
-29
lines changed

README.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ The MCP server provides the following tools that can be used through natural lan
247247
```
248248
"List all active alerts"
249249
"Get details for alert rule ID abc123"
250-
"Show me the history for alert rule abc123 from the last 24 hours"
250+
"Show me the history for alert rule abc123 from the last 6 hours"
251251
"Get logs related to alert abc456"
252252
```
253253

@@ -259,7 +259,7 @@ The MCP server provides the following tools that can be used through natural lan
259259

260260
#### Service Analysis
261261
```
262-
"List all services from the last 24 hours"
262+
"List all services from the last 6 hours"
263263
"What are the top operations for the paymentservice?"
264264
```
265265

@@ -311,15 +311,15 @@ Gets complete dashboard configuration.
311311
Lists all services within a time range.
312312
- **Parameters**:
313313
- `timeRange` (optional) - Time range like '2h', '6h', '2d', '7d'
314-
- `start` (optional) - Start time in nanoseconds (defaults to 24 hours ago)
314+
- `start` (optional) - Start time in nanoseconds (defaults to 6 hours ago)
315315
- `end` (optional) - End time in nanoseconds (defaults to now)
316316

317317
#### `get_service_top_operations`
318318
Gets top operations for a specific service.
319319
- **Parameters**:
320320
- `service` (required) - Service name
321321
- `timeRange` (optional) - Time range like '2h', '6h', '2d', '7d'
322-
- `start` (optional) - Start time in nanoseconds (defaults to 24 hours ago)
322+
- `start` (optional) - Start time in nanoseconds (defaults to 6 hours ago)
323323
- `end` (optional) - End time in nanoseconds (defaults to now)
324324
- `tags` (optional) - JSON array of tags
325325

@@ -328,7 +328,7 @@ Gets alert history timeline for a specific rule.
328328
- **Parameters**:
329329
- `ruleId` (required) - Alert rule ID
330330
- `timeRange` (optional) - Time range like '2h', '6h', '2d', '7d'
331-
- `start` (optional) - Start timestamp in milliseconds (defaults to 24 hours ago)
331+
- `start` (optional) - Start timestamp in milliseconds (defaults to 6 hours ago)
332332
- `end` (optional) - End timestamp in milliseconds (defaults to now)
333333
- `offset` (optional) - Offset for pagination (default: 0)
334334
- `limit` (optional) - Limit number of results (default: 20)
@@ -353,7 +353,7 @@ Gets logs related to a specific alert automatically.
353353
Gets logs with ERROR or FATAL severity within a time range.
354354
- **Parameters**:
355355
- `timeRange` (optional) - Time range like '2h', '6h', '2d', '7d'
356-
- `start` (optional) - Start time in milliseconds (defaults to 24 hours ago)
356+
- `start` (optional) - Start time in milliseconds (defaults to 6 hours ago)
357357
- `end` (optional) - End time in milliseconds (defaults to now)
358358
- `service` (optional) - Service name to filter by
359359
- `limit` (optional) - Maximum number of logs to return (default: 100)
@@ -363,7 +363,7 @@ Searches logs for a specific service within a time range.
363363
- **Parameters**:
364364
- `service` (required) - Service name to search logs for
365365
- `timeRange` (optional) - Time range like '2h', '6h', '2d', '7d'
366-
- `start` (optional) - Start time in milliseconds (defaults to 24 hours ago)
366+
- `start` (optional) - Start time in milliseconds (defaults to 6 hours ago)
367367
- `end` (optional) - End time in milliseconds (defaults to now)
368368
- `severity` (optional) - Log severity filter (DEBUG, INFO, WARN, ERROR, FATAL)
369369
- `searchText` (optional) - Text to search for in log body
@@ -380,7 +380,7 @@ Searches traces for a specific service.
380380
- **Parameters**:
381381
- `service` (required) - Service name to search traces for
382382
- `timeRange` (optional) - Time range like '2h', '6h', '2d', '7d'
383-
- `start` (optional) - Start time in milliseconds (defaults to 24 hours ago)
383+
- `start` (optional) - Start time in milliseconds (defaults to 6 hours ago)
384384
- `end` (optional) - End time in milliseconds (defaults to now)
385385
- `operation` (optional) - Operation name to filter by
386386
- `error` (optional) - Filter by error status (true/false)
@@ -393,15 +393,15 @@ Gets trace information including all spans and metadata.
393393
- **Parameters**:
394394
- `traceId` (required) - Trace ID to get details for
395395
- `timeRange` (optional) - Time range like '2h', '6h', '2d', '7d'
396-
- `start` (optional) - Start time in milliseconds (defaults to 24 hours ago)
396+
- `start` (optional) - Start time in milliseconds (defaults to 6 hours ago)
397397
- `end` (optional) - End time in milliseconds (defaults to now)
398398
- `includeSpans` (optional) - Include detailed span information (true/false, default: true)
399399

400400
#### `get_trace_error_analysis`
401401
Analyzes error patterns in traces.
402402
- **Parameters**:
403403
- `timeRange` (optional) - Time range like '2h', '6h', '2d', '7d'
404-
- `start` (optional) - Start time in milliseconds (defaults to 24 hours ago)
404+
- `start` (optional) - Start time in milliseconds (defaults to 6 hours ago)
405405
- `end` (optional) - End time in milliseconds (defaults to now)
406406
- `service` (optional) - Service name to filter by
407407
- **Returns**: Traces with errors, useful for identifying patterns and affected services
@@ -411,7 +411,7 @@ Gets trace span relationships and hierarchy.
411411
- **Parameters**:
412412
- `traceId` (required) - Trace ID to get span hierarchy for
413413
- `timeRange` (optional) - Time range like '2h', '6h', '2d', '7d'
414-
- `start` (optional) - Start time in milliseconds (defaults to 24 hours ago)
414+
- `start` (optional) - Start time in milliseconds (defaults to 6 hours ago)
415415
- `end` (optional) - End time in milliseconds (defaults to now)
416416

417417
#### `signoz_execute_builder_query`
@@ -438,7 +438,7 @@ Use the `timeRange` parameter with formats:
438438
- `'2d'` - Last 2 days
439439
- `'7d'` - Last 7 days
440440

441-
The `timeRange` parameter automatically calculates the time window from now backwards. If not specified, most tools default to the last 24 hours. You can also specify time in milliseconds and nanoseconds
441+
The `timeRange` parameter automatically calculates the time window from now backwards. If not specified, most tools default to the last 6 hours. You can also specify time in milliseconds and nanoseconds
442442
### Response Format
443443

444444
All tools return JSON responses that are optimized for LLM consumption:

pkg/types/querybuilder.go

Lines changed: 111 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type QuerySpec struct {
3333
Order []Order `json:"order"`
3434
Having Having `json:"having"`
3535
SelectFields []SelectField `json:"selectFields"`
36+
Aggregations []any `json:"aggregations,omitempty"`
3637
}
3738

3839
type Order struct {
@@ -69,20 +70,61 @@ type FormatOptions struct {
6970
// if there is an error LLM checks the error and fix.
7071
func (q *QueryPayload) Validate() error {
7172
if q.SchemaVersion == "" {
72-
return fmt.Errorf("missing required field: schemaVersion")
73+
q.SchemaVersion = "v1"
7374
}
74-
if q.RequestType == "" {
75-
return fmt.Errorf("missing required field: requestType")
75+
76+
if q.Start == 0 || q.End == 0 {
77+
return fmt.Errorf("missing start or end timestamp")
7678
}
7779
if len(q.CompositeQuery.Queries) == 0 {
7880
return fmt.Errorf("missing or empty compositeQuery.queries")
7981
}
80-
if q.Start == 0 {
81-
return fmt.Errorf("missing or zero start timestamp")
82+
83+
for i, query := range q.CompositeQuery.Queries {
84+
if query.Type != "builder_query" {
85+
continue
86+
}
87+
88+
spec := query.Spec
89+
signal := spec.Signal
90+
queryName := spec.Name
91+
if queryName == "" {
92+
queryName = fmt.Sprintf("query at position %d", i+1)
93+
}
94+
95+
switch signal {
96+
case "metrics":
97+
if q.RequestType != "time_series" {
98+
q.RequestType = "time_series"
99+
}
100+
if spec.StepInterval == nil || *spec.StepInterval <= 0 {
101+
def := int64(60)
102+
spec.StepInterval = &def
103+
}
104+
105+
case "traces":
106+
if q.RequestType != "raw" && q.RequestType != "trace" {
107+
q.RequestType = "raw"
108+
}
109+
spec.StepInterval = nil
110+
111+
case "logs":
112+
if q.RequestType != "raw" {
113+
q.RequestType = "raw"
114+
}
115+
spec.StepInterval = nil
116+
117+
default:
118+
return fmt.Errorf("%s: unknown signal type '%s'", queryName, signal)
119+
}
120+
121+
q.CompositeQuery.Queries[i].Spec = spec
82122
}
83-
if q.End == 0 {
84-
return fmt.Errorf("missing or zero end timestamp")
123+
124+
if q.RequestType == "" {
125+
q.RequestType = "raw"
85126
}
127+
86128
return nil
87129
}
88130

@@ -362,7 +404,8 @@ func buildMetricsHelpText(queryType string) string {
362404
- resource attributes: service.version, deployment.environment, etc.
363405
- metric attributes: custom labels and tags`
364406
case "structure":
365-
return `Metric query structure:
407+
return `Metric query structure (aggregations field is REQUIRED for metrics queries):
408+
366409
{
367410
"schemaVersion": "v1",
368411
"start": 1704067200000,
@@ -377,23 +420,31 @@ func buildMetricsHelpText(queryType string) string {
377420
"disabled": false,
378421
"limit": 10,
379422
"offset": 0,
380-
"order": [{"key": {"name": "timestamp"}, "direction": "desc"}],
423+
"order": [{"key": {"name": "0"}, "direction": "desc"}],
381424
"having": {"expression": ""},
382425
"selectFields": [
383426
{"name": "value", "fieldDataType": "float64", "signal": "metrics"},
384-
{"name": "metric_name", "fieldDataType": "string", "signal": "metrics"}
427+
{"name": "timestamp", "fieldDataType": "string", "signal": "metrics"}
385428
],
386-
"stepInterval": 60
429+
"stepInterval": 60,
430+
"aggregations": [{
431+
"metricName": "cpu_usage",
432+
"timeAggregation": "avg",
433+
"spaceAggregation": "avg",
434+
"temporality": "Unspecified"
435+
}]
387436
}
388437
}]
389438
},
390439
"formatOptions": {"formatTableResultForUI": false, "fillGaps": false},
391440
"variables": {}
392-
}`
441+
}
442+
443+
Note: The aggregations field is REQUIRED for metrics queries. Always include it explicitly with the metricName.`
393444
case "examples":
394445
return `Example metric queries:
395446
396-
1. CPU usage over time:
447+
1. CPU usage over time (with explicit aggregations):
397448
{
398449
"schemaVersion": "v1",
399450
"start": 1704067200000,
@@ -408,19 +459,62 @@ func buildMetricsHelpText(queryType string) string {
408459
"disabled": false,
409460
"limit": 100,
410461
"offset": 0,
411-
"order": [{"key": {"name": "timestamp"}, "direction": "asc"}],
412-
"having": {"expression": "metric_name = 'cpu_usage'"},
462+
"order": [{"key": {"name": "0"}, "direction": "asc"}],
463+
"having": {"expression": ""},
413464
"selectFields": [
414465
{"name": "value", "fieldDataType": "float64", "signal": "metrics"},
415466
{"name": "timestamp", "fieldDataType": "string", "signal": "metrics"}
416467
],
417-
"stepInterval": 60
468+
"stepInterval": 60,
469+
"aggregations": [{
470+
"metricName": "cpu_usage",
471+
"timeAggregation": "avg",
472+
"spaceAggregation": "avg",
473+
"temporality": "Unspecified"
474+
}]
418475
}
419476
}]
420477
},
421478
"formatOptions": {"formatTableResultForUI": false, "fillGaps": false},
422479
"variables": {}
423-
}`
480+
}
481+
482+
2. Memory usage with rate aggregation:
483+
{
484+
"schemaVersion": "v1",
485+
"start": 1704067200000,
486+
"end": 1758758400000,
487+
"requestType": "time_series",
488+
"compositeQuery": {
489+
"queries": [{
490+
"type": "builder_query",
491+
"spec": {
492+
"name": "A",
493+
"signal": "metrics",
494+
"disabled": false,
495+
"limit": 100,
496+
"offset": 0,
497+
"order": [{"key": {"name": "0"}, "direction": "desc"}],
498+
"having": {"expression": ""},
499+
"selectFields": [
500+
{"name": "value", "fieldDataType": "float64", "signal": "metrics"},
501+
{"name": "timestamp", "fieldDataType": "string", "signal": "metrics"}
502+
],
503+
"stepInterval": 60,
504+
"aggregations": [{
505+
"metricName": "memory_usage",
506+
"timeAggregation": "rate",
507+
"spaceAggregation": "sum",
508+
"temporality": "Cumulative"
509+
}]
510+
}
511+
}]
512+
},
513+
"formatOptions": {"formatTableResultForUI": false, "fillGaps": false},
514+
"variables": {}
515+
}
516+
517+
IMPORTANT: The "aggregations" field is REQUIRED for metrics queries. Always include it explicitly with the metricName.`
424518
default:
425519
return buildMetricsHelpText("fields") + "\n\n" + buildMetricsHelpText("structure") + "\n\n" + buildMetricsHelpText("examples")
426520
}

0 commit comments

Comments
 (0)