2023-05-09 19:16:55 +05:30
package queryBuilder
2023-03-23 19:45:15 +05:30
import (
"strings"
"testing"
2025-03-20 21:01:41 +05:30
logsV3 "github.com/SigNoz/signoz/pkg/query-service/app/logs/v3"
logsV4 "github.com/SigNoz/signoz/pkg/query-service/app/logs/v4"
metricsv3 "github.com/SigNoz/signoz/pkg/query-service/app/metrics/v3"
"github.com/SigNoz/signoz/pkg/query-service/constants"
"github.com/SigNoz/signoz/pkg/query-service/featureManager"
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
2023-03-23 19:45:15 +05:30
"github.com/stretchr/testify/require"
)
func TestBuildQueryWithMultipleQueriesAndFormula ( t * testing . T ) {
t . Run ( "TestBuildQueryWithFilters" , func ( t * testing . T ) {
q := & v3 . QueryRangeParamsV3 {
Start : 1650991982000 ,
End : 1651078382000 ,
CompositeQuery : & v3 . CompositeQuery {
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
2023-08-22 17:09:58 +05:30
StepInterval : 60 ,
2023-03-23 19:45:15 +05:30
DataSource : v3 . DataSourceMetrics ,
AggregateAttribute : v3 . AttributeKey { Key : "name" } ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
2023-04-07 09:46:21 +05:30
{ Key : v3 . AttributeKey { Key : "in" } , Value : [ ] interface { } { "a" , "b" , "c" } , Operator : v3 . FilterOperatorIn } ,
2023-03-23 19:45:15 +05:30
} } ,
AggregateOperator : v3 . AggregateOperatorRateMax ,
2024-05-21 12:01:21 +05:30
Temporality : v3 . Cumulative ,
2023-03-23 19:45:15 +05:30
Expression : "A" ,
} ,
"B" : {
2023-05-12 16:25:22 +05:30
QueryName : "B" ,
2023-08-22 17:09:58 +05:30
StepInterval : 60 ,
2023-03-23 19:45:15 +05:30
AggregateAttribute : v3 . AttributeKey { Key : "name2" } ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorRateAvg ,
2024-05-21 12:01:21 +05:30
Temporality : v3 . Cumulative ,
2023-03-23 19:45:15 +05:30
Expression : "B" ,
} ,
"C" : {
QueryName : "C" ,
Expression : "A/B" ,
} ,
} ,
} ,
}
2023-05-09 19:16:55 +05:30
qbOptions := QueryBuilderOptions {
2023-03-23 19:45:15 +05:30
BuildMetricQuery : metricsv3 . PrepareMetricQuery ,
}
2023-08-18 07:32:05 +05:30
fm := featureManager . StartManager ( )
qb := NewQueryBuilder ( qbOptions , fm )
2023-03-23 19:45:15 +05:30
2023-05-09 19:16:55 +05:30
queries , err := qb . PrepareQueries ( q )
2023-03-23 19:45:15 +05:30
require . NoError ( t , err )
2023-12-21 12:11:35 +05:30
require . Contains ( t , queries [ "C" ] , "SELECT A.`ts` as `ts`, A.value / B.value" )
2025-03-03 14:04:16 +05:30
require . Contains ( t , queries [ "C" ] , "WHERE metric_name IN ['name'] AND temporality = 'Cumulative' AND __normalized = true AND unix_milli >= 1650931200000 AND unix_milli < 1651078380000 AND JSONExtractString(labels, 'in') IN ['a','b','c']" )
2023-11-28 19:16:08 +05:30
require . Contains ( t , queries [ "C" ] , "(value - lagInFrame(value, 1, 0) OVER rate_window) / (ts - lagInFrame(ts, 1, toDate('1970-01-01')) OVER rate_window)))" )
2023-03-23 19:45:15 +05:30
} )
}
func TestBuildQueryWithIncorrectQueryRef ( t * testing . T ) {
t . Run ( "TestBuildQueryWithFilters" , func ( t * testing . T ) {
q := & v3 . QueryRangeParamsV3 {
Start : 1650991982000 ,
End : 1651078382000 ,
CompositeQuery : & v3 . CompositeQuery {
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
2023-08-22 17:09:58 +05:30
StepInterval : 60 ,
2023-03-23 19:45:15 +05:30
DataSource : v3 . DataSourceMetrics ,
AggregateAttribute : v3 . AttributeKey { Key : "name" } ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
2023-04-07 09:46:21 +05:30
{ Key : v3 . AttributeKey { Key : "in" } , Value : [ ] interface { } { "a" , "b" , "c" } , Operator : v3 . FilterOperatorIn } ,
2023-03-23 19:45:15 +05:30
} } ,
AggregateOperator : v3 . AggregateOperatorRateMax ,
Expression : "A" ,
} ,
"C" : {
QueryName : "C" ,
Expression : "A*2" ,
} ,
} ,
} ,
}
2023-05-09 19:16:55 +05:30
qbOptions := QueryBuilderOptions {
2023-03-23 19:45:15 +05:30
BuildMetricQuery : metricsv3 . PrepareMetricQuery ,
}
2023-08-18 07:32:05 +05:30
fm := featureManager . StartManager ( )
qb := NewQueryBuilder ( qbOptions , fm )
2023-03-23 19:45:15 +05:30
2023-05-09 19:16:55 +05:30
_ , err := qb . PrepareQueries ( q )
2023-03-23 19:45:15 +05:30
require . NoError ( t , err )
} )
}
func TestBuildQueryWithThreeOrMoreQueriesRefAndFormula ( t * testing . T ) {
t . Run ( "TestBuildQueryWithFilters" , func ( t * testing . T ) {
q := & v3 . QueryRangeParamsV3 {
Start : 1650991982000 ,
End : 1651078382000 ,
CompositeQuery : & v3 . CompositeQuery {
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
2023-08-22 17:09:58 +05:30
StepInterval : 60 ,
2023-03-23 19:45:15 +05:30
DataSource : v3 . DataSourceMetrics ,
AggregateAttribute : v3 . AttributeKey { Key : "name" } ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
2023-04-07 09:46:21 +05:30
{ Key : v3 . AttributeKey { Key : "in" } , Value : [ ] interface { } { "a" , "b" , "c" } , Operator : v3 . FilterOperatorIn } ,
2023-03-23 19:45:15 +05:30
} } ,
AggregateOperator : v3 . AggregateOperatorRateMax ,
Expression : "A" ,
Disabled : true ,
} ,
"B" : {
2023-05-12 16:25:22 +05:30
QueryName : "B" ,
2023-08-22 17:09:58 +05:30
StepInterval : 60 ,
2023-03-23 19:45:15 +05:30
AggregateAttribute : v3 . AttributeKey { Key : "name2" } ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorRateMax ,
Expression : "B" ,
Disabled : true ,
} ,
"C" : {
2023-05-12 16:25:22 +05:30
QueryName : "C" ,
2023-08-22 17:09:58 +05:30
StepInterval : 60 ,
2023-03-23 19:45:15 +05:30
AggregateAttribute : v3 . AttributeKey { Key : "name3" } ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
Expression : "C" ,
Disabled : true ,
} ,
"F1" : {
QueryName : "F1" ,
Expression : "A/B" ,
} ,
"F2" : {
QueryName : "F2" ,
Expression : "A/(B+C)" ,
} ,
"F3" : {
QueryName : "F3" ,
Expression : "A*A" ,
} ,
"F4" : {
QueryName : "F4" ,
Expression : "A*B*C" ,
} ,
"F5" : {
QueryName : "F5" ,
Expression : "((A - B) / B) * 100" ,
} ,
} ,
} ,
}
2023-05-09 19:16:55 +05:30
qbOptions := QueryBuilderOptions {
2023-03-23 19:45:15 +05:30
BuildMetricQuery : metricsv3 . PrepareMetricQuery ,
}
2023-08-18 07:32:05 +05:30
fm := featureManager . StartManager ( )
qb := NewQueryBuilder ( qbOptions , fm )
2023-03-23 19:45:15 +05:30
2023-05-09 19:16:55 +05:30
queries , err := qb . PrepareQueries ( q )
2023-03-23 19:45:15 +05:30
require . NoError ( t , err )
2023-12-21 12:11:35 +05:30
require . Contains ( t , queries [ "F1" ] , "SELECT A.`ts` as `ts`, A.value / B.value" )
2023-03-23 19:45:15 +05:30
require . Equal ( t , 1 , strings . Count ( queries [ "F1" ] , " ON " ) )
2023-12-21 12:11:35 +05:30
require . Contains ( t , queries [ "F2" ] , "SELECT A.`ts` as `ts`, A.value / (B.value + C.value)" )
2023-03-23 19:45:15 +05:30
require . Equal ( t , 2 , strings . Count ( queries [ "F2" ] , " ON " ) )
// Working with same query multiple times should not join on itself
require . NotContains ( t , queries [ "F3" ] , " ON " )
2023-12-21 12:11:35 +05:30
require . Contains ( t , queries [ "F4" ] , "SELECT A.`ts` as `ts`, A.value * B.value * C.value" )
2023-03-23 19:45:15 +05:30
require . Equal ( t , 2 , strings . Count ( queries [ "F4" ] , " ON " ) )
2023-12-21 12:11:35 +05:30
require . Contains ( t , queries [ "F5" ] , "SELECT A.`ts` as `ts`, ((A.value - B.value) / B.value) * 100" )
2023-03-23 19:45:15 +05:30
require . Equal ( t , 1 , strings . Count ( queries [ "F5" ] , " ON " ) )
2023-05-12 16:25:22 +05:30
for _ , query := range q . CompositeQuery . BuilderQueries {
if query . Disabled {
require . NotContains ( t , queries , query . QueryName )
}
}
2023-03-23 19:45:15 +05:30
// res := PrepareBuilderMetricQueries(q, "table")
// So(res.Err, ShouldBeNil)
// queries := res.Queries
// So(len(queries), ShouldEqual, 5)
// So(queries["F1"], ShouldContainSubstring, "SELECT A.ts as ts, A.value / B.value")
// So(strings.Count(queries["F1"], " ON "), ShouldEqual, 1)
// So(queries["F2"], ShouldContainSubstring, "SELECT A.ts as ts, A.value / (B.value + C.value)")
// So(strings.Count(queries["F2"], " ON "), ShouldEqual, 2)
// // Working with same query multiple times should not join on itself
// So(queries["F3"], ShouldNotContainSubstring, " ON ")
// So(queries["F4"], ShouldContainSubstring, "SELECT A.ts as ts, A.value * B.value * C.value")
// // Number of times JOIN ON appears is N-1 where N is number of unique queries
// So(strings.Count(queries["F4"], " ON "), ShouldEqual, 2)
// So(queries["F5"], ShouldContainSubstring, "SELECT A.ts as ts, ((A.value - B.value) / B.value) * 100")
// So(strings.Count(queries["F5"], " ON "), ShouldEqual, 1)
} )
2025-01-03 10:52:55 +05:30
t . Run ( "TestBuildQueryWithDotMetricNameAndAttribute" , func ( t * testing . T ) {
q := & v3 . QueryRangeParamsV3 {
Start : 1735036101000 ,
End : 1735637901000 ,
Step : 60 ,
Variables : map [ string ] interface { } {
"SIGNOZ_START_TIME" : 1735034992000 ,
"SIGNOZ_END_TIME" : 1735036792000 ,
} ,
FormatForWeb : false ,
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeGraph ,
FillGaps : false ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorAvg ,
AggregateAttribute : v3 . AttributeKey {
Key : "system.memory.usage" ,
DataType : v3 . AttributeKeyDataTypeFloat64 ,
Type : v3 . AttributeKeyType ( "Gauge" ) ,
IsColumn : true ,
} ,
TimeAggregation : v3 . TimeAggregationAvg ,
SpaceAggregation : v3 . SpaceAggregationSum ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{
Key : v3 . AttributeKey {
Key : "os.type" ,
DataType : v3 . AttributeKeyDataTypeString ,
Type : v3 . AttributeKeyTypeTag ,
IsColumn : false ,
} ,
Operator : v3 . FilterOperatorEqual ,
Value : "linux" ,
} ,
} ,
} ,
Expression : "A" ,
Disabled : true ,
StepInterval : 60 ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "#SIGNOZ_VALUE" ,
Order : v3 . DirectionAsc ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{
Key : "os.type" ,
DataType : v3 . AttributeKeyDataTypeString ,
Type : v3 . AttributeKeyTypeTag ,
IsColumn : false ,
} ,
} ,
Legend : "" ,
ReduceTo : v3 . ReduceToOperatorAvg ,
Having : [ ] v3 . Having { } ,
} ,
"B" : {
QueryName : "B" ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSum ,
AggregateAttribute : v3 . AttributeKey {
Key : "system.network.io" ,
DataType : v3 . AttributeKeyDataTypeFloat64 ,
Type : v3 . AttributeKeyType ( "Sum" ) ,
IsColumn : true ,
} ,
TimeAggregation : v3 . TimeAggregationIncrease ,
SpaceAggregation : v3 . SpaceAggregationSum ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem { } ,
} ,
Expression : "B" ,
Disabled : true ,
StepInterval : 60 ,
OrderBy : [ ] v3 . OrderBy {
{
Key : "os.type" ,
DataType : v3 . AttributeKeyDataTypeString ,
Type : v3 . AttributeKeyTypeTag ,
IsColumn : false ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{
Key : "os.type" ,
DataType : v3 . AttributeKeyDataTypeString ,
Type : v3 . AttributeKeyTypeTag ,
IsColumn : false ,
} ,
} ,
Legend : "" ,
ReduceTo : v3 . ReduceToOperatorAvg ,
Having : [ ] v3 . Having {
{
ColumnName : "SUM(system.network.io)" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 4 ,
} ,
} ,
} ,
"F1" : {
QueryName : "F1" ,
Expression : "A + B" ,
Disabled : false ,
Legend : "" ,
OrderBy : [ ] v3 . OrderBy { } ,
Limit : 2 ,
} ,
} ,
} ,
}
qbOptions := QueryBuilderOptions {
BuildMetricQuery : metricsv3 . PrepareMetricQuery ,
}
fm := featureManager . StartManager ( )
qb := NewQueryBuilder ( qbOptions , fm )
queries , err := qb . PrepareQueries ( q )
2025-03-03 14:04:16 +05:30
require . Contains ( t , queries [ "F1" ] , "SELECT A.`os.type` as `os.type`, A.`ts` as `ts`, A.value + B.value as value FROM (SELECT `os.type`, toStartOfInterval(toDateTime(intDiv(unix_milli, 1000)), INTERVAL 60 SECOND) as ts, avg(value) as value FROM signoz_metrics.distributed_samples_v4 INNER JOIN (SELECT DISTINCT JSONExtractString(labels, 'os.type') as `os.type`, fingerprint FROM signoz_metrics.time_series_v4_1day WHERE metric_name IN ['system.memory.usage'] AND temporality = '' AND __normalized = true AND unix_milli >= 1734998400000 AND unix_milli < 1735637880000 AND JSONExtractString(labels, 'os.type') = 'linux') as filtered_time_series USING fingerprint WHERE metric_name IN ['system.memory.usage'] AND unix_milli >= 1735036080000 AND unix_milli < 1735637880000 GROUP BY `os.type`, ts ORDER BY `os.type` ASC, ts) as A INNER JOIN (SELECT * FROM (SELECT `os.type`, toStartOfInterval(toDateTime(intDiv(unix_milli, 1000)), INTERVAL 60 SECOND) as ts, sum(value) as value FROM signoz_metrics.distributed_samples_v4 INNER JOIN (SELECT DISTINCT JSONExtractString(labels, 'os.type') as `os.type`, fingerprint FROM signoz_metrics.time_series_v4_1day WHERE metric_name IN ['system.network.io'] AND temporality = '' AND __normalized = true AND unix_milli >= 1734998400000 AND unix_milli < 1735637880000) as filtered_time_series USING fingerprint WHERE metric_name IN ['system.network.io'] AND unix_milli >= 1735036020000 AND unix_milli < 1735637880000 GROUP BY `os.type`, ts ORDER BY `os.type` ASC, ts) HAVING value > 4) as B ON A.`os.type` = B.`os.type` AND A.`ts` = B.`ts`" )
2025-01-03 10:52:55 +05:30
require . NoError ( t , err )
} )
2023-03-23 19:45:15 +05:30
}
2023-07-13 18:50:19 +05:30
func TestDeltaQueryBuilder ( t * testing . T ) {
cases := [ ] struct {
name string
query * v3 . QueryRangeParamsV3
queryToTest string
expected string
} {
{
name : "TestQueryWithName - Request rate" ,
query : & v3 . QueryRangeParamsV3 {
2024-10-21 14:22:32 +05:30
Start : 1650991982000 , // 2022-04-25 10:53:02
End : 1651078382000 , // 2022-04-26 10:53:02
2023-07-13 18:50:19 +05:30
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeGraph ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
DataSource : v3 . DataSourceMetrics ,
QueryName : "A" ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_count" } ,
StepInterval : 60 ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
Expression : "A" ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Items : [ ] v3 . FilterItem {
{
Key : v3 . AttributeKey { Key : "service_name" } ,
Operator : v3 . FilterOperatorIn ,
Value : [ ] interface { } { "frontend" } ,
} ,
{
Key : v3 . AttributeKey { Key : "operation" } ,
Operator : v3 . FilterOperatorIn ,
Value : [ ] interface { } { "HTTP GET /dispatch" } ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
queryToTest : "A" ,
2025-03-03 14:04:16 +05:30
expected : "SELECT toStartOfInterval(toDateTime(intDiv(unix_milli, 1000)), INTERVAL 60 SECOND) as ts, sum(value)/60 as value FROM signoz_metrics.distributed_samples_v4 INNER JOIN (SELECT DISTINCT fingerprint FROM signoz_metrics.time_series_v4_1day WHERE metric_name IN ['signoz_latency_count'] AND temporality = 'Delta' AND __normalized = true AND unix_milli >= 1650931200000 AND unix_milli < 1651078380000 AND JSONExtractString(labels, 'service_name') IN ['frontend'] AND JSONExtractString(labels, 'operation') IN ['HTTP GET /dispatch'] AND JSONExtractString(labels, '__temporality__') = 'Delta') as filtered_time_series USING fingerprint WHERE metric_name IN ['signoz_latency_count'] AND unix_milli >= 1650991980000 AND unix_milli <= 1651078380000 GROUP BY ts ORDER BY ts" ,
2023-07-13 18:50:19 +05:30
} ,
{
name : "TestQueryWithExpression - Error rate" ,
query : & v3 . QueryRangeParamsV3 {
2024-10-21 14:22:32 +05:30
Start : 1650991982000 , // 2022-04-25 10:53:02
End : 1651078382000 , // 2022-04-26 10:53:02
2023-07-13 18:50:19 +05:30
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeGraph ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
DataSource : v3 . DataSourceMetrics ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_count" } ,
StepInterval : 60 ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
Expression : "A" ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Items : [ ] v3 . FilterItem {
{
Key : v3 . AttributeKey { Key : "service_name" } ,
Operator : v3 . FilterOperatorIn ,
Value : [ ] interface { } { "frontend" } ,
} ,
{
Key : v3 . AttributeKey { Key : "operation" } ,
Operator : v3 . FilterOperatorIn ,
Value : [ ] interface { } { "HTTP GET /dispatch" } ,
} ,
{
Key : v3 . AttributeKey { Key : "status_code" } ,
Operator : v3 . FilterOperatorIn ,
Value : [ ] interface { } { "STATUS_CODE_ERROR" } ,
} ,
} ,
} ,
} ,
"B" : {
QueryName : "B" ,
DataSource : v3 . DataSourceMetrics ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_count" } ,
StepInterval : 60 ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
Expression : "B" ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Items : [ ] v3 . FilterItem {
{
Key : v3 . AttributeKey { Key : "service_name" } ,
Operator : v3 . FilterOperatorIn ,
Value : [ ] interface { } { "frontend" } ,
} ,
{
Key : v3 . AttributeKey { Key : "operation" } ,
Operator : v3 . FilterOperatorIn ,
Value : [ ] interface { } { "HTTP GET /dispatch" } ,
} ,
} ,
} ,
} ,
"C" : {
QueryName : "C" ,
Expression : "A*100/B" ,
} ,
} ,
} ,
} ,
queryToTest : "C" ,
2025-03-03 14:04:16 +05:30
expected : "SELECT A.`ts` as `ts`, A.value * 100 / B.value as value FROM (SELECT toStartOfInterval(toDateTime(intDiv(unix_milli, 1000)), INTERVAL 60 SECOND) as ts, sum(value)/60 as value FROM signoz_metrics.distributed_samples_v4 INNER JOIN (SELECT DISTINCT fingerprint FROM signoz_metrics.time_series_v4_1day WHERE metric_name IN ['signoz_latency_count'] AND temporality = 'Delta' AND __normalized = true AND unix_milli >= 1650931200000 AND unix_milli < 1651078380000 AND JSONExtractString(labels, 'service_name') IN ['frontend'] AND JSONExtractString(labels, 'operation') IN ['HTTP GET /dispatch'] AND JSONExtractString(labels, 'status_code') IN ['STATUS_CODE_ERROR'] AND JSONExtractString(labels, '__temporality__') = 'Delta') as filtered_time_series USING fingerprint WHERE metric_name IN ['signoz_latency_count'] AND unix_milli >= 1650991980000 AND unix_milli <= 1651078380000 GROUP BY ts ORDER BY ts) as A INNER JOIN (SELECT toStartOfInterval(toDateTime(intDiv(unix_milli, 1000)), INTERVAL 60 SECOND) as ts, sum(value)/60 as value FROM signoz_metrics.distributed_samples_v4 INNER JOIN (SELECT DISTINCT fingerprint FROM signoz_metrics.time_series_v4_1day WHERE metric_name IN ['signoz_latency_count'] AND temporality = 'Delta' AND __normalized = true AND unix_milli >= 1650931200000 AND unix_milli < 1651078380000 AND JSONExtractString(labels, 'service_name') IN ['frontend'] AND JSONExtractString(labels, 'operation') IN ['HTTP GET /dispatch'] AND JSONExtractString(labels, '__temporality__') = 'Delta') as filtered_time_series USING fingerprint WHERE metric_name IN ['signoz_latency_count'] AND unix_milli >= 1650991980000 AND unix_milli <= 1651078380000 GROUP BY ts ORDER BY ts) as B ON A.`ts` = B.`ts`" ,
2023-07-13 18:50:19 +05:30
} ,
{
name : "TestQuery - Quantile" ,
query : & v3 . QueryRangeParamsV3 {
Start : 1650991982000 ,
End : 1651078382000 ,
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeGraph ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
DataSource : v3 . DataSourceMetrics ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
StepInterval : 60 ,
AggregateOperator : v3 . AggregateOperatorHistQuant95 ,
Expression : "A" ,
Temporality : v3 . Delta ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
2024-05-15 18:52:01 +05:30
{ Key : "le" } ,
2023-07-13 18:50:19 +05:30
} ,
} ,
} ,
} ,
} ,
queryToTest : "A" ,
2025-03-03 14:04:16 +05:30
expected : "SELECT service_name, ts, histogramQuantile(arrayMap(x -> toFloat64(x), groupArray(le)), groupArray(value), 0.950) as value FROM (SELECT service_name,le, toStartOfInterval(toDateTime(intDiv(unix_milli, 1000)), INTERVAL 60 SECOND) as ts, sum(value)/60 as value FROM signoz_metrics.distributed_samples_v4 INNER JOIN (SELECT DISTINCT JSONExtractString(labels, 'service_name') as service_name, JSONExtractString(labels, 'le') as le, fingerprint FROM signoz_metrics.time_series_v4_1day WHERE metric_name IN ['signoz_latency_bucket'] AND temporality = 'Delta' AND __normalized = true AND unix_milli >= 1650931200000 AND unix_milli < 1651078380000) as filtered_time_series USING fingerprint WHERE metric_name IN ['signoz_latency_bucket'] AND unix_milli >= 1650991980000 AND unix_milli <= 1651078380000 GROUP BY service_name,le,ts ORDER BY service_name ASC,le ASC, ts) GROUP BY service_name,ts ORDER BY service_name ASC, ts" ,
2023-07-13 18:50:19 +05:30
} ,
}
for _ , c := range cases {
t . Run ( c . name , func ( t * testing . T ) {
qbOptions := QueryBuilderOptions {
BuildMetricQuery : metricsv3 . PrepareMetricQuery ,
}
2023-08-18 07:32:05 +05:30
fm := featureManager . StartManager ( )
qb := NewQueryBuilder ( qbOptions , fm )
2023-07-13 18:50:19 +05:30
queries , err := qb . PrepareQueries ( c . query )
require . NoError ( t , err )
require . Equal ( t , c . expected , queries [ c . queryToTest ] )
} )
}
}
2023-12-21 12:11:35 +05:30
var testLogsWithFormula = [ ] struct {
Name string
Query * v3 . QueryRangeParamsV3
ExpectedQuery string
} {
{
Name : "test formula without dot in filter and group by attribute" ,
Query : & v3 . QueryRangeParamsV3 {
Start : 1702979275000000000 ,
End : 1702981075000000000 ,
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeGraph ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key_1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key_1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } ,
} ,
} ,
"B" : {
QueryName : "B" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key_2" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "B" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key_1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } ,
} ,
} ,
"C" : {
QueryName : "C" ,
Expression : "A + B" ,
} ,
} ,
} ,
} ,
ExpectedQuery : "SELECT A.`key_1` as `key_1`, A.`ts` as `ts`, A.value + B.value as value FROM " +
"(SELECT toStartOfInterval(fromUnixTimestamp64Nano(timestamp), INTERVAL 60 SECOND) AS ts, attributes_bool_value[indexOf(attributes_bool_key, 'key_1')] as `key_1`, toFloat64(count(*)) as value from " +
"signoz_logs.distributed_logs where (timestamp >= 1702979275000000000 AND timestamp <= 1702981075000000000) AND attributes_bool_value[indexOf(attributes_bool_key, 'key_1')] = true AND " +
"has(attributes_bool_key, 'key_1') group by `key_1`,ts order by value DESC) as A INNER JOIN (SELECT toStartOfInterval(fromUnixTimestamp64Nano(timestamp), INTERVAL 60 SECOND) AS ts, " +
"attributes_bool_value[indexOf(attributes_bool_key, 'key_1')] as `key_1`, toFloat64(count(*)) as value from signoz_logs.distributed_logs where (timestamp >= 1702979275000000000 AND timestamp <= 1702981075000000000) " +
"AND attributes_bool_value[indexOf(attributes_bool_key, 'key_2')] = true AND has(attributes_bool_key, 'key_1') group by `key_1`,ts order by value DESC) as B ON A.`key_1` = B.`key_1` AND A.`ts` = B.`ts`" ,
} ,
{
Name : "test formula with dot in filter and group by attribute" ,
Query : & v3 . QueryRangeParamsV3 {
Start : 1702979056000000000 ,
End : 1702982656000000000 ,
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeTable ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key1.1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key1.1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } ,
} ,
} ,
"B" : {
QueryName : "B" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key1.2" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "B" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key1.1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } ,
} ,
} ,
"C" : {
QueryName : "C" ,
Expression : "A + B" ,
} ,
} ,
} ,
} ,
2024-11-12 13:34:45 +05:30
ExpectedQuery : "SELECT A.`key1.1` as `key1.1`, A.value + B.value as value FROM (SELECT now() as ts, attributes_bool_value[indexOf(attributes_bool_key, 'key1.1')] as `key1.1`, " +
2023-12-21 12:11:35 +05:30
"toFloat64(count(*)) as value from signoz_logs.distributed_logs where (timestamp >= 1702979056000000000 AND timestamp <= 1702982656000000000) AND attributes_bool_value[indexOf(attributes_bool_key, 'key1.1')] = true AND " +
"has(attributes_bool_key, 'key1.1') group by `key1.1` order by value DESC) as A INNER JOIN (SELECT now() as ts, attributes_bool_value[indexOf(attributes_bool_key, 'key1.1')] as `key1.1`, " +
"toFloat64(count(*)) as value from signoz_logs.distributed_logs where (timestamp >= 1702979056000000000 AND timestamp <= 1702982656000000000) AND attributes_bool_value[indexOf(attributes_bool_key, 'key1.2')] = true AND " +
2024-11-12 13:34:45 +05:30
"has(attributes_bool_key, 'key1.1') group by `key1.1` order by value DESC) as B ON A.`key1.1` = B.`key1.1`" ,
2023-12-21 12:11:35 +05:30
} ,
{
Name : "test formula with dot in filter and group by materialized attribute" ,
Query : & v3 . QueryRangeParamsV3 {
Start : 1702980884000000000 ,
End : 1702984484000000000 ,
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeGraph ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key_2" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag , IsColumn : true } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key1.1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag , IsColumn : true } ,
} ,
} ,
"B" : {
QueryName : "B" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key_1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "B" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key1.1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag , IsColumn : true } ,
} ,
} ,
"C" : {
QueryName : "C" ,
Expression : "A - B" ,
} ,
} ,
} ,
} ,
ExpectedQuery : "SELECT A.`key1.1` as `key1.1`, A.`ts` as `ts`, A.value - B.value as value FROM (SELECT toStartOfInterval(fromUnixTimestamp64Nano(timestamp), INTERVAL 60 SECOND) AS ts, " +
2024-03-30 17:57:01 +05:30
"`attribute_bool_key1$$1` as `key1.1`, toFloat64(count(*)) as value from signoz_logs.distributed_logs where (timestamp >= 1702980884000000000 AND timestamp <= 1702984484000000000) AND " +
"`attribute_bool_key_2` = true AND `attribute_bool_key1$$1_exists`=true group by `key1.1`,ts order by value DESC) as A INNER JOIN (SELECT toStartOfInterval(fromUnixTimestamp64Nano(timestamp), " +
"INTERVAL 60 SECOND) AS ts, `attribute_bool_key1$$1` as `key1.1`, toFloat64(count(*)) as value from signoz_logs.distributed_logs where (timestamp >= 1702980884000000000 AND " +
"timestamp <= 1702984484000000000) AND attributes_bool_value[indexOf(attributes_bool_key, 'key_1')] = true AND `attribute_bool_key1$$1_exists`=true group by `key1.1`,ts order by value DESC) as B " +
2023-12-21 12:11:35 +05:30
"ON A.`key1.1` = B.`key1.1` AND A.`ts` = B.`ts`" ,
} ,
}
func TestLogsQueryWithFormula ( t * testing . T ) {
t . Parallel ( )
qbOptions := QueryBuilderOptions {
BuildLogQuery : logsV3 . PrepareLogsQuery ,
}
fm := featureManager . StartManager ( )
qb := NewQueryBuilder ( qbOptions , fm )
for _ , test := range testLogsWithFormula {
t . Run ( test . Name , func ( t * testing . T ) {
queries , err := qb . PrepareQueries ( test . Query )
require . NoError ( t , err )
require . Equal ( t , test . ExpectedQuery , queries [ "C" ] )
} )
}
}
2024-08-09 12:32:11 +05:30
2024-09-13 17:04:22 +05:30
var testLogsWithFormulaV2 = [ ] struct {
Name string
Query * v3 . QueryRangeParamsV3
ExpectedQuery string
} {
{
Name : "test formula without dot in filter and group by attribute" ,
Query : & v3 . QueryRangeParamsV3 {
Start : 1702979275000000000 ,
End : 1702981075000000000 ,
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeGraph ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key_1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key_1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } ,
} ,
} ,
"B" : {
QueryName : "B" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key_2" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "B" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key_1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } ,
} ,
} ,
"C" : {
QueryName : "C" ,
Expression : "A + B" ,
} ,
} ,
} ,
} ,
ExpectedQuery : "SELECT A.`key_1` as `key_1`, A.`ts` as `ts`, A.value + B.value as value FROM " +
"(SELECT toStartOfInterval(fromUnixTimestamp64Nano(timestamp), INTERVAL 60 SECOND) AS ts, attributes_bool['key_1'] as `key_1`, toFloat64(count(*)) as value from " +
"signoz_logs.distributed_logs_v2 where (timestamp >= 1702979275000000000 AND timestamp <= 1702981075000000000) AND (ts_bucket_start >= 1702977475 AND ts_bucket_start <= 1702981075) " +
"AND attributes_bool['key_1'] = true AND mapContains(attributes_bool, 'key_1') AND mapContains(attributes_bool, 'key_1') group by `key_1`,ts order by value DESC) as A INNER JOIN (SELECT " +
"toStartOfInterval(fromUnixTimestamp64Nano(timestamp), INTERVAL 60 SECOND) AS ts, attributes_bool['key_1'] as `key_1`, toFloat64(count(*)) as value " +
"from signoz_logs.distributed_logs_v2 where (timestamp >= 1702979275000000000 AND timestamp <= 1702981075000000000) AND (ts_bucket_start >= 1702977475 AND ts_bucket_start <= 1702981075) " +
"AND attributes_bool['key_2'] = true AND mapContains(attributes_bool, 'key_2') AND mapContains(attributes_bool, 'key_1') group by `key_1`,ts order by value DESC) as B ON A.`key_1` = B.`key_1` AND A.`ts` = B.`ts`" ,
} ,
{
Name : "test formula with dot in filter and group by attribute" ,
Query : & v3 . QueryRangeParamsV3 {
Start : 1702979056000000000 ,
End : 1702982656000000000 ,
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeTable ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key1.1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key1.1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } ,
} ,
} ,
"B" : {
QueryName : "B" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key1.2" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "B" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key1.1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } ,
} ,
} ,
"C" : {
QueryName : "C" ,
Expression : "A + B" ,
} ,
} ,
} ,
} ,
2024-11-12 13:34:45 +05:30
ExpectedQuery : "SELECT A.`key1.1` as `key1.1`, A.value + B.value as value FROM (SELECT attributes_bool['key1.1'] as `key1.1`, " +
2024-09-13 17:04:22 +05:30
"toFloat64(count(*)) as value from signoz_logs.distributed_logs_v2 where (timestamp >= 1702979056000000000 AND timestamp <= 1702982656000000000) AND (ts_bucket_start >= 1702977256 AND ts_bucket_start <= 1702982656) " +
"AND attributes_bool['key1.1'] = true AND mapContains(attributes_bool, 'key1.1') AND mapContains(attributes_bool, 'key1.1') group by `key1.1` order by value DESC) as A INNER JOIN (SELECT " +
"attributes_bool['key1.1'] as `key1.1`, toFloat64(count(*)) as value from signoz_logs.distributed_logs_v2 where (timestamp >= 1702979056000000000 AND timestamp <= 1702982656000000000) " +
"AND (ts_bucket_start >= 1702977256 AND ts_bucket_start <= 1702982656) AND attributes_bool['key1.2'] = true AND mapContains(attributes_bool, 'key1.2') AND " +
2024-11-12 13:34:45 +05:30
"mapContains(attributes_bool, 'key1.1') group by `key1.1` order by value DESC) as B ON A.`key1.1` = B.`key1.1`" ,
2024-09-13 17:04:22 +05:30
} ,
{
Name : "test formula with dot in filter and group by materialized attribute" ,
Query : & v3 . QueryRangeParamsV3 {
Start : 1702980884000000000 ,
End : 1702984484000000000 ,
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeGraph ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key_2" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag , IsColumn : true } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key1.1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag , IsColumn : true } ,
} ,
} ,
"B" : {
QueryName : "B" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
Filters : & v3 . FilterSet { Operator : "AND" , Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "key_1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag } , Value : true , Operator : v3 . FilterOperatorEqual } ,
} } ,
AggregateOperator : v3 . AggregateOperatorCount ,
Expression : "B" ,
OrderBy : [ ] v3 . OrderBy {
{
ColumnName : "timestamp" ,
Order : "desc" ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "key1.1" , DataType : v3 . AttributeKeyDataTypeBool , Type : v3 . AttributeKeyTypeTag , IsColumn : true } ,
} ,
} ,
"C" : {
QueryName : "C" ,
Expression : "A - B" ,
} ,
} ,
} ,
} ,
ExpectedQuery : "SELECT A.`key1.1` as `key1.1`, A.`ts` as `ts`, A.value - B.value as value FROM (SELECT toStartOfInterval(fromUnixTimestamp64Nano(timestamp), INTERVAL 60 SECOND) AS ts, " +
"`attribute_bool_key1$$1` as `key1.1`, toFloat64(count(*)) as value from signoz_logs.distributed_logs_v2 where (timestamp >= 1702980884000000000 AND timestamp <= 1702984484000000000) AND " +
"(ts_bucket_start >= 1702979084 AND ts_bucket_start <= 1702984484) AND `attribute_bool_key_2` = true AND `attribute_bool_key1$$1_exists`=true group by `key1.1`,ts order by value DESC) as " +
"A INNER JOIN (SELECT toStartOfInterval(fromUnixTimestamp64Nano(timestamp), INTERVAL 60 SECOND) AS ts, `attribute_bool_key1$$1` as `key1.1`, toFloat64(count(*)) as value from " +
"signoz_logs.distributed_logs_v2 where (timestamp >= 1702980884000000000 AND timestamp <= 1702984484000000000) AND (ts_bucket_start >= 1702979084 AND ts_bucket_start <= 1702984484) AND " +
"attributes_bool['key_1'] = true AND mapContains(attributes_bool, 'key_1') AND `attribute_bool_key1$$1_exists`=true group by `key1.1`,ts order by value DESC) as B " +
"ON A.`key1.1` = B.`key1.1` AND A.`ts` = B.`ts`" ,
} ,
}
func TestLogsQueryWithFormulaV2 ( t * testing . T ) {
t . Parallel ( )
qbOptions := QueryBuilderOptions {
BuildLogQuery : logsV4 . PrepareLogsQuery ,
}
fm := featureManager . StartManager ( )
qb := NewQueryBuilder ( qbOptions , fm )
for _ , test := range testLogsWithFormulaV2 {
t . Run ( test . Name , func ( t * testing . T ) {
queries , err := qb . PrepareQueries ( test . Query )
require . NoError ( t , err )
require . Equal ( t , test . ExpectedQuery , queries [ "C" ] )
} )
}
}
2024-08-09 12:32:11 +05:30
func TestGenerateCacheKeysMetricsBuilder ( t * testing . T ) {
testCases := [ ] struct {
name string
query * v3 . QueryRangeParamsV3
expectedCacheKeys map [ string ] string
} {
// v3 - only the graph builder queries can be cached
{
name : "version=v3;panelType=graph;dataSource=metrics;queryType=builder" ,
query : & v3 . QueryRangeParamsV3 {
Version : "v3" ,
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeGraph ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "le" } ,
} ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
"A" : "source=metrics&step=60&aggregate=sum_rate&timeAggregation=&spaceAggregation=&aggregateAttribute=signoz_latency_bucket---false&filter-0=key:service_name---false,op:=,value:A&groupBy-0=service_name---false&groupBy-1=le---false&having-0=column:value,op:>,value:100" ,
} ,
} ,
{
name : "version=v3;panelType=graph;dataSource=metrics;queryType=builder with limit" , // limit should not be part of the cache key
query : & v3 . QueryRangeParamsV3 {
Version : "v3" ,
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeGraph ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "le" } ,
} ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
Limit : 10 ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
"A" : "source=metrics&step=60&aggregate=sum_rate&timeAggregation=&spaceAggregation=&aggregateAttribute=signoz_latency_bucket---false&filter-0=key:service_name---false,op:=,value:A&groupBy-0=service_name---false&groupBy-1=le---false&having-0=column:value,op:>,value:100" ,
} ,
} ,
{
name : "version=v3;panelType=graph;dataSource=metrics;queryType=builder with shiftBy" , // shiftBy should be part of the cache key
query : & v3 . QueryRangeParamsV3 {
Version : "v3" ,
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeGraph ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "le" } ,
} ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
Limit : 10 ,
ShiftBy : 86400 ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
"A" : "source=metrics&step=60&aggregate=sum_rate&timeAggregation=&spaceAggregation=&shiftBy=86400&aggregateAttribute=signoz_latency_bucket---false&filter-0=key:service_name---false,op:=,value:A&groupBy-0=service_name---false&groupBy-1=le---false&having-0=column:value,op:>,value:100" ,
} ,
} ,
{
name : "version=v3;panelType=value;dataSource=metrics;queryType=builder" ,
query : & v3 . QueryRangeParamsV3 {
Version : "v3" ,
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeValue ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
Expression : "A" ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "le" } ,
} ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
ReduceTo : v3 . ReduceToOperatorAvg ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string { } ,
} ,
{
name : "version=v3;panelType=table;dataSource=metrics;queryType=builder" ,
query : & v3 . QueryRangeParamsV3 {
Version : "v3" ,
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeTable ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
Expression : "A" ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "le" } ,
} ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string { } ,
} ,
// v4 - everything can be cached
{
name : "version=v4;panelType=graph;dataSource=metrics;queryType=builder" ,
query : & v3 . QueryRangeParamsV3 {
Version : "v4" ,
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeGraph ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "le" } ,
} ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
"A" : "source=metrics&step=60&aggregate=sum_rate&timeAggregation=&spaceAggregation=&aggregateAttribute=signoz_latency_bucket---false&filter-0=key:service_name---false,op:=,value:A&groupBy-0=service_name---false&groupBy-1=le---false&having-0=column:value,op:>,value:100" ,
} ,
} ,
{
name : "version=v4;panelType=graph;dataSource=metrics;queryType=builder with limit" , // limit should not be part of the cache key
query : & v3 . QueryRangeParamsV3 {
Version : "v4" ,
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeGraph ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "le" } ,
} ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
Limit : 10 ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
"A" : "source=metrics&step=60&aggregate=sum_rate&timeAggregation=&spaceAggregation=&aggregateAttribute=signoz_latency_bucket---false&filter-0=key:service_name---false,op:=,value:A&groupBy-0=service_name---false&groupBy-1=le---false&having-0=column:value,op:>,value:100" ,
} ,
} ,
{
name : "version=v4;panelType=graph;dataSource=metrics;queryType=builder with shiftBy" , // shiftBy should be part of the cache key
query : & v3 . QueryRangeParamsV3 {
Version : "v4" ,
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeGraph ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "le" } ,
} ,
Expression : "A" ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
Limit : 10 ,
ShiftBy : 86400 ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
"A" : "source=metrics&step=60&aggregate=sum_rate&timeAggregation=&spaceAggregation=&shiftBy=86400&aggregateAttribute=signoz_latency_bucket---false&filter-0=key:service_name---false,op:=,value:A&groupBy-0=service_name---false&groupBy-1=le---false&having-0=column:value,op:>,value:100" ,
} ,
} ,
{
name : "version=v4;panelType=value;dataSource=metrics;queryType=builder" ,
query : & v3 . QueryRangeParamsV3 {
Version : "v4" ,
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeValue ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
2025-01-14 23:13:47 +05:30
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
SecondaryAggregation : v3 . SecondaryAggregationMax ,
Expression : "A" ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
Temporality : v3 . Delta ,
2024-08-09 12:32:11 +05:30
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "le" } ,
} ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
ReduceTo : v3 . ReduceToOperatorAvg ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
2025-01-14 23:13:47 +05:30
"A" : "source=metrics&step=60&aggregate=sum_rate&timeAggregation=&spaceAggregation=&aggregateAttribute=signoz_latency_bucket---false&filter-0=key:service_name---false,op:=,value:A&groupBy-0=service_name---false&groupBy-1=le---false&secondaryAggregation=max&having-0=column:value,op:>,value:100" ,
2024-08-09 12:32:11 +05:30
} ,
} ,
2024-12-28 22:25:19 +05:30
{
name : "version=v3;panelType=value;dataSource=metrics;queryType=builder with expression" , //not caching panel type value for v3
query : & v3 . QueryRangeParamsV3 {
Version : "v3" ,
CompositeQuery : & v3 . CompositeQuery {
QueryType : v3 . QueryTypeBuilder ,
PanelType : v3 . PanelTypeValue ,
FillGaps : false ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorNoOp ,
AggregateAttribute : v3 . AttributeKey {
Key : "system_memory_usage" ,
DataType : v3 . AttributeKeyDataTypeFloat64 ,
Type : v3 . AttributeKeyType ( "Gauge" ) ,
IsColumn : true ,
} ,
TimeAggregation : v3 . TimeAggregationUnspecified ,
SpaceAggregation : v3 . SpaceAggregationSum ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{
Key : v3 . AttributeKey {
Key : "state" ,
DataType : v3 . AttributeKeyDataTypeString ,
Type : v3 . AttributeKeyTypeTag ,
IsColumn : false ,
} ,
Operator : v3 . FilterOperatorEqual ,
Value : "cached" ,
} ,
} ,
} ,
Expression : "A" ,
Disabled : true ,
StepInterval : 60 ,
} ,
"B" : {
QueryName : "B" ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorNoOp ,
AggregateAttribute : v3 . AttributeKey {
Key : "system_memory_usage" ,
DataType : v3 . AttributeKeyDataTypeFloat64 ,
Type : v3 . AttributeKeyType ( "Gauge" ) ,
IsColumn : true ,
} ,
TimeAggregation : v3 . TimeAggregationUnspecified ,
SpaceAggregation : v3 . SpaceAggregationSum ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{
Key : v3 . AttributeKey {
Key : "state" ,
DataType : v3 . AttributeKeyDataTypeString ,
Type : v3 . AttributeKeyTypeTag ,
IsColumn : false ,
} ,
Operator : v3 . FilterOperatorEqual ,
Value : "cached" ,
} ,
} ,
} ,
Expression : "B" ,
Disabled : true ,
StepInterval : 60 ,
} ,
"F1" : {
QueryName : "F1" ,
Expression : "A+B" ,
Disabled : false ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string { } ,
} ,
2024-08-09 12:32:11 +05:30
{
name : "version=v4;panelType=table;dataSource=metrics;queryType=builder" ,
query : & v3 . QueryRangeParamsV3 {
Version : "v4" ,
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeTable ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceMetrics ,
AggregateOperator : v3 . AggregateOperatorSumRate ,
Expression : "A" ,
AggregateAttribute : v3 . AttributeKey { Key : "signoz_latency_bucket" } ,
Temporality : v3 . Delta ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "le" } ,
} ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
"A" : "source=metrics&step=60&aggregate=sum_rate&timeAggregation=&spaceAggregation=&aggregateAttribute=signoz_latency_bucket---false&filter-0=key:service_name---false,op:=,value:A&groupBy-0=service_name---false&groupBy-1=le---false&having-0=column:value,op:>,value:100" ,
} ,
} ,
}
keyGen := NewKeyGenerator ( )
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
cacheKeys := keyGen . GenerateKeys ( test . query )
require . Equal ( t , test . expectedCacheKeys , cacheKeys )
} )
}
}
func TestGenerateCacheKeysLogs ( t * testing . T ) {
testCases := [ ] struct {
name string
query * v3 . QueryRangeParamsV3
expectedCacheKeys map [ string ] string
} {
{
name : "panelType=graph;dataSource=logs;queryType=builder" ,
query : & v3 . QueryRangeParamsV3 {
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeGraph ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
AggregateOperator : v3 . AggregateOperatorCount ,
AggregateAttribute : v3 . AttributeKey { Key : "log_level" } ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "log_level" } ,
} ,
Expression : "A" ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
"A" : "source=logs&step=60&aggregate=count&limit=0&aggregateAttribute=log_level---false&filter-0=key:service_name---false,op:=,value:A&groupBy-0=service_name---false&groupBy-1=log_level---false&orderBy-0=#SIGNOZ_VALUE-desc&having-0=column:value,op:>,value:100" ,
} ,
} ,
{
name : "panelType=table;dataSource=logs;queryType=builder" ,
query : & v3 . QueryRangeParamsV3 {
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeTable ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
AggregateOperator : v3 . AggregateOperatorCount ,
AggregateAttribute : v3 . AttributeKey { Key : "log_level" } ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
GroupBy : [ ] v3 . AttributeKey {
{ Key : "service_name" } ,
{ Key : "log_level" } ,
} ,
Expression : "A" ,
Having : [ ] v3 . Having {
{
ColumnName : "value" ,
Operator : v3 . HavingOperatorGreaterThan ,
Value : 100 ,
} ,
} ,
OrderBy : [ ] v3 . OrderBy {
{ ColumnName : constants . SigNozOrderByValue , Order : "desc" } ,
} ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string { } ,
} ,
{
name : "panelType=value;dataSource=logs;queryType=builder" ,
query : & v3 . QueryRangeParamsV3 {
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeValue ,
QueryType : v3 . QueryTypeBuilder ,
BuilderQueries : map [ string ] * v3 . BuilderQuery {
"A" : {
QueryName : "A" ,
StepInterval : 60 ,
DataSource : v3 . DataSourceLogs ,
AggregateOperator : v3 . AggregateOperatorCount ,
AggregateAttribute : v3 . AttributeKey { Key : "log_level" } ,
Filters : & v3 . FilterSet {
Operator : "AND" ,
Items : [ ] v3 . FilterItem {
{ Key : v3 . AttributeKey { Key : "service_name" } , Value : "A" , Operator : v3 . FilterOperatorEqual } ,
} ,
} ,
Expression : "A" ,
Limit : 10 ,
ReduceTo : v3 . ReduceToOperatorAvg ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string { } ,
} ,
}
keyGen := NewKeyGenerator ( )
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
cacheKeys := keyGen . GenerateKeys ( test . query )
require . Equal ( t , test . expectedCacheKeys , cacheKeys )
} )
}
}
func TestGenerateCacheKeysMetricsPromQL ( t * testing . T ) {
// there is no version difference between v3 and v4 for promql
testCases := [ ] struct {
name string
query * v3 . QueryRangeParamsV3
expectedCacheKeys map [ string ] string
} {
{
name : "panelType=graph;dataSource=metrics;queryType=promql" ,
query : & v3 . QueryRangeParamsV3 {
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeGraph ,
QueryType : v3 . QueryTypePromQL ,
PromQueries : map [ string ] * v3 . PromQuery {
"A" : {
Query : "signoz_latency_bucket" ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
"A" : "signoz_latency_bucket" ,
} ,
} ,
{
name : "panelType=graph;dataSource=metrics;queryType=promql" ,
query : & v3 . QueryRangeParamsV3 {
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeGraph ,
QueryType : v3 . QueryTypePromQL ,
PromQueries : map [ string ] * v3 . PromQuery {
"A" : {
Query : "histogram_quantile(0.9, sum(rate(signoz_latency_bucket[1m])) by (le))" ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string {
"A" : "histogram_quantile(0.9, sum(rate(signoz_latency_bucket[1m])) by (le))" ,
} ,
} ,
{
name : "panelType=value;dataSource=metrics;queryType=promql" ,
query : & v3 . QueryRangeParamsV3 {
CompositeQuery : & v3 . CompositeQuery {
PanelType : v3 . PanelTypeValue ,
QueryType : v3 . QueryTypePromQL ,
PromQueries : map [ string ] * v3 . PromQuery {
"A" : {
Query : "histogram_quantile(0.9, sum(rate(signoz_latency_bucket[1m])) by (le))" ,
} ,
} ,
} ,
} ,
expectedCacheKeys : map [ string ] string { } ,
} ,
}
keyGen := NewKeyGenerator ( )
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
cacheKeys := keyGen . GenerateKeys ( test . query )
require . Equal ( t , test . expectedCacheKeys , cacheKeys )
} )
}
}