mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-17 15:36:48 +00:00
## 📄 Summary
To reliably migrate the alerts and dashboards, we need access to the telemetrystore to fetch some metadata and while doing migration, I need to log some stuff to fix stuff later.
Key changes:
- Modified the migration to include telemetrystore and a logging provider (open to using a standard logger instead)
- To avoid the previous issues with imported dashboards failing during migration, I've ensured that imported JSON files are automatically transformed when migration is active
- Implemented detailed logic to handle dashboard migration cleanly and prevent unnecessary errors
- Separated the core migration logic from SQL migration code, as users from the dot metrics migration requested shareable code snippets for local migrations. This modular approach allows others to easily reuse the migration functionality.
Known: I didn't register the migration yet in this PR, and will not merge this yet, so please review with that in mid.
154 lines
4.6 KiB
Go
154 lines
4.6 KiB
Go
package querybuilder
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"time"
|
|
|
|
"github.com/SigNoz/signoz/pkg/types/metrictypes"
|
|
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
|
)
|
|
|
|
const (
|
|
NsToSeconds = 1000000000
|
|
BucketAdjustment = 1800 // 30 minutes
|
|
|
|
RecommendedNumberOfPoints = 300
|
|
MaxAllowedNumberOfPoints = 1500
|
|
MaxAllowedSeries = 3000
|
|
)
|
|
|
|
// ToNanoSecs takes epoch and returns it in ns
|
|
func ToNanoSecs(epoch uint64) uint64 {
|
|
temp := epoch
|
|
count := 0
|
|
if epoch == 0 {
|
|
count = 1
|
|
} else {
|
|
for epoch != 0 {
|
|
epoch /= 10
|
|
count++
|
|
}
|
|
}
|
|
return temp * uint64(math.Pow(10, float64(19-count)))
|
|
}
|
|
|
|
// TODO(srikanthccv): should these be rounded to nearest multiple of 60 instead of 5 if step > 60?
|
|
// That would make graph look nice but "nice" but should be less important than the usefulness
|
|
func RecommendedStepInterval(start, end uint64) uint64 {
|
|
start = ToNanoSecs(start)
|
|
end = ToNanoSecs(end)
|
|
|
|
step := (end - start) / RecommendedNumberOfPoints / 1e9
|
|
|
|
if step < 5 {
|
|
return 5
|
|
}
|
|
|
|
// return the nearest lower multiple of 5
|
|
return step - step%5
|
|
}
|
|
|
|
func MinAllowedStepInterval(start, end uint64) uint64 {
|
|
start = ToNanoSecs(start)
|
|
end = ToNanoSecs(end)
|
|
|
|
step := (end - start) / MaxAllowedNumberOfPoints / 1e9
|
|
|
|
if step < 5 {
|
|
return 5
|
|
}
|
|
|
|
// return the nearest lower multiple of 5
|
|
return step - step%5
|
|
}
|
|
|
|
func RecommendedStepIntervalForMetric(start, end uint64) uint64 {
|
|
start = ToNanoSecs(start)
|
|
end = ToNanoSecs(end)
|
|
|
|
step := (end - start) / RecommendedNumberOfPoints / 1e9
|
|
|
|
// TODO(srikanthccv): make this make use of the reporting frequency and remove the 60
|
|
if step < 60 {
|
|
return 60
|
|
}
|
|
|
|
// return the nearest lower multiple of 60
|
|
recommended := step - step%60
|
|
|
|
// if the time range is greater than 1 day, and less than 1 week set the step interval to be multiple of 5 minutes
|
|
// if the time range is greater than 1 week, set the step interval to be multiple of 30 mins
|
|
if end-start >= uint64(24*time.Hour.Nanoseconds()) && end-start < uint64(7*24*time.Hour.Nanoseconds()) {
|
|
recommended = uint64(math.Round(float64(recommended)/300)) * 300
|
|
} else if end-start >= uint64(7*24*time.Hour.Nanoseconds()) {
|
|
recommended = uint64(math.Round(float64(recommended)/1800)) * 1800
|
|
}
|
|
return recommended
|
|
}
|
|
|
|
func MinAllowedStepIntervalForMetric(start, end uint64) uint64 {
|
|
start = ToNanoSecs(start)
|
|
end = ToNanoSecs(end)
|
|
|
|
step := (end - start) / RecommendedNumberOfPoints / 1e9
|
|
|
|
// TODO(srikanthccv): make this make use of the reporting frequency and remove the 60
|
|
if step < 60 {
|
|
return 60
|
|
}
|
|
|
|
// return the nearest lower multiple of 60
|
|
minAllowed := step - step%60
|
|
|
|
// if the time range is greater than 1 day, and less than 1 week set the step interval to be multiple of 5 minutes
|
|
// if the time range is greater than 1 week, set the step interval to be multiple of 30 mins
|
|
if end-start >= uint64(24*time.Hour.Nanoseconds()) && end-start < uint64(7*24*time.Hour.Nanoseconds()) {
|
|
minAllowed = uint64(math.Round(float64(minAllowed)/300)) * 300
|
|
} else if end-start >= uint64(7*24*time.Hour.Nanoseconds()) {
|
|
minAllowed = uint64(math.Round(float64(minAllowed)/1800)) * 1800
|
|
}
|
|
return minAllowed
|
|
}
|
|
|
|
func AdjustedMetricTimeRange(start, end, step uint64, mq qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]) (uint64, uint64) {
|
|
// align the start to the step interval
|
|
start = start - (start % (step * 1000))
|
|
// if the query is a rate query, we adjust the start time by one more step
|
|
// so that we can calculate the rate for the first data point
|
|
hasRunningDiff := false
|
|
for _, fn := range mq.Functions {
|
|
if fn.Name == qbtypes.FunctionNameRunningDiff {
|
|
hasRunningDiff = true
|
|
break
|
|
}
|
|
}
|
|
if (mq.Aggregations[0].TimeAggregation == metrictypes.TimeAggregationRate || mq.Aggregations[0].TimeAggregation == metrictypes.TimeAggregationIncrease) &&
|
|
mq.Aggregations[0].Temporality != metrictypes.Delta {
|
|
start -= step * 1000
|
|
}
|
|
if hasRunningDiff {
|
|
start -= step * 1000
|
|
}
|
|
// align the end to the nearest minute
|
|
adjustStep := uint64(math.Min(float64(step), 60))
|
|
end = end - (end % (adjustStep * 1000))
|
|
return start, end
|
|
}
|
|
|
|
func AssignReservedVars(vars map[string]any, start, end uint64) {
|
|
start = ToNanoSecs(start)
|
|
end = ToNanoSecs(end)
|
|
|
|
vars["start_timestamp"] = start / 1_000_000_000
|
|
vars["end_timestamp"] = end / 1_000_000_000
|
|
vars["start_timestamp_ms"] = start / 1_000_000
|
|
vars["end_timestamp_ms"] = end / 1_000_000
|
|
vars["SIGNOZ_START_TIME"] = start / 1_000_000
|
|
vars["SIGNOZ_END_TIME"] = end / 1_000_000
|
|
vars["start_timestamp_nano"] = start
|
|
vars["end_timestamp_nano"] = end
|
|
vars["start_datetime"] = fmt.Sprintf("toDateTime(%d)", start/1_000_000_000)
|
|
vars["end_datetime"] = fmt.Sprintf("toDateTime(%d)", end/1_000_000_000)
|
|
}
|