Skip to content

Commit

Permalink
Add QueryValidationStatus
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasz-dobek committed Nov 25, 2024
1 parent a7cb5e0 commit 874b3b4
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 5 deletions.
83 changes: 83 additions & 0 deletions manifest/v1alpha/slo/metrics.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package slo

import (
"encoding/json"
"fmt"
"math"
"sort"
"strings"

"github.com/nobl9/nobl9-go/manifest/v1alpha"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)

// CountMetricsSpec represents set of two time series of good and total counts
Expand Down Expand Up @@ -367,3 +373,80 @@ func (m *MetricSpec) Query() interface{} {
return nil
}
}

// TODO: use this in ts.go
func (m *MetricSpec) FormatQuery(query json.RawMessage) *string {
switch m.DataSourceType() {
case v1alpha.Dynatrace:
return m.Dynatrace.MetricSelector
case v1alpha.Datadog:
return m.Datadog.Query
case v1alpha.NewRelic:
return m.NewRelic.NRQL
case v1alpha.SplunkObservability:
return m.SplunkObservability.Program
case v1alpha.SumoLogic:
return m.SumoLogic.Query
default:
var formattedQuery string
if len(query) > 0 {
formattedQuery = formatRawJSONMetricQueryToString(query)
}
return &formattedQuery
}
}

func formatRawJSONMetricQueryToString(queryAsJSON []byte) string {
var formatJSONToString func(jsonObjAny any, prefix string) string
var queryObj map[string]any

err := json.Unmarshal(queryAsJSON, &queryObj)
if err != nil {
return ""
}

toTitle := func(s string) string {
return cases.Title(language.English).String(s)
}

formatJSONToString = func(jsonObjAny any, prefix string) string {
var sb strings.Builder

switch jsonObj := jsonObjAny.(type) {
case string:
sb.WriteString(fmt.Sprintf("%s\n", jsonObj))
case float64:
number := jsonObj
if math.Floor(number) == number {
sb.WriteString(fmt.Sprintf("%d\n", int64(number)))
} else {
sb.WriteString(fmt.Sprintf("%f\n", number))
}
case map[string]any:
keys := make([]string, 0, len(jsonObj))
for k := range jsonObj {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
sb.WriteString(
fmt.Sprintf("%s%s: %s", prefix, toTitle(k), formatJSONToString(jsonObj[k], prefix)),
)
}
case []any:
sb.WriteString("\n")
prefix += " "
for i, val := range jsonObj {
sb.WriteString(
fmt.Sprintf("%s%d:\n%s", prefix, i+1, formatJSONToString(val, prefix+" ")),
)
}
default:
sb.WriteString("")
}

return sb.String()
}

return formatJSONToString(queryObj, "")
}
42 changes: 37 additions & 5 deletions manifest/v1alpha/slo/slo.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package slo

import (
"time"

"github.com/nobl9/nobl9-go/manifest"
"github.com/nobl9/nobl9-go/manifest/v1alpha"
)
Expand Down Expand Up @@ -162,15 +164,45 @@ type AnomalyConfigAlertMethod struct {
// Status holds dynamic fields returned when the Service is fetched from Nobl9 platform.
// Status is not part of the static object definition.
type Status struct {
UpdatedAt string `json:"updatedAt,omitempty"`
CompositeSLO *ProcessStatus `json:"compositeSlo,omitempty"`
ErrorBudgetAdjustment *ProcessStatus `json:"errorBudgetAdjustment,omitempty"`
Replay *ProcessStatus `json:"replay,omitempty"`
TargetSLO *TargetSloStatus `json:"targetSlo,omitempty"`
UpdatedAt string `json:"updatedAt,omitempty"`
CompositeSLO *ProcessStatus `json:"compositeSlo,omitempty"`
ErrorBudgetAdjustment *ProcessStatus `json:"errorBudgetAdjustment,omitempty"`
Replay *ProcessStatus `json:"replay,omitempty"`
TargetSLO *TargetSloStatus `json:"targetSlo,omitempty"`
ObjectiveIndicatorValidation []*ObjectiveIndicatorValidationStatus `json:"objectiveIndicatorValidation,omitempty"`
// Deprecated: use Status.Replay instead.
ReplayStatus *ReplayStatus `json:"timeTravel,omitempty"`
}

type ObjectiveIndicatorValidationStatus struct {
ObjectiveName string `json:"objectiveName"`
QueryValidationStatus
}

type QueryValidationStatus struct {
ValidationStatus `json:"validationStatus"`
}

type ValidationStatus struct {
GoodMetricValidation *ValidationDetails `json:"goodMetric,omitempty"`
BadMetricValidation *ValidationDetails `json:"badMetric,omitempty"`
TotalMetricValidation *ValidationDetails `json:"totalMetric,omitempty"`
RawMetricValidation *ValidationDetails `json:"rawMetric,omitempty"`
}

type ErrorDetails struct {
Message *string `json:"message"`
ValidationResult string `json:"validationResult"`
LogTimestamp *time.Time `json:"logTimestamp"`
HTTPStatusCode *int `json:"httpStatusCode"`
Query string `json:"query"`
}

type ValidationDetails struct {
*ErrorDetails
*MetricSpec
}

type ProcessStatus struct {
Status string `json:"status"`
TriggeredBy string `json:"triggeredBy"`
Expand Down

0 comments on commit 874b3b4

Please sign in to comment.