mirror of
https://github.com/SigNoz/signoz.git
synced 2026-03-24 13:20:27 +00:00
Compare commits
4 Commits
nv/4172
...
fix/promql
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7ad3680bc | ||
|
|
bc33c2ad29 | ||
|
|
e3f3b42858 | ||
|
|
531979543c |
@@ -144,6 +144,8 @@ telemetrystore:
|
||||
|
||||
##################### Prometheus #####################
|
||||
prometheus:
|
||||
# The maximum time a PromQL query is allowed to run before being aborted.
|
||||
timeout: 2m
|
||||
active_query_tracker:
|
||||
# Whether to enable the active query tracker.
|
||||
enabled: true
|
||||
|
||||
@@ -257,7 +257,7 @@ func TestManager_TestNotification_SendUnmatched_PromRule(t *testing.T) {
|
||||
WillReturnRows(samplesRows)
|
||||
|
||||
// Create Prometheus provider for this test
|
||||
promProvider = prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, store)
|
||||
promProvider = prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, store)
|
||||
},
|
||||
ManagerOptionsHook: func(opts *rules.ManagerOptions) {
|
||||
// Set Prometheus provider for PromQL queries
|
||||
|
||||
@@ -62,9 +62,6 @@ export const getVolumeQueryPayload = (
|
||||
const k8sPVCNameKey = dotMetricsEnabled
|
||||
? 'k8s.persistentvolumeclaim.name'
|
||||
: 'k8s_persistentvolumeclaim_name';
|
||||
const legendTemplate = dotMetricsEnabled
|
||||
? '{{k8s.namespace.name}}-{{k8s.pod.name}}'
|
||||
: '{{k8s_namespace_name}}-{{k8s_pod_name}}';
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -136,7 +133,7 @@ export const getVolumeQueryPayload = (
|
||||
functions: [],
|
||||
groupBy: [],
|
||||
having: [],
|
||||
legend: legendTemplate,
|
||||
legend: 'Available',
|
||||
limit: null,
|
||||
orderBy: [],
|
||||
queryName: 'A',
|
||||
@@ -228,7 +225,7 @@ export const getVolumeQueryPayload = (
|
||||
functions: [],
|
||||
groupBy: [],
|
||||
having: [],
|
||||
legend: legendTemplate,
|
||||
legend: 'Capacity',
|
||||
limit: null,
|
||||
orderBy: [],
|
||||
queryName: 'A',
|
||||
@@ -319,7 +316,7 @@ export const getVolumeQueryPayload = (
|
||||
},
|
||||
groupBy: [],
|
||||
having: [],
|
||||
legend: legendTemplate,
|
||||
legend: 'Inodes Used',
|
||||
limit: null,
|
||||
orderBy: [],
|
||||
queryName: 'A',
|
||||
@@ -411,7 +408,7 @@ export const getVolumeQueryPayload = (
|
||||
},
|
||||
groupBy: [],
|
||||
having: [],
|
||||
legend: legendTemplate,
|
||||
legend: 'Total Inodes',
|
||||
limit: null,
|
||||
orderBy: [],
|
||||
queryName: 'A',
|
||||
@@ -503,7 +500,7 @@ export const getVolumeQueryPayload = (
|
||||
},
|
||||
groupBy: [],
|
||||
having: [],
|
||||
legend: legendTemplate,
|
||||
legend: 'Inodes Free',
|
||||
limit: null,
|
||||
orderBy: [],
|
||||
queryName: 'A',
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
package common
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// Shared types
|
||||
// ──────────────────────────────────────────────
|
||||
|
||||
#TelemetryFieldKey: {
|
||||
name: string
|
||||
key?: string
|
||||
description?: string
|
||||
unit?: string
|
||||
signal?: string
|
||||
fieldContext?: string
|
||||
fieldDataType?: string
|
||||
materialized?: bool
|
||||
isIndexed?: bool
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// Panel types
|
||||
// ──────────────────────────────────────────────
|
||||
|
||||
#ContextLinkProps: {
|
||||
url: string
|
||||
label: string
|
||||
}
|
||||
|
||||
#TimePreference: *"globalTime" | "last5Min" | "last15Min" | "last30Min" | "last1Hr" | "last6Hr" | "last1Day" | "last3Days" | "last1Week" | "last1Month"
|
||||
|
||||
#PrecisionOption: *2 | 0 | 1 | 3 | 4 | "full"
|
||||
|
||||
#Axes: {
|
||||
softMin?: number | *null
|
||||
softMax?: number | *null
|
||||
isLogScale?: bool | *false
|
||||
}
|
||||
|
||||
#LegendPosition: *"bottom" | "right"
|
||||
|
||||
#ThresholdWithLabel: {
|
||||
value: number
|
||||
unit?: string
|
||||
color: string
|
||||
format: "Text" | "Background"
|
||||
label?: string
|
||||
}
|
||||
|
||||
#ComparisonThreshold: {
|
||||
value: number
|
||||
operator: ">" | "<" | ">=" | "<=" | "="
|
||||
unit?: string
|
||||
color: string
|
||||
format: "Text" | "Background"
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// Query types
|
||||
// ──────────────────────────────────────────────
|
||||
|
||||
#QueryName: =~"^[A-Za-z][A-Za-z0-9_]*$"
|
||||
|
||||
#Limit: int & >=0 & <=10000
|
||||
|
||||
#Offset: int & >=0
|
||||
|
||||
#ReduceTo: "sum" | "count" | "avg" | "min" | "max" | "last" | "median"
|
||||
|
||||
#MetricAggregation: close({
|
||||
metricName: string & !=""
|
||||
timeAggregation: "latest" | "sum" | "avg" | "min" | "max" | "count" | "rate" | "increase"
|
||||
spaceAggregation: "sum" | "avg" | "min" | "max" | "count" | "p50" | "p75" | "p90" | "p95" | "p99"
|
||||
reduceTo?: #ReduceTo
|
||||
temporality?: "delta" | "cumulative" | "unspecified"
|
||||
})
|
||||
|
||||
#ExpressionAggregation: close({
|
||||
expression: string & !=""
|
||||
alias?: string
|
||||
})
|
||||
|
||||
#Aggregation: #MetricAggregation | #ExpressionAggregation
|
||||
|
||||
#FilterExpression: close({
|
||||
expression: string
|
||||
})
|
||||
|
||||
#GroupByItem: close({
|
||||
name: string & !=""
|
||||
fieldDataType?: string
|
||||
fieldContext?: string
|
||||
})
|
||||
|
||||
#OrderByItem: close({
|
||||
columnName: string & !=""
|
||||
order: "asc" | "desc"
|
||||
})
|
||||
|
||||
#HavingExpression: close({
|
||||
expression: string
|
||||
})
|
||||
|
||||
#Function: close({
|
||||
name: "cutOffMin" | "cutOffMax" | "clampMin" | "clampMax" |
|
||||
"absolute" | "runningDiff" | "log2" | "log10" |
|
||||
"cumulativeSum" | "ewma3" | "ewma5" | "ewma7" |
|
||||
"median3" | "median5" | "median7" | "timeShift" |
|
||||
"anomaly" | "fillZero"
|
||||
args?: [...close({value: number | string | bool})]
|
||||
})
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// Variable types
|
||||
// ──────────────────────────────────────────────
|
||||
|
||||
#VariableSortOrder: *"disabled" | "asc" | "desc"
|
||||
@@ -1,4 +0,0 @@
|
||||
module: "github.com/signoz"
|
||||
language: {
|
||||
version: "v0.12.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,868 +0,0 @@
|
||||
{
|
||||
"kind": "Dashboard",
|
||||
"metadata": {
|
||||
"name": "the-everything-dashboard",
|
||||
"project": "signoz"
|
||||
},
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "The everything dashboard",
|
||||
"description": "Trying to cover as many concepts here as possible"
|
||||
},
|
||||
"duration": "1h",
|
||||
"datasources": {
|
||||
"SigNozDatasource": {
|
||||
"default": true,
|
||||
"plugin": {
|
||||
"kind": "SigNozDatasource",
|
||||
"spec": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"kind": "ListVariable",
|
||||
"spec": {
|
||||
"name": "serviceName",
|
||||
"display": {
|
||||
"name": "serviceName"
|
||||
},
|
||||
"allowAllValue": true,
|
||||
"allowMultiple": false,
|
||||
"plugin": {
|
||||
"kind": "SigNozDynamicVariable",
|
||||
"spec": {
|
||||
"name": "service.name",
|
||||
"source": "Metrics",
|
||||
"sort": "disabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "ListVariable",
|
||||
"spec": {
|
||||
"name": "statusCodesFromQuery",
|
||||
"display": {
|
||||
"name": "statusCodesFromQuery"
|
||||
},
|
||||
"allowAllValue": true,
|
||||
"allowMultiple": true,
|
||||
"plugin": {
|
||||
"kind": "SigNozQueryVariable",
|
||||
"spec": {
|
||||
"queryValue": "SELECT JSONExtractString(labels, 'http.status_code') AS status_code FROM signoz_metrics.distributed_time_series_v4_1day WHERE status_code != '' GROUP BY status_code",
|
||||
"sort": "asc"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "ListVariable",
|
||||
"spec": {
|
||||
"name": "limit",
|
||||
"display": {
|
||||
"name": "limit"
|
||||
},
|
||||
"allowAllValue": false,
|
||||
"allowMultiple": false,
|
||||
"plugin": {
|
||||
"kind": "SigNozCustomVariable",
|
||||
"spec": {
|
||||
"customValue": "1,10,20,40,80,160,200",
|
||||
"sort": "disabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"panels": {
|
||||
"24e2697b": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "total resp size",
|
||||
"description": ""
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozTimeSeriesPanel",
|
||||
"spec": {
|
||||
"visualization": {
|
||||
"fillSpans": true
|
||||
},
|
||||
"formatting": {
|
||||
"unit": "By",
|
||||
"decimalPrecision": 3
|
||||
},
|
||||
"axes": {
|
||||
"softMax": 800,
|
||||
"isLogScale": true
|
||||
},
|
||||
"legend": {
|
||||
"position": "right",
|
||||
"customColors": {
|
||||
"{service.name=\"sampleapp-gateway\"}": "#9ea5f7"
|
||||
}
|
||||
},
|
||||
"contextLinks": [
|
||||
{
|
||||
"label": "View service details",
|
||||
"url": "http://localhost:8080/{{_service.name}}?dfddf=%7B%7Blimit%7D%7D"
|
||||
}
|
||||
],
|
||||
"thresholds": [
|
||||
{
|
||||
"value": 1024,
|
||||
"unit": "By",
|
||||
"color": "Red",
|
||||
"format": "Text",
|
||||
"label": "upper limit"
|
||||
},
|
||||
{
|
||||
"value": 100,
|
||||
"unit": "By",
|
||||
"color": "Orange",
|
||||
"format": "Text",
|
||||
"label": "kinda bad"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozBuilderQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "metrics",
|
||||
"expression": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"metricName": "http.server.response.body.size.sum",
|
||||
"reduceTo": "sum",
|
||||
"spaceAggregation": "sum",
|
||||
"timeAggregation": "rate"
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "http.response.status_code IN $statusCodesFromQuery"
|
||||
},
|
||||
"groupBy": [
|
||||
{
|
||||
"name": "service.name",
|
||||
"fieldDataType": "string",
|
||||
"fieldContext": "tag"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ff2f72f1": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "fraction of calls",
|
||||
"description": ""
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozTimeSeriesPanel",
|
||||
"spec": {
|
||||
"visualization": {
|
||||
"fillSpans": true
|
||||
},
|
||||
"formatting": {
|
||||
"decimalPrecision": 1
|
||||
},
|
||||
"thresholds": [
|
||||
{
|
||||
"value": 1,
|
||||
"color": "Blue",
|
||||
"format": "Background",
|
||||
"label": "max possible"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozCompositeQuery",
|
||||
"spec": {
|
||||
"queries": [
|
||||
{
|
||||
"type": "builder_query",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "metrics",
|
||||
"expression": "A",
|
||||
"disabled": true,
|
||||
"aggregations": [
|
||||
{
|
||||
"metricName": "signoz_calls_total",
|
||||
"reduceTo": "sum",
|
||||
"spaceAggregation": "sum",
|
||||
"timeAggregation": "rate"
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "service.name IN $serviceName AND http.status_code IN $statusCodesFromQuery"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "builder_query",
|
||||
"spec": {
|
||||
"name": "B",
|
||||
"signal": "metrics",
|
||||
"expression": "B",
|
||||
"disabled": true,
|
||||
"aggregations": [
|
||||
{
|
||||
"metricName": "signoz_calls_total",
|
||||
"reduceTo": "sum",
|
||||
"spaceAggregation": "sum",
|
||||
"timeAggregation": "rate"
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "service.name in $serviceName"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "builder_formula",
|
||||
"spec": {
|
||||
"name": "F1",
|
||||
"expression": "A / B"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"011605e7": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "total resp size"
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozBarChartPanel",
|
||||
"spec": {
|
||||
"visualization": {
|
||||
"stackedBarChart": false
|
||||
},
|
||||
"formatting": {
|
||||
"unit": "By"
|
||||
}
|
||||
}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozBuilderQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "metrics",
|
||||
"expression": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"metricName": "http.server.response.body.size.sum",
|
||||
"reduceTo": "sum",
|
||||
"spaceAggregation": "sum",
|
||||
"timeAggregation": "rate"
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "http.response.status_code IN $statusCodesFromQuery"
|
||||
},
|
||||
"groupBy": [
|
||||
{
|
||||
"name": "service.name",
|
||||
"fieldDataType": "string",
|
||||
"fieldContext": "tag"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"e23516fc": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "num traces for service"
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozNumberPanel",
|
||||
"spec": {
|
||||
"formatting": {
|
||||
"unit": "none",
|
||||
"decimalPrecision": 1
|
||||
},
|
||||
"thresholds": [
|
||||
{
|
||||
"value": 1200000,
|
||||
"operator": ">",
|
||||
"unit": "none",
|
||||
"color": "Red",
|
||||
"format": "Text"
|
||||
},
|
||||
{
|
||||
"value": 1200000,
|
||||
"operator": "<=",
|
||||
"unit": "none",
|
||||
"color": "Green",
|
||||
"format": "Text"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozBuilderQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "traces",
|
||||
"expression": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"expression": "count() "
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "service.name = $serviceName "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"130c8d6b": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "num logs for service"
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozNumberPanel",
|
||||
"spec": {
|
||||
"formatting": {
|
||||
"unit": "none",
|
||||
"decimalPrecision": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozBuilderQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "logs",
|
||||
"expression": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"expression": "count() "
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "service.name = $serviceName "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"246f7c6d": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "num traces for service per resp code"
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozPieChartPanel",
|
||||
"spec": {
|
||||
"formatting": {
|
||||
"decimalPrecision": 1
|
||||
},
|
||||
"legend": {
|
||||
"customColors": {
|
||||
"\"201\"": "#2bc051",
|
||||
"\"400\"": "#cc462e",
|
||||
"\"500\"": "#ff0000"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozBuilderQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "traces",
|
||||
"expression": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"expression": "count() "
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "service.name = $serviceName isEntryPoint = 'true'"
|
||||
},
|
||||
"groupBy": [
|
||||
{
|
||||
"name": "http.response.status_code",
|
||||
"fieldDataType": "float64",
|
||||
"fieldContext": "tag"
|
||||
}
|
||||
],
|
||||
"legend": "\"{{http.response.status_code}}\""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"21f7d4d0": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "average latency per service"
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozTablePanel",
|
||||
"spec": {
|
||||
"formatting": {
|
||||
"columnUnits": {
|
||||
"A": "s"
|
||||
}
|
||||
},
|
||||
"thresholds": [
|
||||
{
|
||||
"value": 1,
|
||||
"operator": ">",
|
||||
"unit": "min",
|
||||
"color": "Red",
|
||||
"format": "Text",
|
||||
"tableOptions": "A"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozClickHouseSQL",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"query": "WITH\n __spatial_aggregation_cte AS\n (\n SELECT\n toStartOfInterval(toDateTime(intDiv(unix_milli, 1000)), toIntervalSecond(60)) AS ts,\n `service.name`,\n le,\n sum(value) / 60 AS value\n FROM signoz_metrics.distributed_samples_v4 AS points\n INNER JOIN\n (\n SELECT\n fingerprint,\n JSONExtractString(labels, 'service.name') AS `service.name`,\n JSONExtractString(labels, 'le') AS le\n FROM signoz_metrics.time_series_v4\n WHERE (metric_name IN ('signoz_latency.bucket')) AND (LOWER(temporality) LIKE LOWER('delta')) AND (__normalized = 0)\n GROUP BY\n fingerprint,\n `service.name`,\n le\n ) AS filtered_time_series ON points.fingerprint = filtered_time_series.fingerprint\n WHERE metric_name IN ('signoz_latency.bucket')\n GROUP BY\n ts,\n `service.name`,\n le\n ),\n __histogramCTE AS\n (\n SELECT\n ts,\n `service.name`,\n histogramQuantile(arrayMap(x -> toFloat64(x), groupArray(le)), groupArray(value), 0.9) AS value\n FROM __spatial_aggregation_cte\n GROUP BY\n `service.name`,\n ts\n ORDER BY\n `service.name` ASC,\n ts ASC\n )\nSELECT\n `service.name` AS service,\n avg(value) AS A\nFROM __histogramCTE\nGROUP BY `service.name`"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ad5fd556": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "logs from service"
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozListPanel",
|
||||
"spec": {
|
||||
"selectedLogFields": [
|
||||
{
|
||||
"name": "timestamp",
|
||||
"type": "log",
|
||||
"dataType": ""
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"type": "log",
|
||||
"dataType": ""
|
||||
},
|
||||
{
|
||||
"name": "error",
|
||||
"type": "",
|
||||
"dataType": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "LogQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozBuilderQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "logs",
|
||||
"expression": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"expression": "count() "
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "service.name = $serviceName"
|
||||
},
|
||||
"groupBy": [],
|
||||
"order": [
|
||||
{
|
||||
"columnName": "timestamp",
|
||||
"order": "desc"
|
||||
},
|
||||
{
|
||||
"columnName": "id",
|
||||
"order": "desc"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"f07b59ee": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "response size buckets"
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozHistogramPanel",
|
||||
"spec": {
|
||||
"histogramBuckets": {
|
||||
"bucketCount": 60,
|
||||
"mergeAllActiveQueries": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozBuilderQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "metrics",
|
||||
"expression": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"metricName": "http.server.response.body.size.bucket",
|
||||
"reduceTo": "avg",
|
||||
"spaceAggregation": "p90",
|
||||
"timeAggregation": "rate"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"e1a41831": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "trace operator",
|
||||
"description": ""
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozTimeSeriesPanel",
|
||||
"spec": {
|
||||
"legend": {
|
||||
"position": "right"
|
||||
}
|
||||
}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozCompositeQuery",
|
||||
"spec": {
|
||||
"queries": [
|
||||
{
|
||||
"type": "builder_query",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "traces",
|
||||
"expression": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"expression": "count() "
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "service.name = 'sampleapp-gateway' "
|
||||
},
|
||||
"legend": "Gateway"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "builder_query",
|
||||
"spec": {
|
||||
"name": "B",
|
||||
"signal": "traces",
|
||||
"expression": "B",
|
||||
"aggregations": [
|
||||
{
|
||||
"expression": "count() "
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "http.response.status_code = 200"
|
||||
},
|
||||
"legend": "$serviceName"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "builder_trace_operator",
|
||||
"spec": {
|
||||
"name": "T1",
|
||||
"expression": "A -> B ",
|
||||
"aggregations": [
|
||||
{
|
||||
"expression": "count()",
|
||||
"alias": "request_count"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"f0d70491": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "no results in this promql",
|
||||
"description": ""
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozTimeSeriesPanel",
|
||||
"spec": {}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozCompositeQuery",
|
||||
"spec": {
|
||||
"queries": [
|
||||
{
|
||||
"type": "promql",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"query": "sum(rate(flask_exporter_info[5m]))"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "promql",
|
||||
"spec": {
|
||||
"name": "B",
|
||||
"query": "sum(increase(flask_exporter_info[5m]))"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"0e6eb4ca": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"display": {
|
||||
"name": "no results in this promql",
|
||||
"description": ""
|
||||
},
|
||||
"plugin": {
|
||||
"kind": "SigNozTimeSeriesPanel",
|
||||
"spec": {}
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozPromQLQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"query": "sum(rate(flask_exporter_info[5m]))"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"layouts": [
|
||||
{
|
||||
"kind": "Grid",
|
||||
"spec": {
|
||||
"items": [
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 6,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/24e2697b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 6,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/ff2f72f1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 6,
|
||||
"width": 6,
|
||||
"height": 6,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/011605e7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 6,
|
||||
"y": 6,
|
||||
"width": 6,
|
||||
"height": 3,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/e23516fc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 6,
|
||||
"y": 9,
|
||||
"width": 6,
|
||||
"height": 3,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/130c8d6b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 12,
|
||||
"width": 6,
|
||||
"height": 6,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/246f7c6d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 6,
|
||||
"y": 12,
|
||||
"width": 6,
|
||||
"height": 6,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/21f7d4d0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 18,
|
||||
"width": 6,
|
||||
"height": 6,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/ad5fd556"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 6,
|
||||
"y": 18,
|
||||
"width": 6,
|
||||
"height": 6,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/f07b59ee"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 24,
|
||||
"width": 12,
|
||||
"height": 6,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/e1a41831"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 30,
|
||||
"width": 6,
|
||||
"height": 6,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/f0d70491"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 6,
|
||||
"y": 30,
|
||||
"width": 6,
|
||||
"height": 6,
|
||||
"content": {
|
||||
"$ref": "#/spec/panels/0e6eb4ca"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
# Adding a new panel plugin
|
||||
|
||||
This guide is for developers adding a new panel kind to the Perses schema. It covers the file structure you need to create, the shared types available in `common.cue`, and how to compose them into your panel's spec.
|
||||
|
||||
---
|
||||
|
||||
## 1. File structure
|
||||
|
||||
Create a new directory under `schemas-wrapper/schemas/` named after your panel:
|
||||
|
||||
```
|
||||
schemas-wrapper/schemas/your-panel-name/
|
||||
├── your-panel-name.cue # Schema definition
|
||||
└── example.json # Example JSON that validates against the schema
|
||||
```
|
||||
|
||||
The CUE file must use `package model` and declare a `kind` and `spec`:
|
||||
|
||||
```cue
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
kind: "YourPanelName"
|
||||
spec: close({
|
||||
// your fields here
|
||||
})
|
||||
```
|
||||
|
||||
Register the panel in `schemas-wrapper/schemas/package.json` by adding an entry to the `plugins` array:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"name": "YourPanelName"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Available shared types from `common.cue`
|
||||
|
||||
These types are defined in `common/common.cue` and can be used via `import "github.com/signoz/common"`. Use them instead of redefining the same structures in your panel.
|
||||
|
||||
## 3. Defining your spec
|
||||
|
||||
Your spec is a `close({})` block containing the fields relevant to your panel. Pick from the shared types above and add panel-specific types as needed. Every field should be optional (suffixed with `?`) since a panel should be valid with just defaults.
|
||||
|
||||
### Typical patterns
|
||||
|
||||
**Panel with graphs** (has axes, legend, thresholds as reference lines):
|
||||
|
||||
```cue
|
||||
spec: close({
|
||||
visualization?: #Visualization
|
||||
formatting?: #Formatting
|
||||
axes?: common.#Axes
|
||||
legend?: #Legend
|
||||
contextLinks?: [...common.#ContextLinkProps]
|
||||
thresholds?: [...common.#ThresholdWithLabel]
|
||||
})
|
||||
```
|
||||
|
||||
**Panel with a single value** (no axes/legend, thresholds as conditional formatting):
|
||||
|
||||
```cue
|
||||
spec: close({
|
||||
visualization?: #Visualization
|
||||
formatting?: #Formatting
|
||||
contextLinks?: [...common.#ContextLinkProps]
|
||||
thresholds?: [...common.#ComparisonThreshold]
|
||||
})
|
||||
```
|
||||
|
||||
**Panel with custom data structure** (panel-specific fields only):
|
||||
|
||||
```cue
|
||||
spec: close({
|
||||
yourCustomConfig?: #YourCustomConfig
|
||||
contextLinks?: [...common.#ContextLinkProps]
|
||||
})
|
||||
```
|
||||
|
||||
### Defining panel-local types
|
||||
|
||||
Types that are specific to your panel (not reusable) should be defined in your CUE file, not in common. For example, `#Visualization` varies per panel because each panel has different rendering options:
|
||||
|
||||
```cue
|
||||
#Visualization: {
|
||||
timePreference?: common.#TimePreference
|
||||
yourCustomFlag?: bool | *false
|
||||
}
|
||||
```
|
||||
|
||||
If your panel needs a threshold type that extends a common one, embed it:
|
||||
|
||||
```cue
|
||||
#YourThreshold: {
|
||||
common.#ComparisonThreshold
|
||||
extraField: string
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Writing the example JSON
|
||||
|
||||
Create an `example.json` that exercises all fields in your spec. This file is used for validation — `./validate.sh` will check it against your schema.
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "YourPanelName",
|
||||
"spec": {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Also add at least one panel using your new kind to `examples/perses.json` so it gets validated as part of a full dashboard.
|
||||
|
||||
---
|
||||
|
||||
## 5. Validation
|
||||
|
||||
Run `./validate.sh` from the `perses/` directory. It lints `examples/perses.json` against all registered schemas. If your schema or example has issues, the error will point to the specific field.
|
||||
|
||||
---
|
||||
|
||||
## Quick reference: existing panels and what they use
|
||||
|
||||
| Field | Time-series | Bar-chart | Number | Pie | Table | Histogram | List |
|
||||
|-------|:-----------:|:---------:|:------:|:---:|:-----:|:---------:|:----:|
|
||||
| `visualization` | yes | yes | yes | yes | yes | — | — |
|
||||
| `formatting` | yes | yes | yes | yes | yes | — | — |
|
||||
| `axes` | yes | yes | — | — | — | — | — |
|
||||
| `legend` | yes | yes | — | yes | — | yes | — |
|
||||
| `contextLinks` | yes | yes | yes | yes | yes | yes | — |
|
||||
| `thresholds` | yes | yes | yes | — | yes | — | — |
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"id": "signoz",
|
||||
"name": "signoz",
|
||||
"metaData": {
|
||||
"buildInfo": {
|
||||
"buildVersion": "0.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
{
|
||||
"name": "@signoz/signoz-schemas",
|
||||
"version": "0.0.1",
|
||||
"description": "SigNoz schema plugins",
|
||||
"perses": {
|
||||
"schemasPath": ".",
|
||||
"plugins": [
|
||||
{
|
||||
"kind": "Datasource",
|
||||
"spec": {
|
||||
"name": "SigNozDatasource"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"name": "SigNozTimeSeriesPanel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"name": "SigNozBarChartPanel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"name": "SigNozNumberPanel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"name": "SigNozPieChartPanel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"name": "SigNozTablePanel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"name": "SigNozHistogramPanel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"name": "SigNozListPanel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"name": "SigNozIgnoredFieldsChart"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"name": "SigNozBuilderQuery"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"name": "SigNozClickHouseSQL"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"name": "SigNozPromQLQuery"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"name": "SigNozCompositeQuery"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"name": "SigNozTraceOperator"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"name": "SigNozFormula"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "LogQuery",
|
||||
"spec": {
|
||||
"name": "SigNozBuilderQuery"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "TraceQuery",
|
||||
"spec": {
|
||||
"name": "SigNozBuilderQuery"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"spec": {
|
||||
"name": "SigNozCustomVariable"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"spec": {
|
||||
"name": "SigNozDynamicVariable"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"spec": {
|
||||
"name": "SigNozQueryVariable"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozBarChartPanel",
|
||||
"spec": {
|
||||
"visualization": {
|
||||
"timePreference": "globalTime",
|
||||
"fillSpans": false,
|
||||
"stackedBarChart": false
|
||||
},
|
||||
"formatting": {
|
||||
"unit": "By",
|
||||
"decimalPrecision": 2
|
||||
},
|
||||
"axes": {
|
||||
"softMin": 0,
|
||||
"softMax": 1000,
|
||||
"isLogScale": false
|
||||
},
|
||||
"legend": {
|
||||
"position": "bottom",
|
||||
"customColors": {
|
||||
"series-A": "#9ea5f7"
|
||||
}
|
||||
},
|
||||
"contextLinks": [
|
||||
{
|
||||
"label": "View details",
|
||||
"url": "http://localhost:8080/{{_service.name}}"
|
||||
}
|
||||
],
|
||||
"thresholds": [
|
||||
{
|
||||
"value": 500,
|
||||
"unit": "By",
|
||||
"color": "Red",
|
||||
"format": "Text",
|
||||
"label": "upper limit"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
kind: "SigNozBarChartPanel"
|
||||
spec: close({
|
||||
visualization?: #Visualization
|
||||
formatting?: #Formatting
|
||||
axes?: common.#Axes
|
||||
legend?: #Legend
|
||||
contextLinks?: [...common.#ContextLinkProps]
|
||||
thresholds?: [...common.#ThresholdWithLabel]
|
||||
})
|
||||
|
||||
#Visualization: {
|
||||
timePreference?: common.#TimePreference
|
||||
fillSpans?: bool | *false
|
||||
stackedBarChart?: bool | *true
|
||||
}
|
||||
|
||||
#Formatting: {
|
||||
unit?: string | *""
|
||||
decimalPrecision?: common.#PrecisionOption
|
||||
}
|
||||
|
||||
#Legend: {
|
||||
position?: common.#LegendPosition
|
||||
customColors?: [string]: string
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
// Source: pkg/types/querybuildertypes/querybuildertypesv5/builder_query.go — QueryBuilderQuery
|
||||
kind: "SigNozBuilderQuery"
|
||||
spec: close({
|
||||
name: common.#QueryName
|
||||
signal: "metrics" | "logs" | "traces"
|
||||
expression: string
|
||||
disabled?: bool | *false
|
||||
|
||||
aggregations?: [...common.#Aggregation]
|
||||
filter?: common.#FilterExpression
|
||||
groupBy?: [...common.#GroupByItem]
|
||||
order?: [...common.#OrderByItem]
|
||||
selectFields?: [...common.#TelemetryFieldKey]
|
||||
limit?: common.#Limit
|
||||
limitBy?: #LimitBy
|
||||
offset?: common.#Offset
|
||||
cursor?: string
|
||||
having?: common.#HavingExpression
|
||||
// secondaryAggregations not added — not yet implemented.
|
||||
functions?: [...common.#Function]
|
||||
legend?: string
|
||||
stepInterval?: number
|
||||
reduceTo?: common.#ReduceTo
|
||||
pageSize?: int & >=1
|
||||
source?: string
|
||||
})
|
||||
|
||||
#LimitBy: close({
|
||||
keys: [...string]
|
||||
value: string
|
||||
})
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozBuilderQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "metrics",
|
||||
"expression": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"metricName": "redis_keyspace_hits",
|
||||
"timeAggregation": "rate",
|
||||
"spaceAggregation": "sum",
|
||||
"reduceTo": "sum"
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "host_name IN $host_name"
|
||||
},
|
||||
"groupBy": [],
|
||||
"order": [],
|
||||
"disabled": false,
|
||||
"legend": "Hit/s across all hosts",
|
||||
"stepInterval": 60
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
// Source: pkg/types/querybuildertypes/querybuildertypesv5/clickhouse_query.go — ClickHouseQuery
|
||||
kind: "SigNozClickHouseSQL"
|
||||
spec: close({
|
||||
name: common.#QueryName
|
||||
query: string & !=""
|
||||
disabled?: bool | *false
|
||||
legend?: string
|
||||
})
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozClickHouseSQL",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"query": "SELECT toStartOfInterval(timestamp, INTERVAL 1 MINUTE) AS ts, count() AS total FROM signoz_logs.distributed_logs GROUP BY ts ORDER BY ts",
|
||||
"disabled": false,
|
||||
"legend": "Log count"
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
bq "github.com/signoz/schemas-wrapper/schemas/signoz-builder-query:model"
|
||||
f "github.com/signoz/schemas-wrapper/schemas/signoz-formula:model"
|
||||
to "github.com/signoz/schemas-wrapper/schemas/signoz-trace-operator:model"
|
||||
pql "github.com/signoz/schemas-wrapper/schemas/signoz-promql:model"
|
||||
ch "github.com/signoz/schemas-wrapper/schemas/signoz-clickhouse-sql:model"
|
||||
)
|
||||
|
||||
// Source: pkg/types/querybuildertypes/querybuildertypesv5/req.go — CompositeQuery
|
||||
// SigNozCompositeQuery groups multiple query plugins into a single
|
||||
// query request. Each entry is a typed envelope whose spec is
|
||||
// validated by the corresponding plugin schema.
|
||||
|
||||
// this is to be used when there are multiple queries in a panel
|
||||
// in most cases, there will be only one query, and there it is a better idea to
|
||||
// use the corresponding kind for that query instead of this composite query
|
||||
kind: "SigNozCompositeQuery"
|
||||
spec: close({
|
||||
queries: [...#QueryEnvelope]
|
||||
})
|
||||
|
||||
// QueryEnvelope wraps a single query plugin with a type discriminator.
|
||||
#QueryEnvelope:
|
||||
close({
|
||||
type: "builder_query",
|
||||
spec: bq.spec
|
||||
}) |
|
||||
close({
|
||||
type: "builder_formula",
|
||||
spec: f.spec
|
||||
}) |
|
||||
close({
|
||||
type: "builder_trace_operator",
|
||||
spec: to.spec
|
||||
}) |
|
||||
close({
|
||||
type: "promql",
|
||||
spec: pql.spec
|
||||
}) |
|
||||
close({
|
||||
type: "clickhouse_sql",
|
||||
spec: ch.spec
|
||||
})
|
||||
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozCompositeQuery",
|
||||
"spec": {
|
||||
"queries": [
|
||||
{
|
||||
"type": "builder_query",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "metrics",
|
||||
"expression": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"metricName": "redis_keyspace_hits",
|
||||
"timeAggregation": "rate",
|
||||
"spaceAggregation": "sum",
|
||||
"reduceTo": "sum"
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "host_name IN $host_name"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "builder_query",
|
||||
"spec": {
|
||||
"name": "B",
|
||||
"signal": "metrics",
|
||||
"expression": "B",
|
||||
"aggregations": [
|
||||
{
|
||||
"metricName": "redis_keyspace_misses",
|
||||
"timeAggregation": "rate",
|
||||
"spaceAggregation": "sum",
|
||||
"reduceTo": "sum"
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "host_name IN $host_name"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "builder_formula",
|
||||
"spec": {
|
||||
"name": "F1",
|
||||
"expression": "A / (A + B) * 100",
|
||||
"legend": "Hit rate %"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
// defaultValue lives on the Perses ListVariable wrapper (spec level).
|
||||
kind: "SigNozCustomVariable"
|
||||
spec: close({
|
||||
customValue: =~"^[^,]+(,[^,]+)*$"
|
||||
sort?: common.#VariableSortOrder
|
||||
})
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozCustomVariable",
|
||||
"spec": {
|
||||
"customValue": "production,staging,development",
|
||||
"sort": "disabled"
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package model
|
||||
|
||||
kind: "SigNozDatasource"
|
||||
|
||||
// SigNoz has a single built-in backend — the frontend already knows
|
||||
// the API endpoint, so there is no connection config to validate.
|
||||
// Add fields here if SigNoz ever supports multiple backends or
|
||||
// configurable API versions.
|
||||
spec: close({})
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozDatasource",
|
||||
"spec": {}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
// defaultValue lives on the Perses ListVariable wrapper (spec level).
|
||||
kind: "SigNozDynamicVariable"
|
||||
spec: close({
|
||||
name: string
|
||||
source: string
|
||||
sort?: common.#VariableSortOrder
|
||||
})
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozDynamicVariable",
|
||||
"spec": {
|
||||
"name": "host_name",
|
||||
"source": "metrics",
|
||||
"sort": "asc"
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package model
|
||||
|
||||
// Fields from IBaseWidget that are NOT in any dedicated panel CUE file.
|
||||
// This file exists as a reference only and will be removed in the end.
|
||||
// Needs to be removed from package.json as well.
|
||||
|
||||
kind: "SigNozIgnoredFieldsChart"
|
||||
spec: close({
|
||||
opacity?: string // not wired to chart rendering
|
||||
nullZeroValues?: string // not wired to chart rendering
|
||||
stepSize?: number
|
||||
columnWidths?: [string]: number // not a config choice — persisted user-resized column widths
|
||||
// "Chart Appearance" section in UI — could not find this section in the app.
|
||||
// These 4 fields are gated behind panelTypeVs* constants (TIME_SERIES only).
|
||||
lineInterpolation?: #LineInterpolation
|
||||
showPoints?: bool
|
||||
lineStyle?: #LineStyle
|
||||
fillMode?: #FillMode
|
||||
})
|
||||
|
||||
#LineInterpolation: "linear" | "spline" | "stepAfter" | "stepBefore"
|
||||
|
||||
#LineStyle: "solid" | "dashed"
|
||||
|
||||
#FillMode: "solid" | "gradient" | "none"
|
||||
@@ -1,17 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
// Source: pkg/types/querybuildertypes/querybuildertypesv5/formula.go — QueryBuilderFormula
|
||||
kind: "SigNozFormula"
|
||||
spec: close({
|
||||
name: common.#QueryName
|
||||
expression: string
|
||||
disabled?: bool | *false
|
||||
legend?: string
|
||||
limit?: common.#Limit
|
||||
having?: common.#HavingExpression
|
||||
stepInterval?: number
|
||||
order?: [...common.#OrderByItem]
|
||||
functions?: [...common.#Function]
|
||||
})
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozFormula",
|
||||
"spec": {
|
||||
"name": "F1",
|
||||
"expression": "A / B * 100",
|
||||
"legend": "Hit rate %"
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozHistogramPanel",
|
||||
"spec": {
|
||||
"histogramBuckets": {
|
||||
"bucketCount": 60,
|
||||
"bucketWidth": 100,
|
||||
"mergeAllActiveQueries": true
|
||||
},
|
||||
"legend": {
|
||||
"customColors": {
|
||||
"series-A": "#9ea5f7"
|
||||
}
|
||||
},
|
||||
"contextLinks": [
|
||||
{
|
||||
"label": "View histogram details",
|
||||
"url": "http://localhost:8080/histogram"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
kind: "SigNozHistogramPanel"
|
||||
spec: close({
|
||||
histogramBuckets?: #HistogramBuckets
|
||||
legend?: #Legend
|
||||
contextLinks?: [...common.#ContextLinkProps]
|
||||
})
|
||||
|
||||
#HistogramBuckets: {
|
||||
bucketCount?: number | *30
|
||||
bucketWidth?: number | *0
|
||||
mergeAllActiveQueries?: bool | *false
|
||||
}
|
||||
|
||||
#Legend: {
|
||||
customColors?: [string]: string
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozListPanel",
|
||||
"spec": {
|
||||
"selectedLogFields": [
|
||||
{
|
||||
"name": "timestamp",
|
||||
"type": "log",
|
||||
"dataType": ""
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"type": "log",
|
||||
"dataType": ""
|
||||
},
|
||||
{
|
||||
"name": "error",
|
||||
"type": "",
|
||||
"dataType": "string"
|
||||
}
|
||||
],
|
||||
"selectedTracesFields": [
|
||||
{
|
||||
"name": "service.name",
|
||||
"signal": "traces",
|
||||
"fieldContext": "resource",
|
||||
"fieldDataType": "string"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"signal": "traces",
|
||||
"fieldContext": "span",
|
||||
"fieldDataType": "string"
|
||||
},
|
||||
{
|
||||
"name": "duration_nano",
|
||||
"signal": "traces",
|
||||
"fieldContext": "span",
|
||||
"fieldDataType": ""
|
||||
},
|
||||
{
|
||||
"name": "http_method",
|
||||
"signal": "traces",
|
||||
"fieldContext": "span",
|
||||
"fieldDataType": ""
|
||||
},
|
||||
{
|
||||
"name": "response_status_code",
|
||||
"signal": "traces",
|
||||
"fieldContext": "span",
|
||||
"fieldDataType": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
kind: "SigNozListPanel"
|
||||
spec: close({
|
||||
selectedLogFields?: [...#LogField]
|
||||
selectedTracesFields?: [...common.#TelemetryFieldKey]
|
||||
})
|
||||
|
||||
#LogField: {
|
||||
name: string
|
||||
type: string
|
||||
dataType: string
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozNumberPanel",
|
||||
"spec": {
|
||||
"visualization": {
|
||||
"timePreference": "globalTime"
|
||||
},
|
||||
"formatting": {
|
||||
"unit": "none",
|
||||
"decimalPrecision": 1
|
||||
},
|
||||
"contextLinks": [
|
||||
{
|
||||
"label": "View details",
|
||||
"url": "http://localhost:8080/details"
|
||||
}
|
||||
],
|
||||
"thresholds": [
|
||||
{
|
||||
"value": 1200000,
|
||||
"operator": ">",
|
||||
"unit": "none",
|
||||
"color": "Red",
|
||||
"format": "Text"
|
||||
},
|
||||
{
|
||||
"value": 1200000,
|
||||
"operator": "<=",
|
||||
"unit": "none",
|
||||
"color": "Green",
|
||||
"format": "Text"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
kind: "SigNozNumberPanel"
|
||||
spec: close({
|
||||
visualization?: #Visualization
|
||||
formatting?: #Formatting
|
||||
contextLinks?: [...common.#ContextLinkProps]
|
||||
thresholds?: [...common.#ComparisonThreshold]
|
||||
})
|
||||
|
||||
#Visualization: {
|
||||
timePreference?: common.#TimePreference
|
||||
}
|
||||
|
||||
#Formatting: {
|
||||
unit?: string | *""
|
||||
decimalPrecision?: common.#PrecisionOption
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozPieChartPanel",
|
||||
"spec": {
|
||||
"visualization": {
|
||||
"timePreference": "globalTime"
|
||||
},
|
||||
"formatting": {
|
||||
"unit": "none",
|
||||
"decimalPrecision": 1
|
||||
},
|
||||
"legend": {
|
||||
"customColors": {
|
||||
"\"201\"": "#2bc051",
|
||||
"\"400\"": "#cc462e",
|
||||
"\"500\"": "#ff0000"
|
||||
}
|
||||
},
|
||||
"contextLinks": [
|
||||
{
|
||||
"label": "View breakdown",
|
||||
"url": "http://localhost:8080/breakdown"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
kind: "SigNozPieChartPanel"
|
||||
spec: close({
|
||||
visualization?: #Visualization
|
||||
formatting?: #Formatting
|
||||
legend?: #Legend
|
||||
contextLinks?: [...common.#ContextLinkProps]
|
||||
})
|
||||
|
||||
#Visualization: {
|
||||
timePreference?: common.#TimePreference
|
||||
}
|
||||
|
||||
#Formatting: {
|
||||
unit?: string | *""
|
||||
decimalPrecision?: common.#PrecisionOption
|
||||
}
|
||||
|
||||
#Legend: {
|
||||
customColors?: [string]: string
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
// Source: pkg/types/querybuildertypes/querybuildertypesv5/prom_query.go — PromQuery
|
||||
kind: "SigNozPromQLQuery"
|
||||
spec: close({
|
||||
name: common.#QueryName
|
||||
query: string & !=""
|
||||
disabled?: bool | *false
|
||||
step?: =~"^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" | number
|
||||
stats?: bool
|
||||
legend?: string
|
||||
})
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozPromQLQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"query": "rate(http_requests_total{status=\"200\"}[5m])",
|
||||
"disabled": false,
|
||||
"legend": "{{method}} {{path}}"
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
// defaultValue lives on the Perses ListVariable wrapper (spec level).
|
||||
kind: "SigNozQueryVariable"
|
||||
spec: close({
|
||||
queryValue: string
|
||||
sort?: common.#VariableSortOrder
|
||||
})
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozQueryVariable",
|
||||
"spec": {
|
||||
"queryValue": "SELECT DISTINCT host_name FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name = 'redis_cpu_time'",
|
||||
"sort": "asc"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozTablePanel",
|
||||
"spec": {
|
||||
"visualization": {
|
||||
"timePreference": "globalTime"
|
||||
},
|
||||
"formatting": {
|
||||
"columnUnits": {
|
||||
"A": "s"
|
||||
},
|
||||
"decimalPrecision": 2
|
||||
},
|
||||
"contextLinks": [
|
||||
{
|
||||
"label": "View trace",
|
||||
"url": "http://localhost:8080/trace/{{traceID}}"
|
||||
}
|
||||
],
|
||||
"thresholds": [
|
||||
{
|
||||
"value": 1,
|
||||
"operator": ">",
|
||||
"unit": "min",
|
||||
"color": "Red",
|
||||
"format": "Text",
|
||||
"tableOptions": "A"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
kind: "SigNozTablePanel"
|
||||
spec: close({
|
||||
visualization?: #Visualization
|
||||
formatting?: #Formatting
|
||||
contextLinks?: [...common.#ContextLinkProps]
|
||||
thresholds?: [...#TableThreshold]
|
||||
})
|
||||
|
||||
#Visualization: {
|
||||
timePreference?: common.#TimePreference
|
||||
}
|
||||
|
||||
#Formatting: {
|
||||
columnUnits?: [string]: string
|
||||
decimalPrecision?: common.#PrecisionOption
|
||||
}
|
||||
|
||||
#TableThreshold: {
|
||||
common.#ComparisonThreshold
|
||||
tableOptions: string
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozTimeSeriesPanel",
|
||||
"spec": {
|
||||
"visualization": {
|
||||
"timePreference": "globalTime",
|
||||
"fillSpans": true
|
||||
},
|
||||
"formatting": {
|
||||
"unit": "By",
|
||||
"decimalPrecision": 3
|
||||
},
|
||||
"axes": {
|
||||
"softMin": 0,
|
||||
"softMax": 800,
|
||||
"isLogScale": true
|
||||
},
|
||||
"legend": {
|
||||
"position": "right",
|
||||
"customColors": {
|
||||
"{service.name=\"sampleapp-gateway\"}": "#9ea5f7"
|
||||
}
|
||||
},
|
||||
"contextLinks": [
|
||||
{
|
||||
"label": "View service details",
|
||||
"url": "http://localhost:8080/{{_service.name}}?dfddf=%7B%7Blimit%7D%7D"
|
||||
}
|
||||
],
|
||||
"thresholds": [
|
||||
{
|
||||
"value": 1024,
|
||||
"unit": "By",
|
||||
"color": "Red",
|
||||
"format": "Text",
|
||||
"label": "upper limit"
|
||||
},
|
||||
{
|
||||
"value": 100,
|
||||
"unit": "By",
|
||||
"color": "Orange",
|
||||
"format": "Text",
|
||||
"label": "kinda bad"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
kind: "SigNozTimeSeriesPanel"
|
||||
spec: close({
|
||||
visualization?: #Visualization
|
||||
formatting?: #Formatting
|
||||
axes?: common.#Axes
|
||||
legend?: #Legend
|
||||
contextLinks?: [...common.#ContextLinkProps]
|
||||
thresholds?: [...common.#ThresholdWithLabel]
|
||||
})
|
||||
|
||||
#Visualization: {
|
||||
timePreference?: common.#TimePreference
|
||||
fillSpans?: bool | *false
|
||||
}
|
||||
|
||||
#Formatting: {
|
||||
unit?: string | *""
|
||||
decimalPrecision?: common.#PrecisionOption
|
||||
}
|
||||
|
||||
#Legend: {
|
||||
position?: common.#LegendPosition
|
||||
customColors?: [string]: string
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
// Source: pkg/types/querybuildertypes/querybuildertypesv5/trace_operator.go — QueryBuilderTraceOperator
|
||||
// SigNozTraceOperator composes multiple trace BuilderQueries using
|
||||
// relational operators (=>, ->, &&, ||, NOT) to query trace relationships.
|
||||
// Signal is implicitly "traces" — all referenced queries must be trace queries.
|
||||
kind: "SigNozTraceOperator"
|
||||
spec: close({
|
||||
name: common.#QueryName
|
||||
// Operator expression composing trace queries, e.g. "A => B && C".
|
||||
expression: string & !=""
|
||||
disabled?: bool | *false
|
||||
|
||||
// Which query's spans to return (must be a query referenced in expression).
|
||||
returnSpansFrom?: common.#QueryName
|
||||
|
||||
aggregations?: [...common.#ExpressionAggregation]
|
||||
filter?: common.#FilterExpression
|
||||
groupBy?: [...common.#GroupByItem]
|
||||
order?: [...common.#OrderByItem]
|
||||
limit?: common.#Limit
|
||||
offset?: common.#Offset
|
||||
cursor?: string
|
||||
functions?: [...common.#Function]
|
||||
stepInterval?: number
|
||||
having?: common.#HavingExpression
|
||||
legend?: string
|
||||
selectFields?: [...common.#TelemetryFieldKey]
|
||||
})
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"kind": "SigNozTraceOperator",
|
||||
"spec": {
|
||||
"name": "T1",
|
||||
"expression": "A => B",
|
||||
"returnSpansFrom": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"expression": "count()",
|
||||
"alias": "request_count"
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "service.name = 'frontend'"
|
||||
},
|
||||
"groupBy": [],
|
||||
"order": []
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
percli lint -f ./examples/perses.json --plugin.path ./schemas-wrapper
|
||||
rm ./schemas-wrapper/plugin-modules.json
|
||||
@@ -3,6 +3,7 @@ package prometheus
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
)
|
||||
|
||||
@@ -20,6 +21,9 @@ type Config struct {
|
||||
//
|
||||
// If not set, the prometheus default is used (currently 5m).
|
||||
LookbackDelta time.Duration `mapstructure:"lookback_delta"`
|
||||
|
||||
// Timeout is the maximum time a query is allowed to run before being aborted.
|
||||
Timeout time.Duration `mapstructure:"timeout"`
|
||||
}
|
||||
|
||||
func NewConfigFactory() factory.ConfigFactory {
|
||||
@@ -33,10 +37,14 @@ func newConfig() factory.Config {
|
||||
Path: "",
|
||||
MaxConcurrent: 20,
|
||||
},
|
||||
Timeout: 2 * time.Minute,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Config) Validate() error {
|
||||
if c.Timeout <= 0 {
|
||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "prometheus::timeout must be greater than 0")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
package prometheus
|
||||
|
||||
const FingerprintAsPromLabelName = "fingerprint"
|
||||
@@ -2,7 +2,6 @@ package prometheus
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
)
|
||||
@@ -21,7 +20,7 @@ func NewEngine(logger *slog.Logger, cfg Config) *Engine {
|
||||
Logger: logger,
|
||||
Reg: nil,
|
||||
MaxSamples: 5_0000_000,
|
||||
Timeout: 2 * time.Minute,
|
||||
Timeout: cfg.Timeout,
|
||||
ActiveQueryTracker: activeQueryTracker,
|
||||
LookbackDelta: cfg.LookbackDelta,
|
||||
})
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
)
|
||||
|
||||
const FingerprintAsPromLabelName string = "fingerprint"
|
||||
|
||||
func RemoveExtraLabels(res *promql.Result, labelsToRemove ...string) error {
|
||||
if len(labelsToRemove) == 0 || res == nil {
|
||||
return nil
|
||||
@@ -36,6 +36,28 @@ var unquotedDottedNamePattern = regexp.MustCompile(`(?:^|[{,(\s])([a-zA-Z_][a-zA
|
||||
// This is a common mistake when migrating to UTF-8 syntax.
|
||||
var quotedMetricOutsideBracesPattern = regexp.MustCompile(`"([^"]+)"\s*\{`)
|
||||
|
||||
// tryEnhancePromQLExecError attempts to convert a PromQL execution error into
|
||||
// a properly typed error. Returns nil if the error is not a recognized execution error.
|
||||
func tryEnhancePromQLExecError(execErr error) error {
|
||||
var eqc promql.ErrQueryCanceled
|
||||
var eqt promql.ErrQueryTimeout
|
||||
var es promql.ErrStorage
|
||||
switch {
|
||||
case errors.As(execErr, &eqc):
|
||||
return errors.Newf(errors.TypeCanceled, errors.CodeCanceled, "query canceled").WithAdditional(eqc.Error())
|
||||
case errors.As(execErr, &eqt):
|
||||
return errors.Newf(errors.TypeTimeout, errors.CodeTimeout, "query timed out").WithAdditional(eqt.Error())
|
||||
case errors.Is(execErr, context.DeadlineExceeded):
|
||||
return errors.Newf(errors.TypeTimeout, errors.CodeTimeout, "query timed out")
|
||||
case errors.Is(execErr, context.Canceled):
|
||||
return errors.Newf(errors.TypeCanceled, errors.CodeCanceled, "query canceled")
|
||||
case errors.As(execErr, &es):
|
||||
return errors.Newf(errors.TypeInternal, errors.CodeInternal, "query execution error: %v", execErr)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// enhancePromQLError adds helpful context to PromQL parse errors,
|
||||
// particularly for UTF-8 syntax migration issues where metric and label
|
||||
// names containing dots need to be quoted.
|
||||
@@ -213,27 +235,20 @@ func (q *promqlQuery) Execute(ctx context.Context) (*qbv5.Result, error) {
|
||||
time.Unix(0, end),
|
||||
q.query.Step.Duration,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
// NewRangeQuery can fail with execution errors (e.g. context deadline exceeded)
|
||||
// during the query queue/scheduling stage, not just parse errors.
|
||||
if err := tryEnhancePromQLExecError(err); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, enhancePromQLError(query, err)
|
||||
}
|
||||
|
||||
res := qry.Exec(ctx)
|
||||
if res.Err != nil {
|
||||
var eqc promql.ErrQueryCanceled
|
||||
var eqt promql.ErrQueryTimeout
|
||||
var es promql.ErrStorage
|
||||
switch {
|
||||
case errors.As(res.Err, &eqc):
|
||||
return nil, errors.Newf(errors.TypeCanceled, errors.CodeCanceled, "query canceled")
|
||||
case errors.As(res.Err, &eqt):
|
||||
return nil, errors.Newf(errors.TypeTimeout, errors.CodeTimeout, "query timeout")
|
||||
case errors.As(res.Err, &es):
|
||||
return nil, errors.Newf(errors.TypeInternal, errors.CodeInternal, "query execution error: %v", res.Err)
|
||||
}
|
||||
|
||||
if errors.Is(res.Err, context.Canceled) {
|
||||
return nil, errors.Newf(errors.TypeCanceled, errors.CodeCanceled, "query canceled")
|
||||
if err := tryEnhancePromQLExecError(res.Err); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, errors.Newf(errors.TypeInternal, errors.CodeInternal, "query execution error: %v", res.Err)
|
||||
|
||||
@@ -1407,7 +1407,7 @@ func Test_querier_Traces_runWindowBasedListQueryDesc(t *testing.T) {
|
||||
slog.Default(),
|
||||
nil,
|
||||
telemetryStore,
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore),
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore),
|
||||
"",
|
||||
time.Duration(time.Second),
|
||||
nil,
|
||||
@@ -1633,7 +1633,7 @@ func Test_querier_Traces_runWindowBasedListQueryAsc(t *testing.T) {
|
||||
slog.Default(),
|
||||
nil,
|
||||
telemetryStore,
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore),
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore),
|
||||
"",
|
||||
time.Duration(time.Second),
|
||||
nil,
|
||||
@@ -1934,7 +1934,7 @@ func Test_querier_Logs_runWindowBasedListQueryDesc(t *testing.T) {
|
||||
slog.Default(),
|
||||
nil,
|
||||
telemetryStore,
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore),
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore),
|
||||
"",
|
||||
time.Duration(time.Second),
|
||||
nil,
|
||||
@@ -2162,7 +2162,7 @@ func Test_querier_Logs_runWindowBasedListQueryAsc(t *testing.T) {
|
||||
slog.Default(),
|
||||
nil,
|
||||
telemetryStore,
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore),
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore),
|
||||
"",
|
||||
time.Duration(time.Second),
|
||||
nil,
|
||||
|
||||
@@ -1459,7 +1459,7 @@ func Test_querier_Traces_runWindowBasedListQueryDesc(t *testing.T) {
|
||||
slog.Default(),
|
||||
nil,
|
||||
telemetryStore,
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore),
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore),
|
||||
"",
|
||||
time.Duration(time.Second),
|
||||
nil,
|
||||
@@ -1685,7 +1685,7 @@ func Test_querier_Traces_runWindowBasedListQueryAsc(t *testing.T) {
|
||||
slog.Default(),
|
||||
nil,
|
||||
telemetryStore,
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore),
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore),
|
||||
"",
|
||||
time.Duration(time.Second),
|
||||
nil,
|
||||
@@ -1985,7 +1985,7 @@ func Test_querier_Logs_runWindowBasedListQueryDesc(t *testing.T) {
|
||||
slog.Default(),
|
||||
nil,
|
||||
telemetryStore,
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore),
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore),
|
||||
"",
|
||||
time.Duration(time.Second),
|
||||
nil,
|
||||
@@ -2213,7 +2213,7 @@ func Test_querier_Logs_runWindowBasedListQueryAsc(t *testing.T) {
|
||||
slog.Default(),
|
||||
nil,
|
||||
telemetryStore,
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore),
|
||||
prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore),
|
||||
"",
|
||||
time.Duration(time.Second),
|
||||
nil,
|
||||
|
||||
@@ -698,7 +698,7 @@ func TestBaseRule_FilterNewSeries(t *testing.T) {
|
||||
slog.Default(),
|
||||
nil,
|
||||
telemetryStore,
|
||||
prometheustest.New(context.Background(), settings, prometheus.Config{}, telemetryStore),
|
||||
prometheustest.New(context.Background(), settings, prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore),
|
||||
"",
|
||||
time.Second,
|
||||
nil,
|
||||
|
||||
@@ -253,7 +253,7 @@ func TestManager_TestNotification_SendUnmatched_PromRule(t *testing.T) {
|
||||
WillReturnRows(samplesRows)
|
||||
|
||||
// Create Prometheus provider for this test
|
||||
promProvider = prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, store)
|
||||
promProvider = prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, store)
|
||||
},
|
||||
ManagerOptionsHook: func(opts *ManagerOptions) {
|
||||
// Set Prometheus provider for PromQL queries
|
||||
|
||||
@@ -99,7 +99,7 @@ func NewTestManager(t *testing.T, testOpts *TestManagerOptions) *Manager {
|
||||
|
||||
options := clickhouseReader.NewOptions("", "", "archiveNamespace")
|
||||
providerSettings := instrumentationtest.New().ToProviderSettings()
|
||||
prometheus := prometheustest.New(context.Background(), providerSettings, prometheus.Config{}, telemetryStore)
|
||||
prometheus := prometheustest.New(context.Background(), providerSettings, prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore)
|
||||
reader := clickhouseReader.NewReader(
|
||||
instrumentationtest.New().Logger(),
|
||||
nil,
|
||||
|
||||
@@ -940,7 +940,7 @@ func TestPromRuleUnitCombinations(t *testing.T) {
|
||||
).
|
||||
WillReturnRows(samplesRows)
|
||||
|
||||
promProvider := prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore)
|
||||
promProvider := prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore)
|
||||
|
||||
postableRule.RuleCondition.CompareOp = ruletypes.CompareOp(c.compareOp)
|
||||
postableRule.RuleCondition.MatchType = ruletypes.MatchType(c.matchType)
|
||||
@@ -1061,7 +1061,7 @@ func _Enable_this_after_9146_issue_fix_is_merged_TestPromRuleNoData(t *testing.T
|
||||
WithArgs("test_metric", "__name__", "test_metric").
|
||||
WillReturnRows(fingerprintRows)
|
||||
|
||||
promProvider := prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore)
|
||||
promProvider := prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore)
|
||||
|
||||
var target float64 = 0
|
||||
postableRule.RuleCondition.Thresholds = &ruletypes.RuleThresholdData{
|
||||
@@ -1281,7 +1281,7 @@ func TestMultipleThresholdPromRule(t *testing.T) {
|
||||
).
|
||||
WillReturnRows(samplesRows)
|
||||
|
||||
promProvider := prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore)
|
||||
promProvider := prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore)
|
||||
|
||||
postableRule.RuleCondition.CompareOp = ruletypes.CompareOp(c.compareOp)
|
||||
postableRule.RuleCondition.MatchType = ruletypes.MatchType(c.matchType)
|
||||
@@ -1441,7 +1441,7 @@ func TestPromRule_NoData(t *testing.T) {
|
||||
promProvider := prometheustest.New(
|
||||
context.Background(),
|
||||
instrumentationtest.New().ToProviderSettings(),
|
||||
prometheus.Config{},
|
||||
prometheus.Config{Timeout: 2 * time.Minute},
|
||||
telemetryStore,
|
||||
)
|
||||
defer func() {
|
||||
@@ -1590,7 +1590,7 @@ func TestPromRule_NoData_AbsentFor(t *testing.T) {
|
||||
promProvider := prometheustest.New(
|
||||
context.Background(),
|
||||
instrumentationtest.New().ToProviderSettings(),
|
||||
prometheus.Config{},
|
||||
prometheus.Config{Timeout: 2 * time.Minute},
|
||||
telemetryStore,
|
||||
)
|
||||
defer func() {
|
||||
@@ -1748,7 +1748,7 @@ func TestPromRuleEval_RequireMinPoints(t *testing.T) {
|
||||
promProvider := prometheustest.New(
|
||||
context.Background(),
|
||||
instrumentationtest.New().ToProviderSettings(),
|
||||
prometheus.Config{LookbackDelta: lookBackDelta},
|
||||
prometheus.Config{Timeout: 2 * time.Minute, LookbackDelta: lookBackDelta},
|
||||
telemetryStore,
|
||||
)
|
||||
defer func() {
|
||||
|
||||
@@ -779,7 +779,7 @@ func TestThresholdRuleUnitCombinations(t *testing.T) {
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore), "", time.Duration(time.Second), nil, readerCache, options)
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore), "", time.Duration(time.Second), nil, readerCache, options)
|
||||
rule, err := NewThresholdRule("69", valuer.GenerateUUID(), &postableRule, reader, nil, logger)
|
||||
rule.TemporalityMap = map[string]map[v3.Temporality]bool{
|
||||
"signoz_calls_total": {
|
||||
@@ -894,7 +894,7 @@ func TestThresholdRuleNoData(t *testing.T) {
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
options := clickhouseReader.NewOptions("", "", "archiveNamespace")
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore), "", time.Duration(time.Second), nil, readerCache, options)
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore), "", time.Duration(time.Second), nil, readerCache, options)
|
||||
|
||||
rule, err := NewThresholdRule("69", valuer.GenerateUUID(), &postableRule, reader, nil, logger)
|
||||
rule.TemporalityMap = map[string]map[v3.Temporality]bool{
|
||||
@@ -1014,7 +1014,7 @@ func TestThresholdRuleTracesLink(t *testing.T) {
|
||||
}
|
||||
|
||||
options := clickhouseReader.NewOptions("", "", "archiveNamespace")
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore), "", time.Duration(time.Second), nil, nil, options)
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore), "", time.Duration(time.Second), nil, nil, options)
|
||||
|
||||
rule, err := NewThresholdRule("69", valuer.GenerateUUID(), &postableRule, reader, nil, logger)
|
||||
rule.TemporalityMap = map[string]map[v3.Temporality]bool{
|
||||
@@ -1151,7 +1151,7 @@ func TestThresholdRuleLogsLink(t *testing.T) {
|
||||
}
|
||||
|
||||
options := clickhouseReader.NewOptions("", "", "archiveNamespace")
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore), "", time.Duration(time.Second), nil, nil, options)
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore), "", time.Duration(time.Second), nil, nil, options)
|
||||
|
||||
rule, err := NewThresholdRule("69", valuer.GenerateUUID(), &postableRule, reader, nil, logger)
|
||||
rule.TemporalityMap = map[string]map[v3.Temporality]bool{
|
||||
@@ -1418,7 +1418,7 @@ func TestMultipleThresholdRule(t *testing.T) {
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore), "", time.Second, nil, readerCache, options)
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore), "", time.Second, nil, readerCache, options)
|
||||
rule, err := NewThresholdRule("69", valuer.GenerateUUID(), &postableRule, reader, nil, logger)
|
||||
rule.TemporalityMap = map[string]map[v3.Temporality]bool{
|
||||
"signoz_calls_total": {
|
||||
@@ -2220,7 +2220,7 @@ func TestThresholdEval_RequireMinPoints(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
prometheusProvider := prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{}, telemetryStore)
|
||||
prometheusProvider := prometheustest.New(context.Background(), instrumentationtest.New().ToProviderSettings(), prometheus.Config{Timeout: 2 * time.Minute}, telemetryStore)
|
||||
reader := clickhouseReader.NewReader(slog.Default(), nil, telemetryStore, prometheusProvider, "", time.Second, nil, readerCache, options)
|
||||
|
||||
rule, err := NewThresholdRule("some-id", valuer.GenerateUUID(), &postableRule, reader, nil, logger)
|
||||
|
||||
Reference in New Issue
Block a user