mirror of
https://github.com/SigNoz/signoz.git
synced 2026-03-24 13:20:27 +00:00
Compare commits
61 Commits
refactor/c
...
nv/4172
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3980e084c | ||
|
|
4319dd9cef | ||
|
|
92a5e9b9c9 | ||
|
|
408a914129 | ||
|
|
0e304b1d40 | ||
|
|
58a9be24d3 | ||
|
|
adf439fcf1 | ||
|
|
a1a54c4bb2 | ||
|
|
3c1961d3fc | ||
|
|
c3efa0660b | ||
|
|
183dd09082 | ||
|
|
a351373c49 | ||
|
|
8e7653b90d | ||
|
|
5c40d6b68b | ||
|
|
31115df41c | ||
|
|
869c3dccb2 | ||
|
|
c5d7a7ef8c | ||
|
|
544b87b254 | ||
|
|
e885fb98e5 | ||
|
|
be227eec43 | ||
|
|
13263c1f25 | ||
|
|
ccbf410d15 | ||
|
|
03b98ff824 | ||
|
|
2cdba0d11c | ||
|
|
84d2885530 | ||
|
|
b82dcc6138 | ||
|
|
a14d5847b9 | ||
|
|
d184746142 | ||
|
|
c335e17e1d | ||
|
|
433dd0b2d0 | ||
|
|
05e97e246a | ||
|
|
bddfe30f6c | ||
|
|
7a01a5250d | ||
|
|
09c98c830d | ||
|
|
0fbb90cc91 | ||
|
|
15f0787610 | ||
|
|
22ebc7732c | ||
|
|
cff18edf6e | ||
|
|
cb49c0bf3b | ||
|
|
1cb6f94d21 | ||
|
|
68155f374b | ||
|
|
696524509f | ||
|
|
705cdab38c | ||
|
|
ae9b881413 | ||
|
|
05f4e15d07 | ||
|
|
1653c6d725 | ||
|
|
070b4b7061 | ||
|
|
7f4c06edd6 | ||
|
|
6bed20b5b9 | ||
|
|
033bd3c9b8 | ||
|
|
d4c9a923fd | ||
|
|
387dcb529f | ||
|
|
7a4da7bcc5 | ||
|
|
b152fae3fa | ||
|
|
2ed766726c | ||
|
|
8767f6a57d | ||
|
|
22d8c7599b | ||
|
|
1019264272 | ||
|
|
c950d7e784 | ||
|
|
1e279e6193 | ||
|
|
d3a278c43e |
115
perses/common/common.cue
Normal file
115
perses/common/common.cue
Normal file
@@ -0,0 +1,115 @@
|
||||
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"
|
||||
4
perses/cue.mod/module.cue
Normal file
4
perses/cue.mod/module.cue
Normal file
@@ -0,0 +1,4 @@
|
||||
module: "github.com/signoz"
|
||||
language: {
|
||||
version: "v0.12.0"
|
||||
}
|
||||
2117
perses/examples/current.json
Normal file
2117
perses/examples/current.json
Normal file
File diff suppressed because it is too large
Load Diff
868
perses/examples/perses.json
Normal file
868
perses/examples/perses.json
Normal file
@@ -0,0 +1,868 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
140
perses/howToDefineAPanel.md
Normal file
140
perses/howToDefineAPanel.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# 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 | — | — |
|
||||
9
perses/schemas-wrapper/schemas/mf-manifest.json
Normal file
9
perses/schemas-wrapper/schemas/mf-manifest.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "signoz",
|
||||
"name": "signoz",
|
||||
"metaData": {
|
||||
"buildInfo": {
|
||||
"buildVersion": "0.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
130
perses/schemas-wrapper/schemas/package.json
Normal file
130
perses/schemas-wrapper/schemas/package.json
Normal file
@@ -0,0 +1,130 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
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
|
||||
})
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
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
|
||||
})
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
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
|
||||
})
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"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 %"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
// defaultValue lives on the Perses ListVariable wrapper (spec level).
|
||||
kind: "SigNozCustomVariable"
|
||||
spec: close({
|
||||
customValue: =~"^[^,]+(,[^,]+)*$"
|
||||
sort?: common.#VariableSortOrder
|
||||
})
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"kind": "SigNozCustomVariable",
|
||||
"spec": {
|
||||
"customValue": "production,staging,development",
|
||||
"sort": "disabled"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
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({})
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"kind": "SigNozDatasource",
|
||||
"spec": {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
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
|
||||
})
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"kind": "SigNozDynamicVariable",
|
||||
"spec": {
|
||||
"name": "host_name",
|
||||
"source": "metrics",
|
||||
"sort": "asc"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
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"
|
||||
@@ -0,0 +1,17 @@
|
||||
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]
|
||||
})
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"kind": "SigNozFormula",
|
||||
"spec": {
|
||||
"name": "F1",
|
||||
"expression": "A / B * 100",
|
||||
"legend": "Hit rate %"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"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": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package model
|
||||
|
||||
import "github.com/signoz/common"
|
||||
|
||||
kind: "SigNozListPanel"
|
||||
spec: close({
|
||||
selectedLogFields?: [...#LogField]
|
||||
selectedTracesFields?: [...common.#TelemetryFieldKey]
|
||||
})
|
||||
|
||||
#LogField: {
|
||||
name: string
|
||||
type: string
|
||||
dataType: string
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
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
|
||||
})
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"kind": "SigNozPromQLQuery",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"query": "rate(http_requests_total{status=\"200\"}[5m])",
|
||||
"disabled": false,
|
||||
"legend": "{{method}} {{path}}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
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
|
||||
})
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"kind": "SigNozQueryVariable",
|
||||
"spec": {
|
||||
"queryValue": "SELECT DISTINCT host_name FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name = 'redis_cpu_time'",
|
||||
"sort": "asc"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
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]
|
||||
})
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"kind": "SigNozTraceOperator",
|
||||
"spec": {
|
||||
"name": "T1",
|
||||
"expression": "A => B",
|
||||
"returnSpansFrom": "A",
|
||||
"aggregations": [
|
||||
{
|
||||
"expression": "count()",
|
||||
"alias": "request_count"
|
||||
}
|
||||
],
|
||||
"filter": {
|
||||
"expression": "service.name = 'frontend'"
|
||||
},
|
||||
"groupBy": [],
|
||||
"order": []
|
||||
}
|
||||
}
|
||||
2
perses/validate.sh
Executable file
2
perses/validate.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
percli lint -f ./examples/perses.json --plugin.path ./schemas-wrapper
|
||||
rm ./schemas-wrapper/plugin-modules.json
|
||||
Reference in New Issue
Block a user